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