comparison libsanitizer/tsan/tsan_rtl.h @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 04ced10e8804
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 //===-- tsan_rtl.h ----------------------------------------------*- C++ -*-===// 1 //===-- tsan_rtl.h ----------------------------------------------*- C++ -*-===//
2 // 2 //
3 // This file is distributed under the University of Illinois Open Source 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // License. See LICENSE.TXT for details. 4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 // 6 //
6 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
7 // 8 //
8 // This file is a part of ThreadSanitizer (TSan), a race detector. 9 // This file is a part of ThreadSanitizer (TSan), a race detector.
9 // 10 //
30 #include "sanitizer_common/sanitizer_common.h" 31 #include "sanitizer_common/sanitizer_common.h"
31 #include "sanitizer_common/sanitizer_deadlock_detector_interface.h" 32 #include "sanitizer_common/sanitizer_deadlock_detector_interface.h"
32 #include "sanitizer_common/sanitizer_libignore.h" 33 #include "sanitizer_common/sanitizer_libignore.h"
33 #include "sanitizer_common/sanitizer_suppressions.h" 34 #include "sanitizer_common/sanitizer_suppressions.h"
34 #include "sanitizer_common/sanitizer_thread_registry.h" 35 #include "sanitizer_common/sanitizer_thread_registry.h"
36 #include "sanitizer_common/sanitizer_vector.h"
35 #include "tsan_clock.h" 37 #include "tsan_clock.h"
36 #include "tsan_defs.h" 38 #include "tsan_defs.h"
37 #include "tsan_flags.h" 39 #include "tsan_flags.h"
40 #include "tsan_mman.h"
38 #include "tsan_sync.h" 41 #include "tsan_sync.h"
39 #include "tsan_trace.h" 42 #include "tsan_trace.h"
40 #include "tsan_vector.h"
41 #include "tsan_report.h" 43 #include "tsan_report.h"
42 #include "tsan_platform.h" 44 #include "tsan_platform.h"
43 #include "tsan_mutexset.h" 45 #include "tsan_mutexset.h"
44 #include "tsan_ignoreset.h" 46 #include "tsan_ignoreset.h"
45 #include "tsan_stack_trace.h" 47 #include "tsan_stack_trace.h"
51 namespace __tsan { 53 namespace __tsan {
52 54
53 #if !SANITIZER_GO 55 #if !SANITIZER_GO
54 struct MapUnmapCallback; 56 struct MapUnmapCallback;
55 #if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) 57 #if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__)
56 static const uptr kAllocatorRegionSizeLog = 20; 58
57 static const uptr kAllocatorNumRegions =
58 SANITIZER_MMAP_RANGE_SIZE >> kAllocatorRegionSizeLog;
59 typedef TwoLevelByteMap<(kAllocatorNumRegions >> 12), 1 << 12,
60 MapUnmapCallback> ByteMap;
61 struct AP32 { 59 struct AP32 {
62 static const uptr kSpaceBeg = 0; 60 static const uptr kSpaceBeg = 0;
63 static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; 61 static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
64 static const uptr kMetadataSize = 0; 62 static const uptr kMetadataSize = 0;
65 typedef __sanitizer::CompactSizeClassMap SizeClassMap; 63 typedef __sanitizer::CompactSizeClassMap SizeClassMap;
66 static const uptr kRegionSizeLog = kAllocatorRegionSizeLog; 64 static const uptr kRegionSizeLog = 20;
67 typedef __tsan::ByteMap ByteMap; 65 using AddressSpaceView = LocalAddressSpaceView;
68 typedef __tsan::MapUnmapCallback MapUnmapCallback; 66 typedef __tsan::MapUnmapCallback MapUnmapCallback;
69 static const uptr kFlags = 0; 67 static const uptr kFlags = 0;
70 }; 68 };
71 typedef SizeClassAllocator32<AP32> PrimaryAllocator; 69 typedef SizeClassAllocator32<AP32> PrimaryAllocator;
72 #else 70 #else
75 static const uptr kSpaceSize = Mapping::kHeapMemEnd - Mapping::kHeapMemBeg; 73 static const uptr kSpaceSize = Mapping::kHeapMemEnd - Mapping::kHeapMemBeg;
76 static const uptr kMetadataSize = 0; 74 static const uptr kMetadataSize = 0;
77 typedef DefaultSizeClassMap SizeClassMap; 75 typedef DefaultSizeClassMap SizeClassMap;
78 typedef __tsan::MapUnmapCallback MapUnmapCallback; 76 typedef __tsan::MapUnmapCallback MapUnmapCallback;
79 static const uptr kFlags = 0; 77 static const uptr kFlags = 0;
78 using AddressSpaceView = LocalAddressSpaceView;
80 }; 79 };
81 typedef SizeClassAllocator64<AP64> PrimaryAllocator; 80 typedef SizeClassAllocator64<AP64> PrimaryAllocator;
82 #endif 81 #endif
83 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache; 82 typedef CombinedAllocator<PrimaryAllocator> Allocator;
84 typedef LargeMmapAllocator<MapUnmapCallback> SecondaryAllocator; 83 typedef Allocator::AllocatorCache AllocatorCache;
85 typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
86 SecondaryAllocator> Allocator;
87 Allocator *allocator(); 84 Allocator *allocator();
88 #endif 85 #endif
89 86
90 void TsanCheckFailed(const char *file, int line, const char *cond, 87 void TsanCheckFailed(const char *file, int line, const char *cond,
91 u64 v1, u64 v2); 88 u64 v1, u64 v2);
239 236
240 static ALWAYS_INLINE bool TwoRangesIntersect(Shadow s1, Shadow s2, 237 static ALWAYS_INLINE bool TwoRangesIntersect(Shadow s1, Shadow s2,
241 unsigned kS2AccessSize) { 238 unsigned kS2AccessSize) {
242 bool res = false; 239 bool res = false;
243 u64 diff = s1.addr0() - s2.addr0(); 240 u64 diff = s1.addr0() - s2.addr0();
244 if ((s64)diff < 0) { // s1.addr0 < s2.addr0 // NOLINT 241 if ((s64)diff < 0) { // s1.addr0 < s2.addr0
245 // if (s1.addr0() + size1) > s2.addr0()) return true; 242 // if (s1.addr0() + size1) > s2.addr0()) return true;
246 if (s1.size() > -diff) 243 if (s1.size() > -diff)
247 res = true; 244 res = true;
248 } else { 245 } else {
249 // if (s2.addr0() + kS2AccessSize > s1.addr0()) return true; 246 // if (s2.addr0() + kS2AccessSize > s1.addr0()) return true;
326 323
327 struct ThreadSignalContext; 324 struct ThreadSignalContext;
328 325
329 struct JmpBuf { 326 struct JmpBuf {
330 uptr sp; 327 uptr sp;
331 uptr mangled_sp;
332 int int_signal_send; 328 int int_signal_send;
333 bool in_blocking_func; 329 bool in_blocking_func;
334 uptr in_signal_handler; 330 uptr in_signal_handler;
335 uptr *shadow_stack_pos; 331 uptr *shadow_stack_pos;
336 }; 332 };
378 // QUESTION: can we can squeeze this into ThreadState::Fast? 374 // QUESTION: can we can squeeze this into ThreadState::Fast?
379 // E.g. ThreadState::Fast is a 44-bit, 32 are taken by synch_epoch and 12 are 375 // E.g. ThreadState::Fast is a 44-bit, 32 are taken by synch_epoch and 12 are
380 // taken by epoch between synchs. 376 // taken by epoch between synchs.
381 // This way we can save one load from tls. 377 // This way we can save one load from tls.
382 u64 fast_synch_epoch; 378 u64 fast_synch_epoch;
379 // Technically `current` should be a separate THREADLOCAL variable;
380 // but it is placed here in order to share cache line with previous fields.
381 ThreadState* current;
383 // This is a slow path flag. On fast path, fast_state.GetIgnoreBit() is read. 382 // This is a slow path flag. On fast path, fast_state.GetIgnoreBit() is read.
384 // We do not distinguish beteween ignoring reads and writes 383 // We do not distinguish beteween ignoring reads and writes
385 // for better performance. 384 // for better performance.
386 int ignore_reads_and_writes; 385 int ignore_reads_and_writes;
387 int ignore_sync; 386 int ignore_sync;
455 }; 454 };
456 455
457 #if !SANITIZER_GO 456 #if !SANITIZER_GO
458 #if SANITIZER_MAC || SANITIZER_ANDROID 457 #if SANITIZER_MAC || SANITIZER_ANDROID
459 ThreadState *cur_thread(); 458 ThreadState *cur_thread();
459 void set_cur_thread(ThreadState *thr);
460 void cur_thread_finalize(); 460 void cur_thread_finalize();
461 INLINE void cur_thread_init() { }
461 #else 462 #else
462 __attribute__((tls_model("initial-exec"))) 463 __attribute__((tls_model("initial-exec")))
463 extern THREADLOCAL char cur_thread_placeholder[]; 464 extern THREADLOCAL char cur_thread_placeholder[];
464 INLINE ThreadState *cur_thread() { 465 INLINE ThreadState *cur_thread() {
465 return reinterpret_cast<ThreadState *>(&cur_thread_placeholder); 466 return reinterpret_cast<ThreadState *>(cur_thread_placeholder)->current;
467 }
468 INLINE void cur_thread_init() {
469 ThreadState *thr = reinterpret_cast<ThreadState *>(cur_thread_placeholder);
470 if (UNLIKELY(!thr->current))
471 thr->current = thr;
472 }
473 INLINE void set_cur_thread(ThreadState *thr) {
474 reinterpret_cast<ThreadState *>(cur_thread_placeholder)->current = thr;
466 } 475 }
467 INLINE void cur_thread_finalize() { } 476 INLINE void cur_thread_finalize() { }
468 #endif // SANITIZER_MAC || SANITIZER_ANDROID 477 #endif // SANITIZER_MAC || SANITIZER_ANDROID
469 #endif // SANITIZER_GO 478 #endif // SANITIZER_GO
470 479
515 524
516 struct Context { 525 struct Context {
517 Context(); 526 Context();
518 527
519 bool initialized; 528 bool initialized;
529 #if !SANITIZER_GO
520 bool after_multithreaded_fork; 530 bool after_multithreaded_fork;
531 #endif
521 532
522 MetaMap metamap; 533 MetaMap metamap;
523 534
524 Mutex report_mtx; 535 Mutex report_mtx;
525 int nreported; 536 int nreported;
570 581
571 const char *GetObjectTypeFromTag(uptr tag); 582 const char *GetObjectTypeFromTag(uptr tag);
572 const char *GetReportHeaderFromTag(uptr tag); 583 const char *GetReportHeaderFromTag(uptr tag);
573 uptr TagFromShadowStackFrame(uptr pc); 584 uptr TagFromShadowStackFrame(uptr pc);
574 585
575 class ScopedReport { 586 class ScopedReportBase {
576 public: 587 public:
577 explicit ScopedReport(ReportType typ, uptr tag = kExternalTagNone);
578 ~ScopedReport();
579
580 void AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, StackTrace stack, 588 void AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, StackTrace stack,
581 const MutexSet *mset); 589 const MutexSet *mset);
582 void AddStack(StackTrace stack, bool suppressable = false); 590 void AddStack(StackTrace stack, bool suppressable = false);
583 void AddThread(const ThreadContext *tctx, bool suppressable = false); 591 void AddThread(const ThreadContext *tctx, bool suppressable = false);
584 void AddThread(int unique_tid, bool suppressable = false); 592 void AddThread(int unique_tid, bool suppressable = false);
589 void AddSleep(u32 stack_id); 597 void AddSleep(u32 stack_id);
590 void SetCount(int count); 598 void SetCount(int count);
591 599
592 const ReportDesc *GetReport() const; 600 const ReportDesc *GetReport() const;
593 601
602 protected:
603 ScopedReportBase(ReportType typ, uptr tag);
604 ~ScopedReportBase();
605
594 private: 606 private:
595 ReportDesc *rep_; 607 ReportDesc *rep_;
596 // Symbolizer makes lots of intercepted calls. If we try to process them, 608 // Symbolizer makes lots of intercepted calls. If we try to process them,
597 // at best it will cause deadlocks on internal mutexes. 609 // at best it will cause deadlocks on internal mutexes.
598 ScopedIgnoreInterceptors ignore_interceptors_; 610 ScopedIgnoreInterceptors ignore_interceptors_;
599 611
600 void AddDeadMutex(u64 id); 612 void AddDeadMutex(u64 id);
601 613
602 ScopedReport(const ScopedReport&); 614 ScopedReportBase(const ScopedReportBase &) = delete;
603 void operator = (const ScopedReport&); 615 void operator=(const ScopedReportBase &) = delete;
616 };
617
618 class ScopedReport : public ScopedReportBase {
619 public:
620 explicit ScopedReport(ReportType typ, uptr tag = kExternalTagNone);
621 ~ScopedReport();
622
623 private:
624 ScopedErrorReportLock lock_;
604 }; 625 };
605 626
606 ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack); 627 ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack);
607 void RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk, 628 void RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk,
608 MutexSet *mset, uptr *tag = nullptr); 629 MutexSet *mset, uptr *tag = nullptr);
633 } 654 }
634 stack->Init(&thr->shadow_stack[start], size, toppc); 655 stack->Init(&thr->shadow_stack[start], size, toppc);
635 ExtractTagFromStack(stack, tag); 656 ExtractTagFromStack(stack, tag);
636 } 657 }
637 658
659 #define GET_STACK_TRACE_FATAL(thr, pc) \
660 VarSizeStackTrace stack; \
661 ObtainCurrentStack(thr, pc, &stack); \
662 stack.ReverseOrder();
638 663
639 #if TSAN_COLLECT_STATS 664 #if TSAN_COLLECT_STATS
640 void StatAggregate(u64 *dst, u64 *src); 665 void StatAggregate(u64 *dst, u64 *src);
641 void StatOutput(u64 *stat); 666 void StatOutput(u64 *stat);
642 #endif 667 #endif
653 } 678 }
654 679
655 void MapShadow(uptr addr, uptr size); 680 void MapShadow(uptr addr, uptr size);
656 void MapThreadTrace(uptr addr, uptr size, const char *name); 681 void MapThreadTrace(uptr addr, uptr size, const char *name);
657 void DontNeedShadowFor(uptr addr, uptr size); 682 void DontNeedShadowFor(uptr addr, uptr size);
683 void UnmapShadow(ThreadState *thr, uptr addr, uptr size);
658 void InitializeShadowMemory(); 684 void InitializeShadowMemory();
659 void InitializeInterceptors(); 685 void InitializeInterceptors();
660 void InitializeLibIgnore(); 686 void InitializeLibIgnore();
661 void InitializeDynamicAnnotations(); 687 void InitializeDynamicAnnotations();
662 688
686 ReportStack *SymbolizeStackId(u32 stack_id); 712 ReportStack *SymbolizeStackId(u32 stack_id);
687 void PrintCurrentStack(ThreadState *thr, uptr pc); 713 void PrintCurrentStack(ThreadState *thr, uptr pc);
688 void PrintCurrentStackSlow(uptr pc); // uses libunwind 714 void PrintCurrentStackSlow(uptr pc); // uses libunwind
689 715
690 void Initialize(ThreadState *thr); 716 void Initialize(ThreadState *thr);
717 void MaybeSpawnBackgroundThread();
691 int Finalize(ThreadState *thr); 718 int Finalize(ThreadState *thr);
692 719
693 void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write); 720 void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write);
694 void OnUserFree(ThreadState *thr, uptr pc, uptr p, bool write); 721 void OnUserFree(ThreadState *thr, uptr pc, uptr p, bool write);
695 722
731 } 758 }
732 759
733 void MemoryResetRange(ThreadState *thr, uptr pc, uptr addr, uptr size); 760 void MemoryResetRange(ThreadState *thr, uptr pc, uptr addr, uptr size);
734 void MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size); 761 void MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size);
735 void MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size); 762 void MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size);
763 void MemoryRangeImitateWriteOrResetRange(ThreadState *thr, uptr pc, uptr addr,
764 uptr size);
736 765
737 void ThreadIgnoreBegin(ThreadState *thr, uptr pc, bool save_stack = true); 766 void ThreadIgnoreBegin(ThreadState *thr, uptr pc, bool save_stack = true);
738 void ThreadIgnoreEnd(ThreadState *thr, uptr pc); 767 void ThreadIgnoreEnd(ThreadState *thr, uptr pc);
739 void ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc, bool save_stack = true); 768 void ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc, bool save_stack = true);
740 void ThreadIgnoreSyncEnd(ThreadState *thr, uptr pc); 769 void ThreadIgnoreSyncEnd(ThreadState *thr, uptr pc);
741 770
742 void FuncEntry(ThreadState *thr, uptr pc); 771 void FuncEntry(ThreadState *thr, uptr pc);
743 void FuncExit(ThreadState *thr); 772 void FuncExit(ThreadState *thr);
744 773
745 int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached); 774 int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached);
746 void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread); 775 void ThreadStart(ThreadState *thr, int tid, tid_t os_id,
776 ThreadType thread_type);
747 void ThreadFinish(ThreadState *thr); 777 void ThreadFinish(ThreadState *thr);
748 int ThreadTid(ThreadState *thr, uptr pc, uptr uid); 778 int ThreadTid(ThreadState *thr, uptr pc, uptr uid);
749 void ThreadJoin(ThreadState *thr, uptr pc, int tid); 779 void ThreadJoin(ThreadState *thr, uptr pc, int tid);
750 void ThreadDetach(ThreadState *thr, uptr pc, int tid); 780 void ThreadDetach(ThreadState *thr, uptr pc, int tid);
751 void ThreadFinalize(ThreadState *thr); 781 void ThreadFinalize(ThreadState *thr);
752 void ThreadSetName(ThreadState *thr, const char *name); 782 void ThreadSetName(ThreadState *thr, const char *name);
753 int ThreadCount(ThreadState *thr); 783 int ThreadCount(ThreadState *thr);
754 void ProcessPendingSignals(ThreadState *thr); 784 void ProcessPendingSignals(ThreadState *thr);
785 void ThreadNotJoined(ThreadState *thr, uptr pc, int tid, uptr uid);
755 786
756 Processor *ProcCreate(); 787 Processor *ProcCreate();
757 void ProcDestroy(Processor *proc); 788 void ProcDestroy(Processor *proc);
758 void ProcWire(Processor *proc, ThreadState *thr); 789 void ProcWire(Processor *proc, ThreadState *thr);
759 void ProcUnwire(Processor *proc, ThreadState *thr); 790 void ProcUnwire(Processor *proc, ThreadState *thr);
843 uptr ALWAYS_INLINE HeapEnd() { 874 uptr ALWAYS_INLINE HeapEnd() {
844 return HeapMemEnd() + PrimaryAllocator::AdditionalSize(); 875 return HeapMemEnd() + PrimaryAllocator::AdditionalSize();
845 } 876 }
846 #endif 877 #endif
847 878
879 ThreadState *FiberCreate(ThreadState *thr, uptr pc, unsigned flags);
880 void FiberDestroy(ThreadState *thr, uptr pc, ThreadState *fiber);
881 void FiberSwitch(ThreadState *thr, uptr pc, ThreadState *fiber, unsigned flags);
882
883 // These need to match __tsan_switch_to_fiber_* flags defined in
884 // tsan_interface.h. See documentation there as well.
885 enum FiberSwitchFlags {
886 FiberSwitchFlagNoSync = 1 << 0, // __tsan_switch_to_fiber_no_sync
887 };
888
848 } // namespace __tsan 889 } // namespace __tsan
849 890
850 #endif // TSAN_RTL_H 891 #endif // TSAN_RTL_H