tsan_flags.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. //===-- tsan_flags.cc -----------------------------------------------------===//
  2. //
  3. // This file is distributed under the University of Illinois Open Source
  4. // License. See LICENSE.TXT for details.
  5. //
  6. //===----------------------------------------------------------------------===//
  7. //
  8. // This file is a part of ThreadSanitizer (TSan), a race detector.
  9. //
  10. //===----------------------------------------------------------------------===//
  11. #include "sanitizer_common/sanitizer_flags.h"
  12. #include "sanitizer_common/sanitizer_libc.h"
  13. #include "tsan_flags.h"
  14. #include "tsan_rtl.h"
  15. #include "tsan_mman.h"
  16. namespace __tsan {
  17. Flags *flags() {
  18. return &ctx->flags;
  19. }
  20. // Can be overriden in frontend.
  21. #ifdef TSAN_EXTERNAL_HOOKS
  22. extern "C" const char* __tsan_default_options();
  23. #else
  24. extern "C" SANITIZER_INTERFACE_ATTRIBUTE
  25. const char *WEAK __tsan_default_options() {
  26. return "";
  27. }
  28. #endif
  29. static void ParseFlags(Flags *f, const char *env) {
  30. ParseFlag(env, &f->enable_annotations, "enable_annotations", "");
  31. ParseFlag(env, &f->suppress_equal_stacks, "suppress_equal_stacks", "");
  32. ParseFlag(env, &f->suppress_equal_addresses, "suppress_equal_addresses", "");
  33. ParseFlag(env, &f->report_bugs, "report_bugs", "");
  34. ParseFlag(env, &f->report_thread_leaks, "report_thread_leaks", "");
  35. ParseFlag(env, &f->report_destroy_locked, "report_destroy_locked", "");
  36. ParseFlag(env, &f->report_mutex_bugs, "report_mutex_bugs", "");
  37. ParseFlag(env, &f->report_signal_unsafe, "report_signal_unsafe", "");
  38. ParseFlag(env, &f->report_atomic_races, "report_atomic_races", "");
  39. ParseFlag(env, &f->force_seq_cst_atomics, "force_seq_cst_atomics", "");
  40. ParseFlag(env, &f->print_benign, "print_benign", "");
  41. ParseFlag(env, &f->exitcode, "exitcode", "");
  42. ParseFlag(env, &f->halt_on_error, "halt_on_error", "");
  43. ParseFlag(env, &f->atexit_sleep_ms, "atexit_sleep_ms", "");
  44. ParseFlag(env, &f->profile_memory, "profile_memory", "");
  45. ParseFlag(env, &f->flush_memory_ms, "flush_memory_ms", "");
  46. ParseFlag(env, &f->flush_symbolizer_ms, "flush_symbolizer_ms", "");
  47. ParseFlag(env, &f->memory_limit_mb, "memory_limit_mb", "");
  48. ParseFlag(env, &f->stop_on_start, "stop_on_start", "");
  49. ParseFlag(env, &f->running_on_valgrind, "running_on_valgrind", "");
  50. ParseFlag(env, &f->history_size, "history_size", "");
  51. ParseFlag(env, &f->io_sync, "io_sync", "");
  52. ParseFlag(env, &f->die_after_fork, "die_after_fork", "");
  53. // DDFlags
  54. ParseFlag(env, &f->second_deadlock_stack, "second_deadlock_stack", "");
  55. }
  56. void InitializeFlags(Flags *f, const char *env) {
  57. internal_memset(f, 0, sizeof(*f));
  58. // Default values.
  59. f->enable_annotations = true;
  60. f->suppress_equal_stacks = true;
  61. f->suppress_equal_addresses = true;
  62. f->report_bugs = true;
  63. f->report_thread_leaks = true;
  64. f->report_destroy_locked = true;
  65. f->report_mutex_bugs = true;
  66. f->report_signal_unsafe = true;
  67. f->report_atomic_races = true;
  68. f->force_seq_cst_atomics = false;
  69. f->print_benign = false;
  70. f->exitcode = 66;
  71. f->halt_on_error = false;
  72. f->atexit_sleep_ms = 1000;
  73. f->profile_memory = "";
  74. f->flush_memory_ms = 0;
  75. f->flush_symbolizer_ms = 5000;
  76. f->memory_limit_mb = 0;
  77. f->stop_on_start = false;
  78. f->running_on_valgrind = false;
  79. f->history_size = kGoMode ? 1 : 2; // There are a lot of goroutines in Go.
  80. f->io_sync = 1;
  81. f->die_after_fork = true;
  82. // DDFlags
  83. f->second_deadlock_stack = false;
  84. CommonFlags *cf = common_flags();
  85. SetCommonFlagsDefaults(cf);
  86. // Override some common flags defaults.
  87. cf->allow_addr2line = true;
  88. cf->detect_deadlocks = true;
  89. cf->print_suppressions = false;
  90. cf->stack_trace_format = " #%n %f %S %M";
  91. // Let a frontend override.
  92. ParseFlags(f, __tsan_default_options());
  93. ParseCommonFlagsFromString(cf, __tsan_default_options());
  94. // Override from command line.
  95. ParseFlags(f, env);
  96. ParseCommonFlagsFromString(cf, env);
  97. // Sanity check.
  98. if (!f->report_bugs) {
  99. f->report_thread_leaks = false;
  100. f->report_destroy_locked = false;
  101. f->report_signal_unsafe = false;
  102. }
  103. if (cf->help) PrintFlagDescriptions();
  104. if (f->history_size < 0 || f->history_size > 7) {
  105. Printf("ThreadSanitizer: incorrect value for history_size"
  106. " (must be [0..7])\n");
  107. Die();
  108. }
  109. if (f->io_sync < 0 || f->io_sync > 2) {
  110. Printf("ThreadSanitizer: incorrect value for io_sync"
  111. " (must be [0..2])\n");
  112. Die();
  113. }
  114. }
  115. } // namespace __tsan