Alexey Samsonov | 603c4be | 2012-06-04 13:55:19 +0000 | [diff] [blame] | 1 | //===-- tsan_flags.cc -----------------------------------------------------===// |
Kostya Serebryany | 7ac4148 | 2012-05-10 13:48:04 +0000 | [diff] [blame] | 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file is a part of ThreadSanitizer (TSan), a race detector. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Alexey Samsonov | f3be706 | 2012-07-09 13:21:39 +0000 | [diff] [blame] | 14 | #include "sanitizer_common/sanitizer_flags.h" |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 15 | #include "sanitizer_common/sanitizer_flag_parser.h" |
Alexey Samsonov | 230c3be | 2012-06-06 09:26:25 +0000 | [diff] [blame] | 16 | #include "sanitizer_common/sanitizer_libc.h" |
Kostya Serebryany | 7ac4148 | 2012-05-10 13:48:04 +0000 | [diff] [blame] | 17 | #include "tsan_flags.h" |
| 18 | #include "tsan_rtl.h" |
| 19 | #include "tsan_mman.h" |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 20 | #include "ubsan/ubsan_flags.h" |
Kostya Serebryany | 7ac4148 | 2012-05-10 13:48:04 +0000 | [diff] [blame] | 21 | |
| 22 | namespace __tsan { |
| 23 | |
Kostya Serebryany | 7ac4148 | 2012-05-10 13:48:04 +0000 | [diff] [blame] | 24 | Flags *flags() { |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 25 | return &ctx->flags; |
Kostya Serebryany | 7ac4148 | 2012-05-10 13:48:04 +0000 | [diff] [blame] | 26 | } |
| 27 | |
| 28 | // Can be overriden in frontend. |
Dmitry Vyukov | 87dbdf5 | 2012-07-25 14:30:51 +0000 | [diff] [blame] | 29 | #ifdef TSAN_EXTERNAL_HOOKS |
Dmitry Vyukov | f719b92 | 2013-10-15 15:58:11 +0000 | [diff] [blame] | 30 | extern "C" const char* __tsan_default_options(); |
Dmitry Vyukov | 87dbdf5 | 2012-07-25 14:30:51 +0000 | [diff] [blame] | 31 | #else |
Pirama Arumuga Nainar | 799172d | 2016-03-03 15:50:30 -0800 | [diff] [blame^] | 32 | SANITIZER_WEAK_DEFAULT_IMPL |
| 33 | const char *__tsan_default_options() { |
Dmitry Vyukov | f719b92 | 2013-10-15 15:58:11 +0000 | [diff] [blame] | 34 | return ""; |
| 35 | } |
Dmitry Vyukov | 87dbdf5 | 2012-07-25 14:30:51 +0000 | [diff] [blame] | 36 | #endif |
Kostya Serebryany | 7ac4148 | 2012-05-10 13:48:04 +0000 | [diff] [blame] | 37 | |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 38 | void Flags::SetDefaults() { |
| 39 | #define TSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; |
| 40 | #include "tsan_flags.inc" |
| 41 | #undef TSAN_FLAG |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 42 | // DDFlags |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 43 | second_deadlock_stack = false; |
| 44 | } |
| 45 | |
| 46 | void RegisterTsanFlags(FlagParser *parser, Flags *f) { |
| 47 | #define TSAN_FLAG(Type, Name, DefaultValue, Description) \ |
| 48 | RegisterFlag(parser, #Name, Description, &f->Name); |
| 49 | #include "tsan_flags.inc" |
| 50 | #undef TSAN_FLAG |
Pirama Arumuga Nainar | 259f706 | 2015-05-06 11:49:53 -0700 | [diff] [blame] | 51 | // DDFlags |
| 52 | RegisterFlag(parser, "second_deadlock_stack", |
| 53 | "Report where each mutex is locked in deadlock reports", |
| 54 | &f->second_deadlock_stack); |
Dmitry Vyukov | f719b92 | 2013-10-15 15:58:11 +0000 | [diff] [blame] | 55 | } |
| 56 | |
Kostya Serebryany | 7ac4148 | 2012-05-10 13:48:04 +0000 | [diff] [blame] | 57 | void InitializeFlags(Flags *f, const char *env) { |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 58 | SetCommonFlagsDefaults(); |
| 59 | { |
| 60 | // Override some common flags defaults. |
| 61 | CommonFlags cf; |
| 62 | cf.CopyFrom(*common_flags()); |
| 63 | cf.allow_addr2line = true; |
Pirama Arumuga Nainar | 799172d | 2016-03-03 15:50:30 -0800 | [diff] [blame^] | 64 | if (kGoMode) { |
| 65 | // Does not work as expected for Go: runtime handles SIGABRT and crashes. |
| 66 | cf.abort_on_error = false; |
| 67 | // Go does not have mutexes. |
| 68 | } else { |
| 69 | cf.detect_deadlocks = true; |
| 70 | } |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 71 | cf.print_suppressions = false; |
| 72 | cf.stack_trace_format = " #%n %f %S %M"; |
Pirama Arumuga Nainar | 799172d | 2016-03-03 15:50:30 -0800 | [diff] [blame^] | 73 | cf.exitcode = 66; |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 74 | OverrideCommonFlags(cf); |
| 75 | } |
Dmitry Vyukov | 6866dba | 2013-10-15 13:28:51 +0000 | [diff] [blame] | 76 | |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 77 | f->SetDefaults(); |
| 78 | |
| 79 | FlagParser parser; |
| 80 | RegisterTsanFlags(&parser, f); |
| 81 | RegisterCommonFlags(&parser); |
| 82 | |
| 83 | #if TSAN_CONTAINS_UBSAN |
| 84 | __ubsan::Flags *uf = __ubsan::flags(); |
| 85 | uf->SetDefaults(); |
| 86 | |
| 87 | FlagParser ubsan_parser; |
| 88 | __ubsan::RegisterUbsanFlags(&ubsan_parser, uf); |
| 89 | RegisterCommonFlags(&ubsan_parser); |
| 90 | #endif |
| 91 | |
Kostya Serebryany | 7ac4148 | 2012-05-10 13:48:04 +0000 | [diff] [blame] | 92 | // Let a frontend override. |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 93 | parser.ParseString(__tsan_default_options()); |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 94 | #if TSAN_CONTAINS_UBSAN |
| 95 | const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions(); |
| 96 | ubsan_parser.ParseString(ubsan_default_options); |
| 97 | #endif |
Kostya Serebryany | 7ac4148 | 2012-05-10 13:48:04 +0000 | [diff] [blame] | 98 | // Override from command line. |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 99 | parser.ParseString(env); |
Pirama Arumuga Nainar | cdce50b | 2015-07-01 12:26:56 -0700 | [diff] [blame] | 100 | #if TSAN_CONTAINS_UBSAN |
| 101 | ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS")); |
| 102 | #endif |
Dmitry Vyukov | 8a32677 | 2012-11-07 16:14:12 +0000 | [diff] [blame] | 103 | |
Alexey Samsonov | 55c7947 | 2013-11-12 13:59:08 +0000 | [diff] [blame] | 104 | // Sanity check. |
Dmitry Vyukov | 8a32677 | 2012-11-07 16:14:12 +0000 | [diff] [blame] | 105 | if (!f->report_bugs) { |
| 106 | f->report_thread_leaks = false; |
| 107 | f->report_destroy_locked = false; |
| 108 | f->report_signal_unsafe = false; |
| 109 | } |
Dmitry Vyukov | d698edc | 2012-11-28 12:19:50 +0000 | [diff] [blame] | 110 | |
Stephen Hines | 86277eb | 2015-03-23 12:06:32 -0700 | [diff] [blame] | 111 | SetVerbosity(common_flags()->verbosity); |
| 112 | |
| 113 | if (Verbosity()) ReportUnrecognizedFlags(); |
| 114 | |
| 115 | if (common_flags()->help) parser.PrintFlagDescriptions(); |
Stephen Hines | 2d1fdb2 | 2014-05-28 23:58:16 -0700 | [diff] [blame] | 116 | |
Dmitry Vyukov | d698edc | 2012-11-28 12:19:50 +0000 | [diff] [blame] | 117 | if (f->history_size < 0 || f->history_size > 7) { |
| 118 | Printf("ThreadSanitizer: incorrect value for history_size" |
| 119 | " (must be [0..7])\n"); |
| 120 | Die(); |
| 121 | } |
Dmitry Vyukov | e3178e8 | 2012-12-18 12:20:55 +0000 | [diff] [blame] | 122 | |
| 123 | if (f->io_sync < 0 || f->io_sync > 2) { |
| 124 | Printf("ThreadSanitizer: incorrect value for io_sync" |
| 125 | " (must be [0..2])\n"); |
| 126 | Die(); |
| 127 | } |
Kostya Serebryany | 7ac4148 | 2012-05-10 13:48:04 +0000 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | } // namespace __tsan |