• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
38 void Report(const char *format, ...);
39 void PcToStrings(uintptr_t pc, bool demangle,
40                 string *img_name, string *rtn_name,
41                 string *file_name, int *line_no);
42 string PcToRtnNameAndFilePos(uintptr_t pc);
43 string PcToRtnName(uintptr_t pc, bool demangle);
44 string Demangle(const char *str);
45 
46 
47 //--------- FLAGS ---------------------------------- {{{1
48 struct 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 
141 extern FLAGS *G_flags;
142 
143 extern bool g_race_verifier_active;
144 
145 extern bool debug_expected_races;
146 extern bool debug_malloc;
147 extern bool debug_free;
148 extern bool debug_thread;
149 extern bool debug_rtn;
150 extern bool debug_wrap;
151 extern bool debug_ins;
152 extern bool debug_shadow_stack;
153 extern bool debug_race_verifier;
154 
155 // -------- CallStack ------------- {{{1
156 const size_t kMaxCallStackSize = 1 << 12;
157 
158 struct CallStackPod {
159   uintptr_t *end_;
160   uintptr_t pcs_[kMaxCallStackSize];
161 };
162 
163 struct CallStack: public CallStackPod {
164 
CallStackCallStack165   CallStack() { Clear(); }
166 
sizeCallStack167   size_t size() { return (size_t)(end_ - pcs_); }
pcsCallStack168   uintptr_t *pcs() { return pcs_; }
169 
emptyCallStack170   bool empty() { return end_ == pcs_; }
171 
backCallStack172   uintptr_t &back() {
173     DCHECK(!empty());
174     return *(end_ - 1);
175   }
176 
pop_backCallStack177   void pop_back() {
178     DCHECK(!empty());
179     end_--;
180   }
181 
push_backCallStack182   void push_back(uintptr_t pc) {
183     DCHECK(size() < kMaxCallStackSize);
184     *end_ = pc;
185     end_++;
186   }
187 
ClearCallStack188   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 
203 struct TSanThread;
204 void ThreadSanitizerInit();
205 void ThreadSanitizerFini();
206 // TODO(glider): this is a temporary solution to avoid deadlocks after fork().
207 #ifdef TS_LLVM
208 void ThreadSanitizerLockAcquire();
209 void ThreadSanitizerLockRelease();
210 #endif
211 void ThreadSanitizerHandleOneEvent(Event *event);
212 TSanThread *ThreadSanitizerGetThreadByTid(int32_t tid);
213 void ThreadSanitizerHandleTrace(int32_t tid, TraceInfo *trace_info,
214                                        uintptr_t *tleb);
215 void ThreadSanitizerHandleTrace(TSanThread *thr, TraceInfo *trace_info,
216                                        uintptr_t *tleb);
217 void ThreadSanitizerHandleOneMemoryAccess(TSanThread *thr, MopInfo mop,
218                                                  uintptr_t addr);
219 void ThreadSanitizerParseFlags(vector<string>* args);
220 bool ThreadSanitizerWantToInstrumentSblock(uintptr_t pc);
221 bool ThreadSanitizerWantToCreateSegmentsOnSblockEntry(uintptr_t pc);
222 bool ThreadSanitizerIgnoreAccessesBelowFunction(uintptr_t pc);
223 
224 typedef int (*ThreadSanitizerUnwindCallback)(uintptr_t* stack, int size, uintptr_t pc);
225 void 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  */
244 uint64_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 
254 enum IGNORE_BELOW_RTN {
255   IGNORE_BELOW_RTN_UNKNOWN,
256   IGNORE_BELOW_RTN_NO,
257   IGNORE_BELOW_RTN_YES
258 };
259 
260 void ThreadSanitizerHandleRtnCall(int32_t tid, uintptr_t call_pc,
261                                          uintptr_t target_pc,
262                                          IGNORE_BELOW_RTN ignore_below);
263 
264 void ThreadSanitizerHandleRtnExit(int32_t tid);
265 
266 void ThreadSanitizerPrintUsage();
267 extern "C" const char *ThreadSanitizerQuery(const char *query);
268 bool PhaseDebugIsOn(const char *phase_name);
269 
270 extern bool g_has_entered_main;
271 extern bool g_has_exited_main;
272 
273 // -------- Stats ------------------- {{{1
274 #include "ts_stats.h"
275 extern Stats *G_stats;
276 
277 // -------- Expected Race ---------------------- {{{1
278 // Information about expected races.
279 struct 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 
289 ExpectedRace* ThreadSanitizerFindExpectedRace(uintptr_t addr);
290 
291 // Tell ThreadSanitizer about the location of NaCl untrusted region.
292 void 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.
297 bool ThreadSanitizerIgnoreForNacl(uintptr_t addr);
298 
299 // end. {{{1
300 #endif  //  THREAD_SANITIZER_H_
301 
302 // vim:shiftwidth=2:softtabstop=2:expandtab
303