1/* Copyright (c) 2008-2010, Google Inc.
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Neither the name of Google Inc. nor the names of its
11 * contributors may be used to endorse or promote products derived from
12 * this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27// This file is part of ThreadSanitizer, a dynamic data race detector.
28// Author: Konstantin Serebryany.
29//--------- Head ------------------- {{{1
30#ifndef THREAD_SANITIZER_H_
31#define THREAD_SANITIZER_H_
32
33#include "ts_util.h"
34#include "ts_atomic.h"
35
36//--------- Utils ------------------- {{{1
37
38void Report(const char *format, ...);
39void PcToStrings(uintptr_t pc, bool demangle,
40                string *img_name, string *rtn_name,
41                string *file_name, int *line_no);
42string PcToRtnNameAndFilePos(uintptr_t pc);
43string PcToRtnName(uintptr_t pc, bool demangle);
44string Demangle(const char *str);
45
46
47//--------- FLAGS ---------------------------------- {{{1
48struct FLAGS {
49  string           input_type; // for ts_offline.
50                               // Possible values: str, bin, decode.
51  bool             ignore_stack;
52  intptr_t         verbosity;
53  intptr_t         show_stats;  // 0 -- no stats; 1 -- some stats; 2 more stats.
54  bool             trace_profile;
55  bool             show_expected_races;
56  uintptr_t        trace_addr;
57  uintptr_t        segment_set_recycle_queue_size;
58  uintptr_t        recent_segments_cache_size;
59  vector<string>   file_prefix_to_cut;
60  vector<string>   ignore;
61  vector<string>   whitelist;
62  bool             ignore_unknown_pcs;  // Ignore PCs with no debug info.
63  vector<string>   cut_stack_below;
64  string           summary_file;
65  string           log_file;
66  bool             offline;
67  intptr_t         max_n_threads;
68  bool             compress_cache_lines;
69  bool             unlock_on_mutex_destroy;
70
71  intptr_t         sample_events;
72  intptr_t         sample_events_depth;
73
74  intptr_t         num_callers;
75
76  intptr_t    keep_history;
77  bool        pure_happens_before;
78  bool        free_is_write;
79  bool        exit_after_main;
80  bool        demangle;
81  bool        announce_threads;
82  bool        full_output;
83  bool        show_states;
84  bool        show_proc_self_status;
85  bool        show_valgrind_context;  // debug-only
86  bool        suggest_happens_before_arcs;
87  bool        show_pc;
88  bool        full_stack_frames;
89  bool        color;  // Colorify terminal output.
90  bool        html;  // Output in html format.
91  bool        show_pid;
92
93  intptr_t  debug_level;
94  bool        save_ignore_context;  // print stack if ignore_end was forgotten.
95  vector<string> debug_phase;
96  intptr_t  trace_level;
97
98  intptr_t     dry_run;
99  intptr_t     max_sid;
100  intptr_t     max_sid_before_flush;
101  intptr_t     max_mem_in_mb;
102  intptr_t     num_callers_in_history;
103  intptr_t     flush_period;
104
105  intptr_t     literace_sampling;
106  bool         start_with_global_ignore_on;
107
108  intptr_t     locking_scheme;  // Used for internal experiments with locking.
109
110  bool         report_races;
111  bool         thread_coverage;
112  bool         atomicity;
113  bool         call_coverage;
114  string       dump_events;  // The name of log file. Debug mode only.
115  bool         symbolize;
116  bool         attach_mode;
117
118  string       tsan_program_name;
119  string       tsan_url;
120
121  vector<string> suppressions;
122  bool           generate_suppressions;
123
124  intptr_t     error_exitcode;
125  bool         trace_children;
126
127  vector<string> race_verifier;
128  vector<string> race_verifier_extra;
129  intptr_t       race_verifier_sleep_ms;
130
131  bool nacl_untrusted;
132
133  bool threaded_analysis;
134
135  bool sched_shake;
136  bool api_ambush;
137
138  bool enable_atomic;
139};
140
141extern FLAGS *G_flags;
142
143extern bool g_race_verifier_active;
144
145extern bool debug_expected_races;
146extern bool debug_malloc;
147extern bool debug_free;
148extern bool debug_thread;
149extern bool debug_rtn;
150extern bool debug_wrap;
151extern bool debug_ins;
152extern bool debug_shadow_stack;
153extern bool debug_race_verifier;
154
155// -------- CallStack ------------- {{{1
156const size_t kMaxCallStackSize = 1 << 12;
157
158struct CallStackPod {
159  uintptr_t *end_;
160  uintptr_t pcs_[kMaxCallStackSize];
161};
162
163struct CallStack: public CallStackPod {
164
165  CallStack() { Clear(); }
166
167  size_t size() { return (size_t)(end_ - pcs_); }
168  uintptr_t *pcs() { return pcs_; }
169
170  bool empty() { return end_ == pcs_; }
171
172  uintptr_t &back() {
173    DCHECK(!empty());
174    return *(end_ - 1);
175  }
176
177  void pop_back() {
178    DCHECK(!empty());
179    end_--;
180  }
181
182  void push_back(uintptr_t pc) {
183    DCHECK(size() < kMaxCallStackSize);
184    *end_ = pc;
185    end_++;
186  }
187
188  void Clear() {
189    end_ = pcs_;
190  }
191
192  uintptr_t &operator[] (size_t i) {
193    DCHECK(i < size());
194    return pcs_[i];
195  }
196
197};
198
199//--------- TS Exports ----------------- {{{1
200#include "ts_events.h"
201#include "ts_trace_info.h"
202
203struct TSanThread;
204void ThreadSanitizerInit();
205void ThreadSanitizerFini();
206// TODO(glider): this is a temporary solution to avoid deadlocks after fork().
207#ifdef TS_LLVM
208void ThreadSanitizerLockAcquire();
209void ThreadSanitizerLockRelease();
210#endif
211void ThreadSanitizerHandleOneEvent(Event *event);
212TSanThread *ThreadSanitizerGetThreadByTid(int32_t tid);
213void ThreadSanitizerHandleTrace(int32_t tid, TraceInfo *trace_info,
214                                       uintptr_t *tleb);
215void ThreadSanitizerHandleTrace(TSanThread *thr, TraceInfo *trace_info,
216                                       uintptr_t *tleb);
217void ThreadSanitizerHandleOneMemoryAccess(TSanThread *thr, MopInfo mop,
218                                                 uintptr_t addr);
219void ThreadSanitizerParseFlags(vector<string>* args);
220bool ThreadSanitizerWantToInstrumentSblock(uintptr_t pc);
221bool ThreadSanitizerWantToCreateSegmentsOnSblockEntry(uintptr_t pc);
222bool ThreadSanitizerIgnoreAccessesBelowFunction(uintptr_t pc);
223
224typedef int (*ThreadSanitizerUnwindCallback)(uintptr_t* stack, int size, uintptr_t pc);
225void ThreadSanitizerSetUnwindCallback(ThreadSanitizerUnwindCallback cb);
226
227/** Atomic operation handler.
228 *  @param tid ID of a thread that issues the operation.
229 *  @param pc Program counter that should be associated with the operation.
230 *  @param op Type of the operation (load, store, etc).
231 *  @param mo Memory ordering associated with the operation
232 *      (relaxed, acquire, release, etc). NB there are some restrictions on
233 *      what memory orderings can be used with what types of operations.
234 *      E.g. a store can't have an acquire semantics
235 *      (see C++0x standard draft for details).
236 *  @param fail_mo Memory ordering the operation has if it fails,
237 *      applicable only to compare_exchange oprations.
238 *  @param size Size of the memory access in bytes (1, 2, 4 or 8).
239 *  @param a Address of the memory access.
240 *  @param v Operand for the operation (e.g. a value to store).
241 *  @param cmp Comparand for compare_exchange oprations.
242 *  @return Result of the operation (e.g. loaded value).
243 */
244uint64_t ThreadSanitizerHandleAtomicOp(int32_t tid,
245                                       uintptr_t pc,
246                                       tsan_atomic_op op,
247                                       tsan_memory_order mo,
248                                       tsan_memory_order fail_mo,
249                                       size_t size,
250                                       void volatile* a,
251                                       uint64_t v,
252                                       uint64_t cmp);
253
254enum IGNORE_BELOW_RTN {
255  IGNORE_BELOW_RTN_UNKNOWN,
256  IGNORE_BELOW_RTN_NO,
257  IGNORE_BELOW_RTN_YES
258};
259
260void ThreadSanitizerHandleRtnCall(int32_t tid, uintptr_t call_pc,
261                                         uintptr_t target_pc,
262                                         IGNORE_BELOW_RTN ignore_below);
263
264void ThreadSanitizerHandleRtnExit(int32_t tid);
265
266void ThreadSanitizerPrintUsage();
267extern "C" const char *ThreadSanitizerQuery(const char *query);
268bool PhaseDebugIsOn(const char *phase_name);
269
270extern bool g_has_entered_main;
271extern bool g_has_exited_main;
272
273// -------- Stats ------------------- {{{1
274#include "ts_stats.h"
275extern Stats *G_stats;
276
277// -------- Expected Race ---------------------- {{{1
278// Information about expected races.
279struct ExpectedRace {
280  uintptr_t   ptr;
281  uintptr_t   size;
282  bool        is_verifiable;
283  bool        is_nacl_untrusted;
284  int         count;
285  const char *description;
286  uintptr_t   pc;
287};
288
289ExpectedRace* ThreadSanitizerFindExpectedRace(uintptr_t addr);
290
291// Tell ThreadSanitizer about the location of NaCl untrusted region.
292void ThreadSanitizerNaclUntrustedRegion(uintptr_t mem_start, uintptr_t mem_end);
293
294// Returns true if accesses and locks at the given address should be ignored
295// according to the current NaCl flags (--nacl-untrusted). Always false if not a
296// NaCl program.
297bool ThreadSanitizerIgnoreForNacl(uintptr_t addr);
298
299// end. {{{1
300#endif  //  THREAD_SANITIZER_H_
301
302// vim:shiftwidth=2:softtabstop=2:expandtab
303