╭ tsan_flags.cpp ───────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
.. builtins/ interception/ sanitizer_common/ ubsan/ LICENSE.TXT tsan_debugging.cpp tsan_defs.h tsan_dense_alloc.h tsan_dispatch_defs.h tsan_external.cpp tsan_fd.cpp tsan_fd.h ╭─────────────────────────────────╮ │tsan_flags.cpp │ ╰─────────────────────────────────╯ tsan_flags.h tsan_flags.inc tsan_ignoreset.cpp tsan_ignoreset.h tsan_ilist.h tsan_interceptors.h tsan_interceptors_mac.cpp tsan_interceptors_mach_vm.cpp tsan_interceptors_memintrinsics.c tsan_interceptors_posix.cpp tsan_interface.cpp tsan_interface.h tsan_interface.inc tsan_interface_ann.cpp tsan_interface_ann.h tsan_interface_atomic.cpp tsan_interface_java.cpp tsan_interface_java.h tsan_malloc_mac.cpp tsan_md5.cpp tsan_mman.cpp tsan_mman.h tsan_mutexset.cpp tsan_mutexset.h tsan_new_delete.cpp tsan_platform.h tsan_platform_linux.cpp tsan_platform_mac.cpp tsan_platform_posix.cpp tsan_platform_windows.cpp tsan_ppc_regs.h tsan_preinit.cpp tsan_report.cpp tsan_report.h tsan_rtl.cpp tsan_rtl.h tsan_rtl_aarch64.S tsan_rtl_access.cpp tsan_rtl_amd64.S tsan_rtl_loongarch64.S tsan_rtl_mips64.S tsan_rtl_mutex.cpp tsan_rtl_ppc64.S tsan_rtl_proc.cpp tsan_rtl_report.cpp tsan_rtl_riscv64.S tsan_rtl_s390x.S tsan_rtl_thread.cpp tsan_shadow.h tsan_stack_trace.cpp tsan_stack_trace.h tsan_suppressions.cpp tsan_suppressions.h tsan_symbolize.cpp tsan_symbolize.h tsan_sync.cpp tsan_sync.h tsan_trace.h tsan_vector_clock.cpp tsan_vector_clock.h
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 13 #include "tsan_flags.h" 14 15 #include "sanitizer_common/sanitizer_flag_parser.h" 16 #include "sanitizer_common/sanitizer_flags.h" 17 #include "sanitizer_common/sanitizer_libc.h" 18 #include "tsan_interface.h" 19 #include "tsan_mman.h" 20 #include "tsan_rtl.h" 21 #include "ubsan/ubsan_flags.h" 22 23 #if SANITIZER_APPLE && !SANITIZER_GO 24 namespace __sanitizer { 25 26 template <> 27 inline bool FlagHandler<LockDuringWriteSetting>::Parse(const char *value) { 28 if (internal_strcmp(value, "on") == 0) { 29 *t_ = kLockDuringAllWrites; 30 return true; 31 } 32 if (internal_strcmp(value, "disable_for_current_process") == 0) { 33 *t_ = kNoLockDuringWritesCurrentProcess; 34 return true; 35 } 36 if (internal_strcmp(value, "disable_for_all_processes") == 0) { 37 *t_ = kNoLockDuringWritesAllProcesses; 38 return true; 39 } 40 Printf("ERROR: Invalid value for signal handler option: '%s'\n", value); 41 return false; 42 } 43 44 template <> 45 inline bool FlagHandler<LockDuringWriteSetting>::Format(char *buffer, 46 uptr size) { 47 switch (*t_) { 48 case kLockDuringAllWrites: 49 return FormatString(buffer, size, "on"); 50 case kNoLockDuringWritesCurrentProcess: 51 return FormatString(buffer, size, "disable_for_current_process"); 52 case kNoLockDuringWritesAllProcesses: 53 return FormatString(buffer, size, "disable_for_all_processes"); 54 } 55 } 56 57 } // namespace __sanitizer 58 #endif // SANITIZER_APPLE && !SANITIZER_GO 59 60 namespace __tsan { 61 62 // Can be overriden in frontend. 63 #ifdef TSAN_EXTERNAL_HOOKS 64 extern "C" const char *__tsan_default_options(); 65 #else 66 SANITIZER_WEAK_DEFAULT_IMPL 67 const char *__tsan_default_options() { 68 return ""; 69 } 70 #endif 71 72 void Flags::SetDefaults() { 73 #define TSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; 74 #include "tsan_flags.inc" 75 #undef TSAN_FLAG 76 // DDFlags 77 second_deadlock_stack = false; 78 } 79 80 void RegisterTsanFlags(FlagParser *parser, Flags *f) { 81 #define TSAN_FLAG(Type, Name, DefaultValue, Description) \ 82 RegisterFlag(parser, #Name, Description, &f->Name); 83 #include "tsan_flags.inc" 84 #undef TSAN_FLAG 85 // DDFlags 86 RegisterFlag(parser, "second_deadlock_stack", 87 "Report where each mutex is locked in deadlock reports", 88 &f->second_deadlock_stack); 89 } 90 91 void InitializeFlags(Flags *f, const char *env, const char *env_option_name) { 92 SetCommonFlagsDefaults(); 93 { 94 // Override some common flags defaults. 95 CommonFlags cf; 96 cf.CopyFrom(*common_flags()); 97 cf.external_symbolizer_path = GetEnv("TSAN_SYMBOLIZER_PATH"); 98 cf.allow_addr2line = true; 99 if (SANITIZER_GO) { 100 // Does not work as expected for Go: runtime handles SIGABRT and crashes. 101 cf.abort_on_error = false; 102 // Go does not have mutexes. 103 cf.detect_deadlocks = false; 104 } 105 cf.print_suppressions = false; 106 cf.stack_trace_format = " #%n %f %S %M"; 107 cf.exitcode = 66; 108 cf.intercept_tls_get_addr = true; 109 OverrideCommonFlags(cf); 110 } 111 112 f->SetDefaults(); 113 114 FlagParser parser; 115 RegisterTsanFlags(&parser, f); 116 RegisterCommonFlags(&parser); 117 118 #if TSAN_CONTAINS_UBSAN 119 __ubsan::Flags *uf = __ubsan::flags(); 120 uf->SetDefaults(); 121 122 FlagParser ubsan_parser; 123 __ubsan::RegisterUbsanFlags(&ubsan_parser, uf); 124 RegisterCommonFlags(&ubsan_parser); 125 #endif 126 127 // Let a frontend override. 128 parser.ParseString(__tsan_default_options()); 129 #if TSAN_CONTAINS_UBSAN 130 const char *ubsan_default_options = __ubsan_default_options(); 131 ubsan_parser.ParseString(ubsan_default_options); 132 #endif 133 // Override from command line. 134 parser.ParseString(env, env_option_name); 135 #if TSAN_CONTAINS_UBSAN 136 ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS"); 137 #endif 138 139 // Check flags. 140 if (!f->report_bugs) { 141 f->report_thread_leaks = false; 142 f->report_destroy_locked = false; 143 f->report_signal_unsafe = false; 144 } 145 146 InitializeCommonFlags(); 147 148 if (Verbosity()) ReportUnrecognizedFlags(); 149 150 if (common_flags()->help) parser.PrintFlagDescriptions(); 151 152 if (f->io_sync < 0 || f->io_sync > 2) { 153 Printf("ThreadSanitizer: incorrect value for io_sync" 154 " (must be [0..2])\n"); 155 Die(); 156 } 157 } 158 159 } // namespace __tsan 160