Home | History | Annotate | Download | only in tsan
      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 
    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 
    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