003 File Manager
Current Path:
/usr/src/contrib/llvm-project/compiler-rt/lib/sanitizer_common
usr
/
src
/
contrib
/
llvm-project
/
compiler-rt
/
lib
/
sanitizer_common
/
📁
..
📄
sancov_flags.cpp
(1.64 KB)
📄
sancov_flags.h
(1.08 KB)
📄
sancov_flags.inc
(777 B)
📄
sanitizer_addrhashmap.h
(9.19 KB)
📄
sanitizer_allocator.cpp
(8.73 KB)
📄
sanitizer_allocator.h
(2.69 KB)
📄
sanitizer_allocator_bytemap.h
(3.12 KB)
📄
sanitizer_allocator_checks.cpp
(686 B)
📄
sanitizer_allocator_checks.h
(2.67 KB)
📄
sanitizer_allocator_combined.h
(6.29 KB)
📄
sanitizer_allocator_interface.h
(1.83 KB)
📄
sanitizer_allocator_internal.h
(2.03 KB)
📄
sanitizer_allocator_local_cache.h
(8.95 KB)
📄
sanitizer_allocator_primary32.h
(12.64 KB)
📄
sanitizer_allocator_primary64.h
(32.71 KB)
📄
sanitizer_allocator_report.cpp
(4.68 KB)
📄
sanitizer_allocator_report.h
(1.72 KB)
📄
sanitizer_allocator_secondary.h
(10.78 KB)
📄
sanitizer_allocator_size_class_map.h
(10.12 KB)
📄
sanitizer_allocator_stats.h
(2.76 KB)
📄
sanitizer_asm.h
(2.57 KB)
📄
sanitizer_atomic.h
(1.97 KB)
📄
sanitizer_atomic_clang.h
(3.42 KB)
📄
sanitizer_atomic_clang_mips.h
(3.77 KB)
📄
sanitizer_atomic_clang_other.h
(3.02 KB)
📄
sanitizer_atomic_clang_x86.h
(3.77 KB)
📄
sanitizer_atomic_msvc.h
(8.53 KB)
📄
sanitizer_bitvector.h
(9.43 KB)
📄
sanitizer_bvgraph.h
(4.62 KB)
📄
sanitizer_common.cpp
(10.13 KB)
📄
sanitizer_common.h
(30.64 KB)
📄
sanitizer_common_interceptors.inc
(348.66 KB)
📄
sanitizer_common_interceptors_format.inc
(16.84 KB)
📄
sanitizer_common_interceptors_ioctl.inc
(22.13 KB)
📄
sanitizer_common_interceptors_netbsd_compat.inc
(4.07 KB)
📄
sanitizer_common_interceptors_vfork_aarch64.inc.S
(1.23 KB)
📄
sanitizer_common_interceptors_vfork_arm.inc.S
(1.24 KB)
📄
sanitizer_common_interceptors_vfork_i386.inc.S
(1.66 KB)
📄
sanitizer_common_interceptors_vfork_x86_64.inc.S
(1.03 KB)
📄
sanitizer_common_interface.inc
(2.05 KB)
📄
sanitizer_common_interface_posix.inc
(732 B)
📄
sanitizer_common_libcdep.cpp
(5.4 KB)
📄
sanitizer_common_nolibc.cpp
(1.12 KB)
📄
sanitizer_common_syscalls.inc
(85 KB)
📄
sanitizer_coverage_fuchsia.cpp
(10.1 KB)
📄
sanitizer_coverage_interface.inc
(1.73 KB)
📄
sanitizer_coverage_libcdep_new.cpp
(7.39 KB)
📄
sanitizer_coverage_win_dll_thunk.cpp
(1.03 KB)
📄
sanitizer_coverage_win_dynamic_runtime_thunk.cpp
(1.16 KB)
📄
sanitizer_coverage_win_sections.cpp
(3.36 KB)
📄
sanitizer_coverage_win_weak_interception.cpp
(1.17 KB)
📄
sanitizer_dbghelp.h
(1.44 KB)
📄
sanitizer_deadlock_detector.h
(13.28 KB)
📄
sanitizer_deadlock_detector1.cpp
(5.6 KB)
📄
sanitizer_deadlock_detector2.cpp
(10.84 KB)
📄
sanitizer_deadlock_detector_interface.h
(2.66 KB)
📄
sanitizer_errno.cpp
(1.09 KB)
📄
sanitizer_errno.h
(1.3 KB)
📄
sanitizer_errno_codes.h
(1.1 KB)
📄
sanitizer_file.cpp
(6.24 KB)
📄
sanitizer_file.h
(3.67 KB)
📄
sanitizer_flag_parser.cpp
(5.55 KB)
📄
sanitizer_flag_parser.h
(5.71 KB)
📄
sanitizer_flags.cpp
(3.95 KB)
📄
sanitizer_flags.h
(2.13 KB)
📄
sanitizer_flags.inc
(12.73 KB)
📄
sanitizer_freebsd.h
(3.31 KB)
📄
sanitizer_fuchsia.cpp
(16.58 KB)
📄
sanitizer_fuchsia.h
(1.03 KB)
📄
sanitizer_getauxval.h
(1.73 KB)
📄
sanitizer_glibc_version.h
(748 B)
📄
sanitizer_hash.h
(1.04 KB)
📄
sanitizer_interceptors_ioctl_netbsd.inc
(68.81 KB)
📄
sanitizer_interface_internal.h
(5.28 KB)
📄
sanitizer_internal_defs.h
(14.28 KB)
📄
sanitizer_lfstack.h
(2.08 KB)
📄
sanitizer_libc.cpp
(7.21 KB)
📄
sanitizer_libc.h
(3.23 KB)
📄
sanitizer_libignore.cpp
(4.24 KB)
📄
sanitizer_libignore.h
(3.5 KB)
📄
sanitizer_linux.cpp
(71.58 KB)
📄
sanitizer_linux.h
(5.47 KB)
📄
sanitizer_linux_libcdep.cpp
(25.67 KB)
📄
sanitizer_linux_s390.cpp
(6.91 KB)
📄
sanitizer_list.h
(3.81 KB)
📄
sanitizer_local_address_space_view.h
(3.67 KB)
📄
sanitizer_mac.cpp
(38.67 KB)
📄
sanitizer_mac.h
(2.49 KB)
📄
sanitizer_mac_libcdep.cpp
(968 B)
📄
sanitizer_malloc_mac.inc
(13.06 KB)
📄
sanitizer_mutex.h
(5.17 KB)
📄
sanitizer_netbsd.cpp
(9.95 KB)
📄
sanitizer_openbsd.cpp
(3.17 KB)
📄
sanitizer_persistent_allocator.cpp
(687 B)
📄
sanitizer_persistent_allocator.h
(2.31 KB)
📄
sanitizer_placement_new.h
(885 B)
📄
sanitizer_platform.h
(10.11 KB)
📄
sanitizer_platform_interceptors.h
(24.93 KB)
📄
sanitizer_platform_limits_freebsd.cpp
(19.79 KB)
📄
sanitizer_platform_limits_freebsd.h
(18.41 KB)
📄
sanitizer_platform_limits_linux.cpp
(3.32 KB)
📄
sanitizer_platform_limits_netbsd.cpp
(109.73 KB)
📄
sanitizer_platform_limits_netbsd.h
(81.54 KB)
📄
sanitizer_platform_limits_openbsd.cpp
(8.69 KB)
📄
sanitizer_platform_limits_openbsd.h
(8.68 KB)
📄
sanitizer_platform_limits_posix.cpp
(48.89 KB)
📄
sanitizer_platform_limits_posix.h
(40.65 KB)
📄
sanitizer_platform_limits_solaris.cpp
(11.93 KB)
📄
sanitizer_platform_limits_solaris.h
(12.26 KB)
📄
sanitizer_posix.cpp
(11.93 KB)
📄
sanitizer_posix.h
(5.14 KB)
📄
sanitizer_posix_libcdep.cpp
(16.21 KB)
📄
sanitizer_printf.cpp
(12.07 KB)
📄
sanitizer_procmaps.h
(2.93 KB)
📄
sanitizer_procmaps_bsd.cpp
(3.81 KB)
📄
sanitizer_procmaps_common.cpp
(5.27 KB)
📄
sanitizer_procmaps_fuchsia.cpp
(2.51 KB)
📄
sanitizer_procmaps_linux.cpp
(2.9 KB)
📄
sanitizer_procmaps_mac.cpp
(13.7 KB)
📄
sanitizer_procmaps_solaris.cpp
(2.18 KB)
📄
sanitizer_ptrauth.h
(720 B)
📄
sanitizer_quarantine.h
(9.57 KB)
📄
sanitizer_report_decorator.h
(1.89 KB)
📄
sanitizer_ring_buffer.h
(4.7 KB)
📄
sanitizer_rtems.cpp
(7.61 KB)
📄
sanitizer_rtems.h
(772 B)
📄
sanitizer_signal_interceptors.inc
(2.89 KB)
📄
sanitizer_solaris.cpp
(6.6 KB)
📄
sanitizer_stackdepot.cpp
(4.54 KB)
📄
sanitizer_stackdepot.h
(2.13 KB)
📄
sanitizer_stackdepotbase.h
(5.58 KB)
📄
sanitizer_stacktrace.cpp
(4.58 KB)
📄
sanitizer_stacktrace.h
(5.65 KB)
📄
sanitizer_stacktrace_libcdep.cpp
(5.54 KB)
📄
sanitizer_stacktrace_printer.cpp
(9.08 KB)
📄
sanitizer_stacktrace_printer.h
(3.08 KB)
📄
sanitizer_stacktrace_sparc.cpp
(3.05 KB)
📄
sanitizer_stoptheworld.h
(2.34 KB)
📄
sanitizer_stoptheworld_fuchsia.cpp
(1.28 KB)
📄
sanitizer_stoptheworld_linux_libcdep.cpp
(20.8 KB)
📄
sanitizer_stoptheworld_mac.cpp
(5.29 KB)
📄
sanitizer_stoptheworld_netbsd_libcdep.cpp
(11.02 KB)
📄
sanitizer_suppressions.cpp
(5.67 KB)
📄
sanitizer_suppressions.h
(1.69 KB)
📄
sanitizer_symbolizer.cpp
(3.65 KB)
📄
sanitizer_symbolizer.h
(6.62 KB)
📄
sanitizer_symbolizer_fuchsia.h
(1.56 KB)
📄
sanitizer_symbolizer_internal.h
(5.8 KB)
📄
sanitizer_symbolizer_libbacktrace.cpp
(6.1 KB)
📄
sanitizer_symbolizer_libbacktrace.h
(1.49 KB)
📄
sanitizer_symbolizer_libcdep.cpp
(17.45 KB)
📄
sanitizer_symbolizer_mac.cpp
(8.48 KB)
📄
sanitizer_symbolizer_mac.h
(1.37 KB)
📄
sanitizer_symbolizer_markup.cpp
(5.39 KB)
📄
sanitizer_symbolizer_posix_libcdep.cpp
(16.5 KB)
📄
sanitizer_symbolizer_report.cpp
(10.01 KB)
📄
sanitizer_symbolizer_rtems.h
(1.56 KB)
📄
sanitizer_symbolizer_win.cpp
(11.59 KB)
📄
sanitizer_syscall_generic.inc
(1.06 KB)
📄
sanitizer_syscall_linux_aarch64.inc
(4.58 KB)
📄
sanitizer_syscall_linux_arm.inc
(4.58 KB)
📄
sanitizer_syscall_linux_x86_64.inc
(3.07 KB)
📄
sanitizer_syscalls_netbsd.inc
(120.97 KB)
📄
sanitizer_termination.cpp
(2.86 KB)
📄
sanitizer_thread_registry.cpp
(10.31 KB)
📄
sanitizer_thread_registry.h
(5.44 KB)
📄
sanitizer_tls_get_addr.cpp
(5.29 KB)
📄
sanitizer_tls_get_addr.h
(2.21 KB)
📄
sanitizer_type_traits.cpp
(708 B)
📄
sanitizer_type_traits.h
(1.49 KB)
📄
sanitizer_unwind_linux_libcdep.cpp
(6.13 KB)
📄
sanitizer_unwind_win.cpp
(2.41 KB)
📄
sanitizer_vector.h
(2.57 KB)
📄
sanitizer_win.cpp
(33.3 KB)
📄
sanitizer_win.h
(851 B)
📄
sanitizer_win_defs.h
(7.23 KB)
📄
sanitizer_win_dll_thunk.cpp
(3.41 KB)
📄
sanitizer_win_dll_thunk.h
(11.13 KB)
📄
sanitizer_win_dynamic_runtime_thunk.cpp
(1.16 KB)
📄
sanitizer_win_weak_interception.cpp
(3.49 KB)
📄
sanitizer_win_weak_interception.h
(1.64 KB)
📁
symbolizer
📄
weak_symbols.txt
(230 B)
Editing: sanitizer_deadlock_detector2.cpp
//===-- sanitizer_deadlock_detector2.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Deadlock detector implementation based on adjacency lists. // //===----------------------------------------------------------------------===// #include "sanitizer_deadlock_detector_interface.h" #include "sanitizer_common.h" #include "sanitizer_allocator_internal.h" #include "sanitizer_placement_new.h" #include "sanitizer_mutex.h" #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 2 namespace __sanitizer { const int kMaxNesting = 64; const u32 kNoId = -1; const u32 kEndId = -2; const int kMaxLink = 8; const int kL1Size = 1024; const int kL2Size = 1024; const int kMaxMutex = kL1Size * kL2Size; struct Id { u32 id; u32 seq; explicit Id(u32 id = 0, u32 seq = 0) : id(id) , seq(seq) { } }; struct Link { u32 id; u32 seq; u32 tid; u32 stk0; u32 stk1; explicit Link(u32 id = 0, u32 seq = 0, u32 tid = 0, u32 s0 = 0, u32 s1 = 0) : id(id) , seq(seq) , tid(tid) , stk0(s0) , stk1(s1) { } }; struct DDPhysicalThread { DDReport rep; bool report_pending; bool visited[kMaxMutex]; Link pending[kMaxMutex]; Link path[kMaxMutex]; }; struct ThreadMutex { u32 id; u32 stk; }; struct DDLogicalThread { u64 ctx; ThreadMutex locked[kMaxNesting]; int nlocked; }; struct Mutex { StaticSpinMutex mtx; u32 seq; int nlink; Link link[kMaxLink]; }; struct DD : public DDetector { explicit DD(const DDFlags *flags); DDPhysicalThread* CreatePhysicalThread(); void DestroyPhysicalThread(DDPhysicalThread *pt); DDLogicalThread* CreateLogicalThread(u64 ctx); void DestroyLogicalThread(DDLogicalThread *lt); void MutexInit(DDCallback *cb, DDMutex *m); void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock); void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, bool trylock); void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock); void MutexDestroy(DDCallback *cb, DDMutex *m); DDReport *GetReport(DDCallback *cb); void CycleCheck(DDPhysicalThread *pt, DDLogicalThread *lt, DDMutex *mtx); void Report(DDPhysicalThread *pt, DDLogicalThread *lt, int npath); u32 allocateId(DDCallback *cb); Mutex *getMutex(u32 id); u32 getMutexId(Mutex *m); DDFlags flags; Mutex* mutex[kL1Size]; SpinMutex mtx; InternalMmapVector<u32> free_id; int id_gen = 0; }; DDetector *DDetector::Create(const DDFlags *flags) { (void)flags; void *mem = MmapOrDie(sizeof(DD), "deadlock detector"); return new(mem) DD(flags); } DD::DD(const DDFlags *flags) : flags(*flags) { free_id.reserve(1024); } DDPhysicalThread* DD::CreatePhysicalThread() { DDPhysicalThread *pt = (DDPhysicalThread*)MmapOrDie(sizeof(DDPhysicalThread), "deadlock detector (physical thread)"); return pt; } void DD::DestroyPhysicalThread(DDPhysicalThread *pt) { pt->~DDPhysicalThread(); UnmapOrDie(pt, sizeof(DDPhysicalThread)); } DDLogicalThread* DD::CreateLogicalThread(u64 ctx) { DDLogicalThread *lt = (DDLogicalThread*)InternalAlloc( sizeof(DDLogicalThread)); lt->ctx = ctx; lt->nlocked = 0; return lt; } void DD::DestroyLogicalThread(DDLogicalThread *lt) { lt->~DDLogicalThread(); InternalFree(lt); } void DD::MutexInit(DDCallback *cb, DDMutex *m) { VPrintf(2, "#%llu: DD::MutexInit(%p)\n", cb->lt->ctx, m); m->id = kNoId; m->recursion = 0; atomic_store(&m->owner, 0, memory_order_relaxed); } Mutex *DD::getMutex(u32 id) { return &mutex[id / kL2Size][id % kL2Size]; } u32 DD::getMutexId(Mutex *m) { for (int i = 0; i < kL1Size; i++) { Mutex *tab = mutex[i]; if (tab == 0) break; if (m >= tab && m < tab + kL2Size) return i * kL2Size + (m - tab); } return -1; } u32 DD::allocateId(DDCallback *cb) { u32 id = -1; SpinMutexLock l(&mtx); if (free_id.size() > 0) { id = free_id.back(); free_id.pop_back(); } else { CHECK_LT(id_gen, kMaxMutex); if ((id_gen % kL2Size) == 0) { mutex[id_gen / kL2Size] = (Mutex*)MmapOrDie(kL2Size * sizeof(Mutex), "deadlock detector (mutex table)"); } id = id_gen++; } CHECK_LE(id, kMaxMutex); VPrintf(3, "#%llu: DD::allocateId assign id %d\n", cb->lt->ctx, id); return id; } void DD::MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) { VPrintf(2, "#%llu: DD::MutexBeforeLock(%p, wlock=%d) nlocked=%d\n", cb->lt->ctx, m, wlock, cb->lt->nlocked); DDPhysicalThread *pt = cb->pt; DDLogicalThread *lt = cb->lt; uptr owner = atomic_load(&m->owner, memory_order_relaxed); if (owner == (uptr)cb->lt) { VPrintf(3, "#%llu: DD::MutexBeforeLock recursive\n", cb->lt->ctx); return; } CHECK_LE(lt->nlocked, kMaxNesting); // FIXME(dvyukov): don't allocate id if lt->nlocked == 0? if (m->id == kNoId) m->id = allocateId(cb); ThreadMutex *tm = <->locked[lt->nlocked++]; tm->id = m->id; if (flags.second_deadlock_stack) tm->stk = cb->Unwind(); if (lt->nlocked == 1) { VPrintf(3, "#%llu: DD::MutexBeforeLock first mutex\n", cb->lt->ctx); return; } bool added = false; Mutex *mtx = getMutex(m->id); for (int i = 0; i < lt->nlocked - 1; i++) { u32 id1 = lt->locked[i].id; u32 stk1 = lt->locked[i].stk; Mutex *mtx1 = getMutex(id1); SpinMutexLock l(&mtx1->mtx); if (mtx1->nlink == kMaxLink) { // FIXME(dvyukov): check stale links continue; } int li = 0; for (; li < mtx1->nlink; li++) { Link *link = &mtx1->link[li]; if (link->id == m->id) { if (link->seq != mtx->seq) { link->seq = mtx->seq; link->tid = lt->ctx; link->stk0 = stk1; link->stk1 = cb->Unwind(); added = true; VPrintf(3, "#%llu: DD::MutexBeforeLock added %d->%d link\n", cb->lt->ctx, getMutexId(mtx1), m->id); } break; } } if (li == mtx1->nlink) { // FIXME(dvyukov): check stale links Link *link = &mtx1->link[mtx1->nlink++]; link->id = m->id; link->seq = mtx->seq; link->tid = lt->ctx; link->stk0 = stk1; link->stk1 = cb->Unwind(); added = true; VPrintf(3, "#%llu: DD::MutexBeforeLock added %d->%d link\n", cb->lt->ctx, getMutexId(mtx1), m->id); } } if (!added || mtx->nlink == 0) { VPrintf(3, "#%llu: DD::MutexBeforeLock don't check\n", cb->lt->ctx); return; } CycleCheck(pt, lt, m); } void DD::MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, bool trylock) { VPrintf(2, "#%llu: DD::MutexAfterLock(%p, wlock=%d, try=%d) nlocked=%d\n", cb->lt->ctx, m, wlock, trylock, cb->lt->nlocked); DDLogicalThread *lt = cb->lt; uptr owner = atomic_load(&m->owner, memory_order_relaxed); if (owner == (uptr)cb->lt) { VPrintf(3, "#%llu: DD::MutexAfterLock recursive\n", cb->lt->ctx); CHECK(wlock); m->recursion++; return; } CHECK_EQ(owner, 0); if (wlock) { VPrintf(3, "#%llu: DD::MutexAfterLock set owner\n", cb->lt->ctx); CHECK_EQ(m->recursion, 0); m->recursion = 1; atomic_store(&m->owner, (uptr)cb->lt, memory_order_relaxed); } if (!trylock) return; CHECK_LE(lt->nlocked, kMaxNesting); if (m->id == kNoId) m->id = allocateId(cb); ThreadMutex *tm = <->locked[lt->nlocked++]; tm->id = m->id; if (flags.second_deadlock_stack) tm->stk = cb->Unwind(); } void DD::MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) { VPrintf(2, "#%llu: DD::MutexBeforeUnlock(%p, wlock=%d) nlocked=%d\n", cb->lt->ctx, m, wlock, cb->lt->nlocked); DDLogicalThread *lt = cb->lt; uptr owner = atomic_load(&m->owner, memory_order_relaxed); if (owner == (uptr)cb->lt) { VPrintf(3, "#%llu: DD::MutexBeforeUnlock recursive\n", cb->lt->ctx); if (--m->recursion > 0) return; VPrintf(3, "#%llu: DD::MutexBeforeUnlock reset owner\n", cb->lt->ctx); atomic_store(&m->owner, 0, memory_order_relaxed); } CHECK_NE(m->id, kNoId); int last = lt->nlocked - 1; for (int i = last; i >= 0; i--) { if (cb->lt->locked[i].id == m->id) { lt->locked[i] = lt->locked[last]; lt->nlocked--; break; } } } void DD::MutexDestroy(DDCallback *cb, DDMutex *m) { VPrintf(2, "#%llu: DD::MutexDestroy(%p)\n", cb->lt->ctx, m); DDLogicalThread *lt = cb->lt; if (m->id == kNoId) return; // Remove the mutex from lt->locked if there. int last = lt->nlocked - 1; for (int i = last; i >= 0; i--) { if (lt->locked[i].id == m->id) { lt->locked[i] = lt->locked[last]; lt->nlocked--; break; } } // Clear and invalidate the mutex descriptor. { Mutex *mtx = getMutex(m->id); SpinMutexLock l(&mtx->mtx); mtx->seq++; mtx->nlink = 0; } // Return id to cache. { SpinMutexLock l(&mtx); free_id.push_back(m->id); } } void DD::CycleCheck(DDPhysicalThread *pt, DDLogicalThread *lt, DDMutex *m) { internal_memset(pt->visited, 0, sizeof(pt->visited)); int npath = 0; int npending = 0; { Mutex *mtx = getMutex(m->id); SpinMutexLock l(&mtx->mtx); for (int li = 0; li < mtx->nlink; li++) pt->pending[npending++] = mtx->link[li]; } while (npending > 0) { Link link = pt->pending[--npending]; if (link.id == kEndId) { npath--; continue; } if (pt->visited[link.id]) continue; Mutex *mtx1 = getMutex(link.id); SpinMutexLock l(&mtx1->mtx); if (mtx1->seq != link.seq) continue; pt->visited[link.id] = true; if (mtx1->nlink == 0) continue; pt->path[npath++] = link; pt->pending[npending++] = Link(kEndId); if (link.id == m->id) return Report(pt, lt, npath); // Bingo! for (int li = 0; li < mtx1->nlink; li++) { Link *link1 = &mtx1->link[li]; // Mutex *mtx2 = getMutex(link->id); // FIXME(dvyukov): fast seq check // FIXME(dvyukov): fast nlink != 0 check // FIXME(dvyukov): fast pending check? // FIXME(dvyukov): npending can be larger than kMaxMutex pt->pending[npending++] = *link1; } } } void DD::Report(DDPhysicalThread *pt, DDLogicalThread *lt, int npath) { DDReport *rep = &pt->rep; rep->n = npath; for (int i = 0; i < npath; i++) { Link *link = &pt->path[i]; Link *link0 = &pt->path[i ? i - 1 : npath - 1]; rep->loop[i].thr_ctx = link->tid; rep->loop[i].mtx_ctx0 = link0->id; rep->loop[i].mtx_ctx1 = link->id; rep->loop[i].stk[0] = flags.second_deadlock_stack ? link->stk0 : 0; rep->loop[i].stk[1] = link->stk1; } pt->report_pending = true; } DDReport *DD::GetReport(DDCallback *cb) { if (!cb->pt->report_pending) return 0; cb->pt->report_pending = false; return &cb->pt->rep; } } // namespace __sanitizer #endif // #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 2
Upload File
Create Folder