blob: 761523171c7708b9e34dcabb6a64ccfc5f54ea6e [file] [log] [blame]
Alexey Samsonov603c4be2012-06-04 13:55:19 +00001//===-- tsan_flags.cc -----------------------------------------------------===//
Kostya Serebryany7ac41482012-05-10 13:48:04 +00002//
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 Samsonovf3be7062012-07-09 13:21:39 +000014#include "sanitizer_common/sanitizer_flags.h"
Stephen Hines86277eb2015-03-23 12:06:32 -070015#include "sanitizer_common/sanitizer_flag_parser.h"
Alexey Samsonov230c3be2012-06-06 09:26:25 +000016#include "sanitizer_common/sanitizer_libc.h"
Kostya Serebryany7ac41482012-05-10 13:48:04 +000017#include "tsan_flags.h"
18#include "tsan_rtl.h"
19#include "tsan_mman.h"
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070020#include "ubsan/ubsan_flags.h"
Kostya Serebryany7ac41482012-05-10 13:48:04 +000021
22namespace __tsan {
23
Kostya Serebryany7ac41482012-05-10 13:48:04 +000024Flags *flags() {
Stephen Hines2d1fdb22014-05-28 23:58:16 -070025 return &ctx->flags;
Kostya Serebryany7ac41482012-05-10 13:48:04 +000026}
27
28// Can be overriden in frontend.
Dmitry Vyukov87dbdf52012-07-25 14:30:51 +000029#ifdef TSAN_EXTERNAL_HOOKS
Dmitry Vyukovf719b922013-10-15 15:58:11 +000030extern "C" const char* __tsan_default_options();
Dmitry Vyukov87dbdf52012-07-25 14:30:51 +000031#else
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080032SANITIZER_WEAK_DEFAULT_IMPL
33const char *__tsan_default_options() {
Dmitry Vyukovf719b922013-10-15 15:58:11 +000034 return "";
35}
Dmitry Vyukov87dbdf52012-07-25 14:30:51 +000036#endif
Kostya Serebryany7ac41482012-05-10 13:48:04 +000037
Stephen Hines86277eb2015-03-23 12:06:32 -070038void Flags::SetDefaults() {
39#define TSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
40#include "tsan_flags.inc"
41#undef TSAN_FLAG
Stephen Hines2d1fdb22014-05-28 23:58:16 -070042 // DDFlags
Stephen Hines86277eb2015-03-23 12:06:32 -070043 second_deadlock_stack = false;
44}
45
46void 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 Nainar259f7062015-05-06 11:49:53 -070051 // DDFlags
52 RegisterFlag(parser, "second_deadlock_stack",
53 "Report where each mutex is locked in deadlock reports",
54 &f->second_deadlock_stack);
Dmitry Vyukovf719b922013-10-15 15:58:11 +000055}
56
Kostya Serebryany7ac41482012-05-10 13:48:04 +000057void InitializeFlags(Flags *f, const char *env) {
Stephen Hines86277eb2015-03-23 12:06:32 -070058 SetCommonFlagsDefaults();
59 {
60 // Override some common flags defaults.
61 CommonFlags cf;
62 cf.CopyFrom(*common_flags());
63 cf.allow_addr2line = true;
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080064 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 Hines86277eb2015-03-23 12:06:32 -070071 cf.print_suppressions = false;
72 cf.stack_trace_format = " #%n %f %S %M";
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080073 cf.exitcode = 66;
Stephen Hines86277eb2015-03-23 12:06:32 -070074 OverrideCommonFlags(cf);
75 }
Dmitry Vyukov6866dba2013-10-15 13:28:51 +000076
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070077 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 Serebryany7ac41482012-05-10 13:48:04 +000092 // Let a frontend override.
Stephen Hines86277eb2015-03-23 12:06:32 -070093 parser.ParseString(__tsan_default_options());
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070094#if TSAN_CONTAINS_UBSAN
95 const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
96 ubsan_parser.ParseString(ubsan_default_options);
97#endif
Kostya Serebryany7ac41482012-05-10 13:48:04 +000098 // Override from command line.
Stephen Hines86277eb2015-03-23 12:06:32 -070099 parser.ParseString(env);
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -0700100#if TSAN_CONTAINS_UBSAN
101 ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
102#endif
Dmitry Vyukov8a326772012-11-07 16:14:12 +0000103
Alexey Samsonov55c79472013-11-12 13:59:08 +0000104 // Sanity check.
Dmitry Vyukov8a326772012-11-07 16:14:12 +0000105 if (!f->report_bugs) {
106 f->report_thread_leaks = false;
107 f->report_destroy_locked = false;
108 f->report_signal_unsafe = false;
109 }
Dmitry Vyukovd698edc2012-11-28 12:19:50 +0000110
Stephen Hines86277eb2015-03-23 12:06:32 -0700111 SetVerbosity(common_flags()->verbosity);
112
113 if (Verbosity()) ReportUnrecognizedFlags();
114
115 if (common_flags()->help) parser.PrintFlagDescriptions();
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700116
Dmitry Vyukovd698edc2012-11-28 12:19:50 +0000117 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 Vyukove3178e82012-12-18 12:20:55 +0000122
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 Serebryany7ac41482012-05-10 13:48:04 +0000128}
129
130} // namespace __tsan