1 //===-- tsan_rtl_report.cpp -----------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is a part of ThreadSanitizer (TSan), a race detector.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "sanitizer_common/sanitizer_libc.h"
14 #include "sanitizer_common/sanitizer_placement_new.h"
15 #include "sanitizer_common/sanitizer_stackdepot.h"
16 #include "sanitizer_common/sanitizer_common.h"
17 #include "sanitizer_common/sanitizer_stacktrace.h"
18 #include "tsan_platform.h"
19 #include "tsan_rtl.h"
20 #include "tsan_suppressions.h"
21 #include "tsan_symbolize.h"
22 #include "tsan_report.h"
23 #include "tsan_sync.h"
24 #include "tsan_mman.h"
25 #include "tsan_flags.h"
26 #include "tsan_fd.h"
27 
28 namespace __tsan {
29 
30 using namespace __sanitizer;
31 
32 static ReportStack *SymbolizeStack(StackTrace trace);
33 
34 // Can be overriden by an application/test to intercept reports.
35 #ifdef TSAN_EXTERNAL_HOOKS
36 bool OnReport(const ReportDesc *rep, bool suppressed);
37 #else
38 SANITIZER_WEAK_CXX_DEFAULT_IMPL
39 bool OnReport(const ReportDesc *rep, bool suppressed) {
40   (void)rep;
41   return suppressed;
42 }
43 #endif
44 
45 SANITIZER_WEAK_DEFAULT_IMPL
46 void __tsan_on_report(const ReportDesc *rep) {
47   (void)rep;
48 }
49 
50 static void StackStripMain(SymbolizedStack *frames) {
51   SymbolizedStack *last_frame = nullptr;
52   SymbolizedStack *last_frame2 = nullptr;
53   for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
54     last_frame2 = last_frame;
55     last_frame = cur;
56   }
57 
58   if (last_frame2 == 0)
59     return;
60 #if !SANITIZER_GO
61   const char *last = last_frame->info.function;
62   const char *last2 = last_frame2->info.function;
63   // Strip frame above 'main'
64   if (last2 && 0 == internal_strcmp(last2, "main")) {
65     last_frame->ClearAll();
66     last_frame2->next = nullptr;
67   // Strip our internal thread start routine.
68   } else if (last && 0 == internal_strcmp(last, "__tsan_thread_start_func")) {
69     last_frame->ClearAll();
70     last_frame2->next = nullptr;
71     // Strip global ctors init, .preinit_array and main caller.
72   } else if (last && (0 == internal_strcmp(last, "__do_global_ctors_aux") ||
73                       0 == internal_strcmp(last, "__libc_csu_init") ||
74                       0 == internal_strcmp(last, "__libc_start_main"))) {
75     last_frame->ClearAll();
76     last_frame2->next = nullptr;
77   // If both are 0, then we probably just failed to symbolize.
78   } else if (last || last2) {
79     // Ensure that we recovered stack completely. Trimmed stack
80     // can actually happen if we do not instrument some code,
81     // so it's only a debug print. However we must try hard to not miss it
82     // due to our fault.
83     DPrintf("Bottom stack frame is missed\n");
84   }
85 #else
86   // The last frame always point into runtime (gosched0, goexit0, runtime.main).
87   last_frame->ClearAll();
88   last_frame2->next = nullptr;
89 #endif
90 }
91 
92 ReportStack *SymbolizeStackId(u32 stack_id) {
93   if (stack_id == 0)
94     return 0;
95   StackTrace stack = StackDepotGet(stack_id);
96   if (stack.trace == nullptr)
97     return nullptr;
98   return SymbolizeStack(stack);
99 }
100 
101 static ReportStack *SymbolizeStack(StackTrace trace) {
102   if (trace.size == 0)
103     return 0;
104   SymbolizedStack *top = nullptr;
105   for (uptr si = 0; si < trace.size; si++) {
106     const uptr pc = trace.trace[si];
107     uptr pc1 = pc;
108     // We obtain the return address, but we're interested in the previous
109     // instruction.
110     if ((pc & kExternalPCBit) == 0)
111       pc1 = StackTrace::GetPreviousInstructionPc(pc);
112     SymbolizedStack *ent = SymbolizeCode(pc1);
113     CHECK_NE(ent, 0);
114     SymbolizedStack *last = ent;
115     while (last->next) {
116       last->info.address = pc;  // restore original pc for report
117       last = last->next;
118     }
119     last->info.address = pc;  // restore original pc for report
120     last->next = top;
121     top = ent;
122   }
123   StackStripMain(top);
124 
125   auto *stack = New<ReportStack>();
126   stack->frames = top;
127   return stack;
128 }
129 
130 bool ShouldReport(ThreadState *thr, ReportType typ) {
131   // We set thr->suppress_reports in the fork context.
132   // Taking any locking in the fork context can lead to deadlocks.
133   // If any locks are already taken, it's too late to do this check.
134   CheckedMutex::CheckNoLocks();
135   // For the same reason check we didn't lock thread_registry yet.
136   if (SANITIZER_DEBUG)
137     ThreadRegistryLock l(&ctx->thread_registry);
138   if (!flags()->report_bugs || thr->suppress_reports)
139     return false;
140   switch (typ) {
141     case ReportTypeSignalUnsafe:
142       return flags()->report_signal_unsafe;
143     case ReportTypeThreadLeak:
144 #if !SANITIZER_GO
145       // It's impossible to join phantom threads
146       // in the child after fork.
147       if (ctx->after_multithreaded_fork)
148         return false;
149 #endif
150       return flags()->report_thread_leaks;
151     case ReportTypeMutexDestroyLocked:
152       return flags()->report_destroy_locked;
153     default:
154       return true;
155   }
156 }
157 
158 ScopedReportBase::ScopedReportBase(ReportType typ, uptr tag) {
159   ctx->thread_registry.CheckLocked();
160   rep_ = New<ReportDesc>();
161   rep_->typ = typ;
162   rep_->tag = tag;
163   ctx->report_mtx.Lock();
164 }
165 
166 ScopedReportBase::~ScopedReportBase() {
167   ctx->report_mtx.Unlock();
168   DestroyAndFree(rep_);
169 }
170 
171 void ScopedReportBase::AddStack(StackTrace stack, bool suppressable) {
172   ReportStack **rs = rep_->stacks.PushBack();
173   *rs = SymbolizeStack(stack);
174   (*rs)->suppressable = suppressable;
175 }
176 
177 void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s,
178                                        StackTrace stack, const MutexSet *mset) {
179   auto *mop = New<ReportMop>();
180   rep_->mops.PushBack(mop);
181   mop->tid = s.tid();
182   mop->addr = addr + s.addr0();
183   mop->size = s.size();
184   mop->write = s.IsWrite();
185   mop->atomic = s.IsAtomic();
186   mop->stack = SymbolizeStack(stack);
187   mop->external_tag = external_tag;
188   if (mop->stack)
189     mop->stack->suppressable = true;
190   for (uptr i = 0; i < mset->Size(); i++) {
191     MutexSet::Desc d = mset->Get(i);
192     u64 mid = this->AddMutex(d.id);
193     ReportMopMutex mtx = {mid, d.write};
194     mop->mset.PushBack(mtx);
195   }
196 }
197 
198 void ScopedReportBase::AddUniqueTid(Tid unique_tid) {
199   rep_->unique_tids.PushBack(unique_tid);
200 }
201 
202 void ScopedReportBase::AddThread(const ThreadContext *tctx, bool suppressable) {
203   for (uptr i = 0; i < rep_->threads.Size(); i++) {
204     if ((u32)rep_->threads[i]->id == tctx->tid)
205       return;
206   }
207   auto *rt = New<ReportThread>();
208   rep_->threads.PushBack(rt);
209   rt->id = tctx->tid;
210   rt->os_id = tctx->os_id;
211   rt->running = (tctx->status == ThreadStatusRunning);
212   rt->name = internal_strdup(tctx->name);
213   rt->parent_tid = tctx->parent_tid;
214   rt->thread_type = tctx->thread_type;
215   rt->stack = 0;
216   rt->stack = SymbolizeStackId(tctx->creation_stack_id);
217   if (rt->stack)
218     rt->stack->suppressable = suppressable;
219 }
220 
221 #if !SANITIZER_GO
222 static bool FindThreadByUidLockedCallback(ThreadContextBase *tctx, void *arg) {
223   int unique_id = *(int *)arg;
224   return tctx->unique_id == (u32)unique_id;
225 }
226 
227 static ThreadContext *FindThreadByUidLocked(Tid unique_id) {
228   ctx->thread_registry.CheckLocked();
229   return static_cast<ThreadContext *>(
230       ctx->thread_registry.FindThreadContextLocked(
231           FindThreadByUidLockedCallback, &unique_id));
232 }
233 
234 static ThreadContext *FindThreadByTidLocked(Tid tid) {
235   ctx->thread_registry.CheckLocked();
236   return static_cast<ThreadContext *>(
237       ctx->thread_registry.GetThreadLocked(tid));
238 }
239 
240 static bool IsInStackOrTls(ThreadContextBase *tctx_base, void *arg) {
241   uptr addr = (uptr)arg;
242   ThreadContext *tctx = static_cast<ThreadContext*>(tctx_base);
243   if (tctx->status != ThreadStatusRunning)
244     return false;
245   ThreadState *thr = tctx->thr;
246   CHECK(thr);
247   return ((addr >= thr->stk_addr && addr < thr->stk_addr + thr->stk_size) ||
248           (addr >= thr->tls_addr && addr < thr->tls_addr + thr->tls_size));
249 }
250 
251 ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack) {
252   ctx->thread_registry.CheckLocked();
253   ThreadContext *tctx =
254       static_cast<ThreadContext *>(ctx->thread_registry.FindThreadContextLocked(
255           IsInStackOrTls, (void *)addr));
256   if (!tctx)
257     return 0;
258   ThreadState *thr = tctx->thr;
259   CHECK(thr);
260   *is_stack = (addr >= thr->stk_addr && addr < thr->stk_addr + thr->stk_size);
261   return tctx;
262 }
263 #endif
264 
265 void ScopedReportBase::AddThread(Tid unique_tid, bool suppressable) {
266 #if !SANITIZER_GO
267   if (const ThreadContext *tctx = FindThreadByUidLocked(unique_tid))
268     AddThread(tctx, suppressable);
269 #endif
270 }
271 
272 void ScopedReportBase::AddMutex(const SyncVar *s) {
273   for (uptr i = 0; i < rep_->mutexes.Size(); i++) {
274     if (rep_->mutexes[i]->id == s->uid)
275       return;
276   }
277   auto *rm = New<ReportMutex>();
278   rep_->mutexes.PushBack(rm);
279   rm->id = s->uid;
280   rm->addr = s->addr;
281   rm->destroyed = false;
282   rm->stack = SymbolizeStackId(s->creation_stack_id);
283 }
284 
285 u64 ScopedReportBase::AddMutex(u64 id) {
286   u64 uid = 0;
287   u64 mid = id;
288   uptr addr = SyncVar::SplitId(id, &uid);
289   SyncVar *s = ctx->metamap.GetSyncIfExists(addr);
290   // Check that the mutex is still alive.
291   // Another mutex can be created at the same address,
292   // so check uid as well.
293   if (s && s->CheckId(uid)) {
294     Lock l(&s->mtx);
295     mid = s->uid;
296     AddMutex(s);
297   } else {
298     AddDeadMutex(id);
299   }
300   return mid;
301 }
302 
303 void ScopedReportBase::AddDeadMutex(u64 id) {
304   for (uptr i = 0; i < rep_->mutexes.Size(); i++) {
305     if (rep_->mutexes[i]->id == id)
306       return;
307   }
308   auto *rm = New<ReportMutex>();
309   rep_->mutexes.PushBack(rm);
310   rm->id = id;
311   rm->addr = 0;
312   rm->destroyed = true;
313   rm->stack = 0;
314 }
315 
316 void ScopedReportBase::AddLocation(uptr addr, uptr size) {
317   if (addr == 0)
318     return;
319 #if !SANITIZER_GO
320   int fd = -1;
321   Tid creat_tid = kInvalidTid;
322   StackID creat_stack = 0;
323   if (FdLocation(addr, &fd, &creat_tid, &creat_stack)) {
324     auto *loc = New<ReportLocation>();
325     loc->type = ReportLocationFD;
326     loc->fd = fd;
327     loc->tid = creat_tid;
328     loc->stack = SymbolizeStackId(creat_stack);
329     rep_->locs.PushBack(loc);
330     ThreadContext *tctx = FindThreadByUidLocked(creat_tid);
331     if (tctx)
332       AddThread(tctx);
333     return;
334   }
335   MBlock *b = 0;
336   uptr block_begin = 0;
337   Allocator *a = allocator();
338   if (a->PointerIsMine((void*)addr)) {
339     block_begin = (uptr)a->GetBlockBegin((void *)addr);
340     if (block_begin)
341       b = ctx->metamap.GetBlock(block_begin);
342   }
343   if (!b)
344     b = JavaHeapBlock(addr, &block_begin);
345   if (b != 0) {
346     ThreadContext *tctx = FindThreadByTidLocked(b->tid);
347     auto *loc = New<ReportLocation>();
348     loc->type = ReportLocationHeap;
349     loc->heap_chunk_start = (uptr)allocator()->GetBlockBegin((void *)addr);
350     loc->heap_chunk_size = b->siz;
351     loc->external_tag = b->tag;
352     loc->tid = tctx ? tctx->tid : b->tid;
353     loc->stack = SymbolizeStackId(b->stk);
354     rep_->locs.PushBack(loc);
355     if (tctx)
356       AddThread(tctx);
357     return;
358   }
359   bool is_stack = false;
360   if (ThreadContext *tctx = IsThreadStackOrTls(addr, &is_stack)) {
361     auto *loc = New<ReportLocation>();
362     loc->type = is_stack ? ReportLocationStack : ReportLocationTLS;
363     loc->tid = tctx->tid;
364     rep_->locs.PushBack(loc);
365     AddThread(tctx);
366   }
367 #endif
368   if (ReportLocation *loc = SymbolizeData(addr)) {
369     loc->suppressable = true;
370     rep_->locs.PushBack(loc);
371     return;
372   }
373 }
374 
375 #if !SANITIZER_GO
376 void ScopedReportBase::AddSleep(StackID stack_id) {
377   rep_->sleep = SymbolizeStackId(stack_id);
378 }
379 #endif
380 
381 void ScopedReportBase::SetCount(int count) { rep_->count = count; }
382 
383 const ReportDesc *ScopedReportBase::GetReport() const { return rep_; }
384 
385 ScopedReport::ScopedReport(ReportType typ, uptr tag)
386     : ScopedReportBase(typ, tag) {}
387 
388 ScopedReport::~ScopedReport() {}
389 
390 void RestoreStack(Tid tid, const u64 epoch, VarSizeStackTrace *stk,
391                   MutexSet *mset, uptr *tag) {
392   // This function restores stack trace and mutex set for the thread/epoch.
393   // It does so by getting stack trace and mutex set at the beginning of
394   // trace part, and then replaying the trace till the given epoch.
395   Trace* trace = ThreadTrace(tid);
396   ReadLock l(&trace->mtx);
397   const int partidx = (epoch / kTracePartSize) % TraceParts();
398   TraceHeader* hdr = &trace->headers[partidx];
399   if (epoch < hdr->epoch0 || epoch >= hdr->epoch0 + kTracePartSize)
400     return;
401   CHECK_EQ(RoundDown(epoch, kTracePartSize), hdr->epoch0);
402   const u64 epoch0 = RoundDown(epoch, TraceSize());
403   const u64 eend = epoch % TraceSize();
404   const u64 ebegin = RoundDown(eend, kTracePartSize);
405   DPrintf("#%d: RestoreStack epoch=%zu ebegin=%zu eend=%zu partidx=%d\n",
406           tid, (uptr)epoch, (uptr)ebegin, (uptr)eend, partidx);
407   Vector<uptr> stack;
408   stack.Resize(hdr->stack0.size + 64);
409   for (uptr i = 0; i < hdr->stack0.size; i++) {
410     stack[i] = hdr->stack0.trace[i];
411     DPrintf2("  #%02zu: pc=%zx\n", i, stack[i]);
412   }
413   if (mset)
414     *mset = hdr->mset0;
415   uptr pos = hdr->stack0.size;
416   Event *events = (Event*)GetThreadTrace(tid);
417   for (uptr i = ebegin; i <= eend; i++) {
418     Event ev = events[i];
419     EventType typ = (EventType)(ev >> kEventPCBits);
420     uptr pc = (uptr)(ev & ((1ull << kEventPCBits) - 1));
421     DPrintf2("  %zu typ=%d pc=%zx\n", i, typ, pc);
422     if (typ == EventTypeMop) {
423       stack[pos] = pc;
424     } else if (typ == EventTypeFuncEnter) {
425       if (stack.Size() < pos + 2)
426         stack.Resize(pos + 2);
427       stack[pos++] = pc;
428     } else if (typ == EventTypeFuncExit) {
429       if (pos > 0)
430         pos--;
431     }
432     if (mset) {
433       if (typ == EventTypeLock) {
434         mset->Add(pc, true, epoch0 + i);
435       } else if (typ == EventTypeUnlock) {
436         mset->Del(pc, true);
437       } else if (typ == EventTypeRLock) {
438         mset->Add(pc, false, epoch0 + i);
439       } else if (typ == EventTypeRUnlock) {
440         mset->Del(pc, false);
441       }
442     }
443     for (uptr j = 0; j <= pos; j++)
444       DPrintf2("      #%zu: %zx\n", j, stack[j]);
445   }
446   if (pos == 0 && stack[0] == 0)
447     return;
448   pos++;
449   stk->Init(&stack[0], pos);
450   ExtractTagFromStack(stk, tag);
451 }
452 
453 namespace v3 {
454 
455 // Replays the trace up to last_pos position in the last part
456 // or up to the provided epoch/sid (whichever is earlier)
457 // and calls the provided function f for each event.
458 template <typename Func>
459 void TraceReplay(Trace *trace, TracePart *last, Event *last_pos, Sid sid,
460                  Epoch epoch, Func f) {
461   TracePart *part = trace->parts.Front();
462   Sid ev_sid = kFreeSid;
463   Epoch ev_epoch = kEpochOver;
464   for (;;) {
465     DCHECK_EQ(part->trace, trace);
466     // Note: an event can't start in the last element.
467     // Since an event can take up to 2 elements,
468     // we ensure we have at least 2 before adding an event.
469     Event *end = &part->events[TracePart::kSize - 1];
470     if (part == last)
471       end = last_pos;
472     for (Event *evp = &part->events[0]; evp < end; evp++) {
473       Event *evp0 = evp;
474       if (!evp->is_access && !evp->is_func) {
475         switch (evp->type) {
476           case EventType::kTime: {
477             auto *ev = reinterpret_cast<EventTime *>(evp);
478             ev_sid = static_cast<Sid>(ev->sid);
479             ev_epoch = static_cast<Epoch>(ev->epoch);
480             if (ev_sid == sid && ev_epoch > epoch)
481               return;
482             break;
483           }
484           case EventType::kAccessExt:
485             FALLTHROUGH;
486           case EventType::kAccessRange:
487             FALLTHROUGH;
488           case EventType::kLock:
489             FALLTHROUGH;
490           case EventType::kRLock:
491             // These take 2 Event elements.
492             evp++;
493             break;
494           case EventType::kUnlock:
495             // This takes 1 Event element.
496             break;
497         }
498       }
499       CHECK_NE(ev_sid, kFreeSid);
500       CHECK_NE(ev_epoch, kEpochOver);
501       f(ev_sid, ev_epoch, evp0);
502     }
503     if (part == last)
504       return;
505     part = trace->parts.Next(part);
506     CHECK(part);
507   }
508   CHECK(0);
509 }
510 
511 static void RestoreStackMatch(VarSizeStackTrace *pstk, MutexSet *pmset,
512                               Vector<uptr> *stack, MutexSet *mset, uptr pc,
513                               bool *found) {
514   DPrintf2("    MATCHED\n");
515   *pmset = *mset;
516   stack->PushBack(pc);
517   pstk->Init(&(*stack)[0], stack->Size());
518   stack->PopBack();
519   *found = true;
520 }
521 
522 // Checks if addr1|size1 is fully contained in addr2|size2.
523 // We check for fully contained instread of just overlapping
524 // because a memory access is always traced once, but can be
525 // split into multiple accesses in the shadow.
526 static constexpr bool IsWithinAccess(uptr addr1, uptr size1, uptr addr2,
527                                      uptr size2) {
528   return addr1 >= addr2 && addr1 + size1 <= addr2 + size2;
529 }
530 
531 // Replays the trace of thread tid up to the target event identified
532 // by sid/epoch/addr/size/typ and restores and returns stack, mutex set
533 // and tag for that event. If there are multiple such events, it returns
534 // the last one. Returns false if the event is not present in the trace.
535 bool RestoreStack(Tid tid, EventType type, Sid sid, Epoch epoch, uptr addr,
536                   uptr size, AccessType typ, VarSizeStackTrace *pstk,
537                   MutexSet *pmset, uptr *ptag) {
538   // This function restores stack trace and mutex set for the thread/epoch.
539   // It does so by getting stack trace and mutex set at the beginning of
540   // trace part, and then replaying the trace till the given epoch.
541   DPrintf2("RestoreStack: tid=%u sid=%u@%u addr=0x%zx/%zu typ=%x\n", tid,
542            static_cast<int>(sid), static_cast<int>(epoch), addr, size,
543            static_cast<int>(typ));
544   ctx->slot_mtx.CheckLocked();  // needed to prevent trace part recycling
545   ctx->thread_registry.CheckLocked();
546   ThreadContext *tctx =
547       static_cast<ThreadContext *>(ctx->thread_registry.GetThreadLocked(tid));
548   Trace *trace = &tctx->trace;
549   // Snapshot first/last parts and the current position in the last part.
550   TracePart *first_part;
551   TracePart *last_part;
552   Event *last_pos;
553   {
554     Lock lock(&trace->mtx);
555     first_part = trace->parts.Front();
556     if (!first_part)
557       return false;
558     last_part = trace->parts.Back();
559     last_pos = trace->final_pos;
560     if (tctx->thr)
561       last_pos = (Event *)atomic_load_relaxed(&tctx->thr->trace_pos);
562   }
563   // Too large for stack.
564   alignas(MutexSet) static char mset_storage[sizeof(MutexSet)];
565   MutexSet &mset = *new (mset_storage) MutexSet();
566   Vector<uptr> stack;
567   uptr prev_pc = 0;
568   bool found = false;
569   bool is_read = typ & kAccessRead;
570   bool is_atomic = typ & kAccessAtomic;
571   bool is_free = typ & kAccessFree;
572   TraceReplay(
573       trace, last_part, last_pos, sid, epoch,
574       [&](Sid ev_sid, Epoch ev_epoch, Event *evp) {
575         bool match = ev_sid == sid && ev_epoch == epoch;
576         if (evp->is_access) {
577           if (evp->is_func == 0 && evp->type == EventType::kAccessExt &&
578               evp->_ == 0)  // NopEvent
579             return;
580           auto *ev = reinterpret_cast<EventAccess *>(evp);
581           uptr ev_addr = RestoreAddr(ev->addr);
582           uptr ev_size = 1 << ev->size_log;
583           uptr ev_pc =
584               prev_pc + ev->pc_delta - (1 << (EventAccess::kPCBits - 1));
585           prev_pc = ev_pc;
586           DPrintf2("  Access: pc=0x%zx addr=0x%zx/%zu type=%u/%u\n", ev_pc,
587                    ev_addr, ev_size, ev->is_read, ev->is_atomic);
588           if (match && type == EventType::kAccessExt &&
589               IsWithinAccess(addr, size, ev_addr, ev_size) &&
590               is_read == ev->is_read && is_atomic == ev->is_atomic && !is_free)
591             RestoreStackMatch(pstk, pmset, &stack, &mset, ev_pc, &found);
592           return;
593         }
594         if (evp->is_func) {
595           auto *ev = reinterpret_cast<EventFunc *>(evp);
596           if (ev->pc) {
597             DPrintf2("  FuncEnter: pc=0x%llx\n", ev->pc);
598             stack.PushBack(ev->pc);
599           } else {
600             DPrintf2("  FuncExit\n");
601             CHECK(stack.Size());
602             stack.PopBack();
603           }
604           return;
605         }
606         switch (evp->type) {
607           case EventType::kAccessExt: {
608             auto *ev = reinterpret_cast<EventAccessExt *>(evp);
609             uptr ev_addr = RestoreAddr(ev->addr);
610             uptr ev_size = 1 << ev->size_log;
611             prev_pc = ev->pc;
612             DPrintf2("  AccessExt: pc=0x%llx addr=0x%zx/%zu type=%u/%u\n",
613                      ev->pc, ev_addr, ev_size, ev->is_read, ev->is_atomic);
614             if (match && type == EventType::kAccessExt &&
615                 IsWithinAccess(addr, size, ev_addr, ev_size) &&
616                 is_read == ev->is_read && is_atomic == ev->is_atomic &&
617                 !is_free)
618               RestoreStackMatch(pstk, pmset, &stack, &mset, ev->pc, &found);
619             break;
620           }
621           case EventType::kAccessRange: {
622             auto *ev = reinterpret_cast<EventAccessRange *>(evp);
623             uptr ev_addr = RestoreAddr(ev->addr);
624             uptr ev_size =
625                 (ev->size_hi << EventAccessRange::kSizeLoBits) + ev->size_lo;
626             uptr ev_pc = RestoreAddr(ev->pc);
627             prev_pc = ev_pc;
628             DPrintf2("  Range: pc=0x%zx addr=0x%zx/%zu type=%u/%u\n", ev_pc,
629                      ev_addr, ev_size, ev->is_read, ev->is_free);
630             if (match && type == EventType::kAccessExt &&
631                 IsWithinAccess(addr, size, ev_addr, ev_size) &&
632                 is_read == ev->is_read && !is_atomic && is_free == ev->is_free)
633               RestoreStackMatch(pstk, pmset, &stack, &mset, ev_pc, &found);
634             break;
635           }
636           case EventType::kLock:
637             FALLTHROUGH;
638           case EventType::kRLock: {
639             auto *ev = reinterpret_cast<EventLock *>(evp);
640             bool is_write = ev->type == EventType::kLock;
641             uptr ev_addr = RestoreAddr(ev->addr);
642             uptr ev_pc = RestoreAddr(ev->pc);
643             StackID stack_id =
644                 (ev->stack_hi << EventLock::kStackIDLoBits) + ev->stack_lo;
645             DPrintf2("  Lock: pc=0x%zx addr=0x%zx stack=%u write=%d\n", ev_pc,
646                      ev_addr, stack_id, is_write);
647             mset.AddAddr(ev_addr, stack_id, is_write);
648             // Events with ev_pc == 0 are written to the beginning of trace
649             // part as initial mutex set (are not real).
650             if (match && type == EventType::kLock && addr == ev_addr && ev_pc)
651               RestoreStackMatch(pstk, pmset, &stack, &mset, ev_pc, &found);
652             break;
653           }
654           case EventType::kUnlock: {
655             auto *ev = reinterpret_cast<EventUnlock *>(evp);
656             uptr ev_addr = RestoreAddr(ev->addr);
657             DPrintf2("  Unlock: addr=0x%zx\n", ev_addr);
658             mset.DelAddr(ev_addr);
659             break;
660           }
661           case EventType::kTime:
662             // TraceReplay already extracted sid/epoch from it,
663             // nothing else to do here.
664             break;
665         }
666       });
667   ExtractTagFromStack(pstk, ptag);
668   return found;
669 }
670 
671 }  // namespace v3
672 
673 static bool FindRacyStacks(const RacyStacks &hash) {
674   for (uptr i = 0; i < ctx->racy_stacks.Size(); i++) {
675     if (hash == ctx->racy_stacks[i]) {
676       VPrintf(2, "ThreadSanitizer: suppressing report as doubled (stack)\n");
677       return true;
678     }
679   }
680   return false;
681 }
682 
683 static bool HandleRacyStacks(ThreadState *thr, VarSizeStackTrace traces[2]) {
684   if (!flags()->suppress_equal_stacks)
685     return false;
686   RacyStacks hash;
687   hash.hash[0] = md5_hash(traces[0].trace, traces[0].size * sizeof(uptr));
688   hash.hash[1] = md5_hash(traces[1].trace, traces[1].size * sizeof(uptr));
689   {
690     ReadLock lock(&ctx->racy_mtx);
691     if (FindRacyStacks(hash))
692       return true;
693   }
694   Lock lock(&ctx->racy_mtx);
695   if (FindRacyStacks(hash))
696     return true;
697   ctx->racy_stacks.PushBack(hash);
698   return false;
699 }
700 
701 static bool FindRacyAddress(const RacyAddress &ra0) {
702   for (uptr i = 0; i < ctx->racy_addresses.Size(); i++) {
703     RacyAddress ra2 = ctx->racy_addresses[i];
704     uptr maxbeg = max(ra0.addr_min, ra2.addr_min);
705     uptr minend = min(ra0.addr_max, ra2.addr_max);
706     if (maxbeg < minend) {
707       VPrintf(2, "ThreadSanitizer: suppressing report as doubled (addr)\n");
708       return true;
709     }
710   }
711   return false;
712 }
713 
714 static bool HandleRacyAddress(ThreadState *thr, uptr addr_min, uptr addr_max) {
715   if (!flags()->suppress_equal_addresses)
716     return false;
717   RacyAddress ra0 = {addr_min, addr_max};
718   {
719     ReadLock lock(&ctx->racy_mtx);
720     if (FindRacyAddress(ra0))
721       return true;
722   }
723   Lock lock(&ctx->racy_mtx);
724   if (FindRacyAddress(ra0))
725     return true;
726   ctx->racy_addresses.PushBack(ra0);
727   return false;
728 }
729 
730 bool OutputReport(ThreadState *thr, const ScopedReport &srep) {
731   // These should have been checked in ShouldReport.
732   // It's too late to check them here, we have already taken locks.
733   CHECK(flags()->report_bugs);
734   CHECK(!thr->suppress_reports);
735   atomic_store_relaxed(&ctx->last_symbolize_time_ns, NanoTime());
736   const ReportDesc *rep = srep.GetReport();
737   CHECK_EQ(thr->current_report, nullptr);
738   thr->current_report = rep;
739   Suppression *supp = 0;
740   uptr pc_or_addr = 0;
741   for (uptr i = 0; pc_or_addr == 0 && i < rep->mops.Size(); i++)
742     pc_or_addr = IsSuppressed(rep->typ, rep->mops[i]->stack, &supp);
743   for (uptr i = 0; pc_or_addr == 0 && i < rep->stacks.Size(); i++)
744     pc_or_addr = IsSuppressed(rep->typ, rep->stacks[i], &supp);
745   for (uptr i = 0; pc_or_addr == 0 && i < rep->threads.Size(); i++)
746     pc_or_addr = IsSuppressed(rep->typ, rep->threads[i]->stack, &supp);
747   for (uptr i = 0; pc_or_addr == 0 && i < rep->locs.Size(); i++)
748     pc_or_addr = IsSuppressed(rep->typ, rep->locs[i], &supp);
749   if (pc_or_addr != 0) {
750     Lock lock(&ctx->fired_suppressions_mtx);
751     FiredSuppression s = {srep.GetReport()->typ, pc_or_addr, supp};
752     ctx->fired_suppressions.push_back(s);
753   }
754   {
755     bool old_is_freeing = thr->is_freeing;
756     thr->is_freeing = false;
757     bool suppressed = OnReport(rep, pc_or_addr != 0);
758     thr->is_freeing = old_is_freeing;
759     if (suppressed) {
760       thr->current_report = nullptr;
761       return false;
762     }
763   }
764   PrintReport(rep);
765   __tsan_on_report(rep);
766   ctx->nreported++;
767   if (flags()->halt_on_error)
768     Die();
769   thr->current_report = nullptr;
770   return true;
771 }
772 
773 bool IsFiredSuppression(Context *ctx, ReportType type, StackTrace trace) {
774   ReadLock lock(&ctx->fired_suppressions_mtx);
775   for (uptr k = 0; k < ctx->fired_suppressions.size(); k++) {
776     if (ctx->fired_suppressions[k].type != type)
777       continue;
778     for (uptr j = 0; j < trace.size; j++) {
779       FiredSuppression *s = &ctx->fired_suppressions[k];
780       if (trace.trace[j] == s->pc_or_addr) {
781         if (s->supp)
782           atomic_fetch_add(&s->supp->hit_count, 1, memory_order_relaxed);
783         return true;
784       }
785     }
786   }
787   return false;
788 }
789 
790 static bool IsFiredSuppression(Context *ctx, ReportType type, uptr addr) {
791   ReadLock lock(&ctx->fired_suppressions_mtx);
792   for (uptr k = 0; k < ctx->fired_suppressions.size(); k++) {
793     if (ctx->fired_suppressions[k].type != type)
794       continue;
795     FiredSuppression *s = &ctx->fired_suppressions[k];
796     if (addr == s->pc_or_addr) {
797       if (s->supp)
798         atomic_fetch_add(&s->supp->hit_count, 1, memory_order_relaxed);
799       return true;
800     }
801   }
802   return false;
803 }
804 
805 static bool RaceBetweenAtomicAndFree(ThreadState *thr) {
806   Shadow s0(thr->racy_state[0]);
807   Shadow s1(thr->racy_state[1]);
808   CHECK(!(s0.IsAtomic() && s1.IsAtomic()));
809   if (!s0.IsAtomic() && !s1.IsAtomic())
810     return true;
811   if (s0.IsAtomic() && s1.IsFreed())
812     return true;
813   if (s1.IsAtomic() && thr->is_freeing)
814     return true;
815   return false;
816 }
817 
818 void ReportRace(ThreadState *thr) {
819   CheckedMutex::CheckNoLocks();
820 
821   // Symbolizer makes lots of intercepted calls. If we try to process them,
822   // at best it will cause deadlocks on internal mutexes.
823   ScopedIgnoreInterceptors ignore;
824 
825   if (!ShouldReport(thr, ReportTypeRace))
826     return;
827   if (!flags()->report_atomic_races && !RaceBetweenAtomicAndFree(thr))
828     return;
829 
830   bool freed = false;
831   {
832     Shadow s(thr->racy_state[1]);
833     freed = s.GetFreedAndReset();
834     thr->racy_state[1] = s.raw();
835   }
836 
837   uptr addr = ShadowToMem(thr->racy_shadow_addr);
838   uptr addr_min = 0;
839   uptr addr_max = 0;
840   {
841     uptr a0 = addr + Shadow(thr->racy_state[0]).addr0();
842     uptr a1 = addr + Shadow(thr->racy_state[1]).addr0();
843     uptr e0 = a0 + Shadow(thr->racy_state[0]).size();
844     uptr e1 = a1 + Shadow(thr->racy_state[1]).size();
845     addr_min = min(a0, a1);
846     addr_max = max(e0, e1);
847     if (IsExpectedReport(addr_min, addr_max - addr_min))
848       return;
849   }
850   if (HandleRacyAddress(thr, addr_min, addr_max))
851     return;
852 
853   ReportType typ = ReportTypeRace;
854   if (thr->is_vptr_access && freed)
855     typ = ReportTypeVptrUseAfterFree;
856   else if (thr->is_vptr_access)
857     typ = ReportTypeVptrRace;
858   else if (freed)
859     typ = ReportTypeUseAfterFree;
860 
861   if (IsFiredSuppression(ctx, typ, addr))
862     return;
863 
864   const uptr kMop = 2;
865   VarSizeStackTrace traces[kMop];
866   uptr tags[kMop] = {kExternalTagNone};
867   uptr toppc = TraceTopPC(thr);
868   if (toppc >> kEventPCBits) {
869     // This is a work-around for a known issue.
870     // The scenario where this happens is rather elaborate and requires
871     // an instrumented __sanitizer_report_error_summary callback and
872     // a __tsan_symbolize_external callback and a race during a range memory
873     // access larger than 8 bytes. MemoryAccessRange adds the current PC to
874     // the trace and starts processing memory accesses. A first memory access
875     // triggers a race, we report it and call the instrumented
876     // __sanitizer_report_error_summary, which adds more stuff to the trace
877     // since it is intrumented. Then a second memory access in MemoryAccessRange
878     // also triggers a race and we get here and call TraceTopPC to get the
879     // current PC, however now it contains some unrelated events from the
880     // callback. Most likely, TraceTopPC will now return a EventTypeFuncExit
881     // event. Later we subtract -1 from it (in GetPreviousInstructionPc)
882     // and the resulting PC has kExternalPCBit set, so we pass it to
883     // __tsan_symbolize_external_ex. __tsan_symbolize_external_ex is within its
884     // rights to crash since the PC is completely bogus.
885     // test/tsan/double_race.cpp contains a test case for this.
886     toppc = 0;
887   }
888   ObtainCurrentStack(thr, toppc, &traces[0], &tags[0]);
889   if (IsFiredSuppression(ctx, typ, traces[0]))
890     return;
891 
892   // MutexSet is too large to live on stack.
893   Vector<u64> mset_buffer;
894   mset_buffer.Resize(sizeof(MutexSet) / sizeof(u64) + 1);
895   MutexSet *mset2 = new(&mset_buffer[0]) MutexSet();
896 
897   Shadow s2(thr->racy_state[1]);
898   RestoreStack(s2.tid(), s2.epoch(), &traces[1], mset2, &tags[1]);
899   if (IsFiredSuppression(ctx, typ, traces[1]))
900     return;
901 
902   if (HandleRacyStacks(thr, traces))
903     return;
904 
905   // If any of the accesses has a tag, treat this as an "external" race.
906   uptr tag = kExternalTagNone;
907   for (uptr i = 0; i < kMop; i++) {
908     if (tags[i] != kExternalTagNone) {
909       typ = ReportTypeExternalRace;
910       tag = tags[i];
911       break;
912     }
913   }
914 
915   ThreadRegistryLock l0(&ctx->thread_registry);
916   ScopedReport rep(typ, tag);
917   for (uptr i = 0; i < kMop; i++) {
918     Shadow s(thr->racy_state[i]);
919     rep.AddMemoryAccess(addr, tags[i], s, traces[i],
920                         i == 0 ? &thr->mset : mset2);
921   }
922 
923   for (uptr i = 0; i < kMop; i++) {
924     FastState s(thr->racy_state[i]);
925     ThreadContext *tctx = static_cast<ThreadContext *>(
926         ctx->thread_registry.GetThreadLocked(s.tid()));
927     if (s.epoch() < tctx->epoch0 || s.epoch() > tctx->epoch1)
928       continue;
929     rep.AddThread(tctx);
930   }
931 
932   rep.AddLocation(addr_min, addr_max - addr_min);
933 
934 #if !SANITIZER_GO
935   {
936     Shadow s(thr->racy_state[1]);
937     if (s.epoch() <= thr->last_sleep_clock.get(s.tid()))
938       rep.AddSleep(thr->last_sleep_stack_id);
939   }
940 #endif
941 
942   OutputReport(thr, rep);
943 }
944 
945 void PrintCurrentStack(ThreadState *thr, uptr pc) {
946   VarSizeStackTrace trace;
947   ObtainCurrentStack(thr, pc, &trace);
948   PrintStack(SymbolizeStack(trace));
949 }
950 
951 // Always inlining PrintCurrentStackSlow, because LocatePcInTrace assumes
952 // __sanitizer_print_stack_trace exists in the actual unwinded stack, but
953 // tail-call to PrintCurrentStackSlow breaks this assumption because
954 // __sanitizer_print_stack_trace disappears after tail-call.
955 // However, this solution is not reliable enough, please see dvyukov's comment
956 // http://reviews.llvm.org/D19148#406208
957 // Also see PR27280 comment 2 and 3 for breaking examples and analysis.
958 ALWAYS_INLINE USED void PrintCurrentStackSlow(uptr pc) {
959 #if !SANITIZER_GO
960   uptr bp = GET_CURRENT_FRAME();
961   auto *ptrace = New<BufferedStackTrace>();
962   ptrace->Unwind(pc, bp, nullptr, false);
963 
964   for (uptr i = 0; i < ptrace->size / 2; i++) {
965     uptr tmp = ptrace->trace_buffer[i];
966     ptrace->trace_buffer[i] = ptrace->trace_buffer[ptrace->size - i - 1];
967     ptrace->trace_buffer[ptrace->size - i - 1] = tmp;
968   }
969   PrintStack(SymbolizeStack(*ptrace));
970 #endif
971 }
972 
973 }  // namespace __tsan
974 
975 using namespace __tsan;
976 
977 extern "C" {
978 SANITIZER_INTERFACE_ATTRIBUTE
979 void __sanitizer_print_stack_trace() {
980   PrintCurrentStackSlow(StackTrace::GetCurrentPc());
981 }
982 }  // extern "C"
983