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