1 //===-- tsan_flags.cc -----------------------------------------------------===// 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 14 #include "sanitizer_common/sanitizer_flags.h" 15 #include "sanitizer_common/sanitizer_libc.h" 16 #include "tsan_flags.h" 17 #include "tsan_rtl.h" 18 #include "tsan_mman.h" 19 20 namespace __tsan { 21 22 Flags *flags() { 23 return &ctx->flags; 24 } 25 26 // Can be overriden in frontend. 27 #ifdef TSAN_EXTERNAL_HOOKS 28 extern "C" const char* __tsan_default_options(); 29 #else 30 extern "C" SANITIZER_INTERFACE_ATTRIBUTE 31 const char *WEAK __tsan_default_options() { 32 return ""; 33 } 34 #endif 35 36 static void ParseFlags(Flags *f, const char *env) { 37 ParseFlag(env, &f->enable_annotations, "enable_annotations", ""); 38 ParseFlag(env, &f->suppress_equal_stacks, "suppress_equal_stacks", ""); 39 ParseFlag(env, &f->suppress_equal_addresses, "suppress_equal_addresses", ""); 40 ParseFlag(env, &f->suppress_java, "suppress_java", ""); 41 ParseFlag(env, &f->report_bugs, "report_bugs", ""); 42 ParseFlag(env, &f->report_thread_leaks, "report_thread_leaks", ""); 43 ParseFlag(env, &f->report_destroy_locked, "report_destroy_locked", ""); 44 ParseFlag(env, &f->report_mutex_bugs, "report_mutex_bugs", ""); 45 ParseFlag(env, &f->report_signal_unsafe, "report_signal_unsafe", ""); 46 ParseFlag(env, &f->report_atomic_races, "report_atomic_races", ""); 47 ParseFlag(env, &f->force_seq_cst_atomics, "force_seq_cst_atomics", ""); 48 ParseFlag(env, &f->suppressions, "suppressions", ""); 49 ParseFlag(env, &f->print_suppressions, "print_suppressions", ""); 50 ParseFlag(env, &f->print_benign, "print_benign", ""); 51 ParseFlag(env, &f->exitcode, "exitcode", ""); 52 ParseFlag(env, &f->halt_on_error, "halt_on_error", ""); 53 ParseFlag(env, &f->atexit_sleep_ms, "atexit_sleep_ms", ""); 54 ParseFlag(env, &f->profile_memory, "profile_memory", ""); 55 ParseFlag(env, &f->flush_memory_ms, "flush_memory_ms", ""); 56 ParseFlag(env, &f->flush_symbolizer_ms, "flush_symbolizer_ms", ""); 57 ParseFlag(env, &f->memory_limit_mb, "memory_limit_mb", ""); 58 ParseFlag(env, &f->stop_on_start, "stop_on_start", ""); 59 ParseFlag(env, &f->running_on_valgrind, "running_on_valgrind", ""); 60 ParseFlag(env, &f->history_size, "history_size", ""); 61 ParseFlag(env, &f->io_sync, "io_sync", ""); 62 ParseFlag(env, &f->die_after_fork, "die_after_fork", ""); 63 64 // DDFlags 65 ParseFlag(env, &f->second_deadlock_stack, "second_deadlock_stack", ""); 66 } 67 68 void InitializeFlags(Flags *f, const char *env) { 69 internal_memset(f, 0, sizeof(*f)); 70 71 // Default values. 72 f->enable_annotations = true; 73 f->suppress_equal_stacks = true; 74 f->suppress_equal_addresses = true; 75 f->suppress_java = false; 76 f->report_bugs = true; 77 f->report_thread_leaks = true; 78 f->report_destroy_locked = true; 79 f->report_mutex_bugs = true; 80 f->report_signal_unsafe = true; 81 f->report_atomic_races = true; 82 f->force_seq_cst_atomics = false; 83 f->suppressions = ""; 84 f->print_suppressions = false; 85 f->print_benign = false; 86 f->exitcode = 66; 87 f->halt_on_error = false; 88 f->atexit_sleep_ms = 1000; 89 f->profile_memory = ""; 90 f->flush_memory_ms = 0; 91 f->flush_symbolizer_ms = 5000; 92 f->memory_limit_mb = 0; 93 f->stop_on_start = false; 94 f->running_on_valgrind = false; 95 f->history_size = kGoMode ? 1 : 2; // There are a lot of goroutines in Go. 96 f->io_sync = 1; 97 f->die_after_fork = true; 98 99 // DDFlags 100 f->second_deadlock_stack = false; 101 102 SetCommonFlagsDefaults(f); 103 // Override some common flags defaults. 104 f->allow_addr2line = true; 105 f->detect_deadlocks = true; 106 107 // Let a frontend override. 108 ParseFlags(f, __tsan_default_options()); 109 ParseCommonFlagsFromString(f, __tsan_default_options()); 110 // Override from command line. 111 ParseFlags(f, env); 112 ParseCommonFlagsFromString(f, env); 113 114 // Copy back to common flags. 115 *common_flags() = *f; 116 117 // Sanity check. 118 if (!f->report_bugs) { 119 f->report_thread_leaks = false; 120 f->report_destroy_locked = false; 121 f->report_signal_unsafe = false; 122 } 123 124 if (f->help) PrintFlagDescriptions(); 125 126 if (f->history_size < 0 || f->history_size > 7) { 127 Printf("ThreadSanitizer: incorrect value for history_size" 128 " (must be [0..7])\n"); 129 Die(); 130 } 131 132 if (f->io_sync < 0 || f->io_sync > 2) { 133 Printf("ThreadSanitizer: incorrect value for io_sync" 134 " (must be [0..2])\n"); 135 Die(); 136 } 137 } 138 139 } // namespace __tsan 140