tsan_flags.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //===-- tsan_flags.cpp ----------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file is a part of ThreadSanitizer (TSan), a race detector.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "sanitizer_common/sanitizer_flags.h"
  13. #include "sanitizer_common/sanitizer_flag_parser.h"
  14. #include "sanitizer_common/sanitizer_libc.h"
  15. #include "tsan_flags.h"
  16. #include "tsan_rtl.h"
  17. #include "tsan_mman.h"
  18. #include "ubsan/ubsan_flags.h"
  19. namespace __tsan {
  20. // Can be overriden in frontend.
  21. #ifdef TSAN_EXTERNAL_HOOKS
  22. extern "C" const char* __tsan_default_options();
  23. #else
  24. SANITIZER_WEAK_DEFAULT_IMPL
  25. const char *__tsan_default_options() {
  26. return "";
  27. }
  28. #endif
  29. void Flags::SetDefaults() {
  30. #define TSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
  31. #include "tsan_flags.inc"
  32. #undef TSAN_FLAG
  33. // DDFlags
  34. second_deadlock_stack = false;
  35. }
  36. void RegisterTsanFlags(FlagParser *parser, Flags *f) {
  37. #define TSAN_FLAG(Type, Name, DefaultValue, Description) \
  38. RegisterFlag(parser, #Name, Description, &f->Name);
  39. #include "tsan_flags.inc"
  40. #undef TSAN_FLAG
  41. // DDFlags
  42. RegisterFlag(parser, "second_deadlock_stack",
  43. "Report where each mutex is locked in deadlock reports",
  44. &f->second_deadlock_stack);
  45. }
  46. void InitializeFlags(Flags *f, const char *env, const char *env_option_name) {
  47. SetCommonFlagsDefaults();
  48. {
  49. // Override some common flags defaults.
  50. CommonFlags cf;
  51. cf.CopyFrom(*common_flags());
  52. cf.external_symbolizer_path = GetEnv("TSAN_SYMBOLIZER_PATH");
  53. cf.allow_addr2line = true;
  54. if (SANITIZER_GO) {
  55. // Does not work as expected for Go: runtime handles SIGABRT and crashes.
  56. cf.abort_on_error = false;
  57. // Go does not have mutexes.
  58. cf.detect_deadlocks = false;
  59. }
  60. cf.print_suppressions = false;
  61. cf.stack_trace_format = " #%n %f %S %M";
  62. cf.exitcode = 66;
  63. cf.intercept_tls_get_addr = true;
  64. OverrideCommonFlags(cf);
  65. }
  66. f->SetDefaults();
  67. FlagParser parser;
  68. RegisterTsanFlags(&parser, f);
  69. RegisterCommonFlags(&parser);
  70. #if TSAN_CONTAINS_UBSAN
  71. __ubsan::Flags *uf = __ubsan::flags();
  72. uf->SetDefaults();
  73. FlagParser ubsan_parser;
  74. __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
  75. RegisterCommonFlags(&ubsan_parser);
  76. #endif
  77. // Let a frontend override.
  78. parser.ParseString(__tsan_default_options());
  79. #if TSAN_CONTAINS_UBSAN
  80. const char *ubsan_default_options = __ubsan_default_options();
  81. ubsan_parser.ParseString(ubsan_default_options);
  82. #endif
  83. // Override from command line.
  84. parser.ParseString(env, env_option_name);
  85. #if TSAN_CONTAINS_UBSAN
  86. ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
  87. #endif
  88. // Sanity check.
  89. if (!f->report_bugs) {
  90. f->report_thread_leaks = false;
  91. f->report_destroy_locked = false;
  92. f->report_signal_unsafe = false;
  93. }
  94. InitializeCommonFlags();
  95. if (Verbosity()) ReportUnrecognizedFlags();
  96. if (common_flags()->help) parser.PrintFlagDescriptions();
  97. if (f->history_size < 0 || f->history_size > 7) {
  98. Printf("ThreadSanitizer: incorrect value for history_size"
  99. " (must be [0..7])\n");
  100. Die();
  101. }
  102. if (f->io_sync < 0 || f->io_sync > 2) {
  103. Printf("ThreadSanitizer: incorrect value for io_sync"
  104. " (must be [0..2])\n");
  105. Die();
  106. }
  107. }
  108. } // namespace __tsan