tsan_flags.cc revision d51a1a10cba87be50e9ada9fa21337c387edb237
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_libc.h"
15#include "tsan_flags.h"
16#include "tsan_rtl.h"
17#include "tsan_mman.h"
18
19namespace __tsan {
20
21static void Flag(const char *env, bool *flag, const char *name);
22static void Flag(const char *env, int *flag, const char *name);
23static void Flag(const char *env, const char **flag, const char *name);
24
25Flags *flags() {
26  return &CTX()->flags;
27}
28
29// Can be overriden in frontend.
30void WEAK OverrideFlags(Flags *f) {
31  (void)f;
32}
33
34void InitializeFlags(Flags *f, const char *env) {
35  internal_memset(f, 0, sizeof(*f));
36
37  // Default values.
38  f->enable_annotations = true;
39  f->suppress_equal_stacks = true;
40  f->suppress_equal_addresses = true;
41  f->report_thread_leaks = true;
42  f->report_signal_unsafe = true;
43  f->force_seq_cst_atomics = false;
44  f->strip_path_prefix = "";
45  f->suppressions = "";
46  f->exitcode = 66;
47  f->log_fileno = 2;
48  f->atexit_sleep_ms = 1000;
49  f->verbosity = 0;
50  f->profile_memory = "";
51  f->flush_memory_ms = 0;
52  f->stop_on_start = false;
53  f->running_on_valgrind = false;
54
55
56  // Let a frontend override.
57  OverrideFlags(f);
58
59  // Override from command line.
60  Flag(env, &f->enable_annotations, "enable_annotations");
61  Flag(env, &f->suppress_equal_stacks, "suppress_equal_stacks");
62  Flag(env, &f->suppress_equal_addresses, "suppress_equal_addresses");
63  Flag(env, &f->report_thread_leaks, "report_thread_leaks");
64  Flag(env, &f->report_signal_unsafe, "report_signal_unsafe");
65  Flag(env, &f->force_seq_cst_atomics, "force_seq_cst_atomics");
66  Flag(env, &f->strip_path_prefix, "strip_path_prefix");
67  Flag(env, &f->suppressions, "suppressions");
68  Flag(env, &f->exitcode, "exitcode");
69  Flag(env, &f->log_fileno, "log_fileno");
70  Flag(env, &f->atexit_sleep_ms, "atexit_sleep_ms");
71  Flag(env, &f->verbosity, "verbosity");
72  Flag(env, &f->profile_memory, "profile_memory");
73  Flag(env, &f->flush_memory_ms, "flush_memory_ms");
74  Flag(env, &f->stop_on_start, "stop_on_start");
75}
76
77static const char *GetFlagValue(const char *env, const char *name,
78                                const char **end) {
79  if (env == 0)
80    return *end = 0;
81  const char *pos = internal_strstr(env, name);
82  if (pos == 0)
83    return *end = 0;
84  pos += internal_strlen(name);
85  if (pos[0] != '=')
86    return *end = pos;
87  pos += 1;
88  if (pos[0] == '"') {
89    pos += 1;
90    *end = internal_strchr(pos, '"');
91  } else if (pos[0] == '\'') {
92    pos += 1;
93    *end = internal_strchr(pos, '\'');
94  } else {
95    *end = internal_strchr(pos, ' ');
96  }
97  if (*end == 0)
98    *end = pos + internal_strlen(pos);
99  return pos;
100}
101
102static void Flag(const char *env, bool *flag, const char *name) {
103  const char *end = 0;
104  const char *val = GetFlagValue(env, name, &end);
105  if (val == 0)
106    return;
107  int len = end - val;
108  if (len == 1 && val[0] == '0')
109    *flag = false;
110  else if (len == 1 && val[0] == '1')
111    *flag = true;
112}
113
114static void Flag(const char *env, int *flag, const char *name) {
115  const char *end = 0;
116  const char *val = GetFlagValue(env, name, &end);
117  if (val == 0)
118    return;
119  bool minus = false;
120  if (val != end && val[0] == '-') {
121    minus = true;
122    val += 1;
123  }
124  int v = 0;
125  for (; val != end; val++) {
126    if (val[0] < '0' || val[0] > '9')
127      break;
128    v = v * 10 + val[0] - '0';
129  }
130  if (minus)
131    v = -v;
132  *flag = v;
133}
134
135static void Flag(const char *env, const char **flag, const char *name) {
136  const char *end = 0;
137  const char *val = GetFlagValue(env, name, &end);
138  if (val == 0)
139    return;
140  int len = end - val;
141  char *f = (char*)internal_alloc(MBlockFlag, len + 1);
142  internal_memcpy(f, val, len);
143  f[len] = 0;
144  *flag = f;
145}
146
147}  // namespace __tsan
148