tsan_rtl.cpp revision 1.5 1 1.1 mrg //===-- tsan_rtl.cpp ------------------------------------------------------===//
2 1.1 mrg //
3 1.1 mrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 1.1 mrg // See https://llvm.org/LICENSE.txt for license information.
5 1.1 mrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 1.1 mrg //
7 1.1 mrg //===----------------------------------------------------------------------===//
8 1.1 mrg //
9 1.1 mrg // This file is a part of ThreadSanitizer (TSan), a race detector.
10 1.1 mrg //
11 1.1 mrg // Main file (entry points) for the TSan run-time.
12 1.1 mrg //===----------------------------------------------------------------------===//
13 1.1 mrg
14 1.3 mrg #include "tsan_rtl.h"
15 1.3 mrg
16 1.1 mrg #include "sanitizer_common/sanitizer_atomic.h"
17 1.1 mrg #include "sanitizer_common/sanitizer_common.h"
18 1.1 mrg #include "sanitizer_common/sanitizer_file.h"
19 1.5 mrg #include "sanitizer_common/sanitizer_interface_internal.h"
20 1.1 mrg #include "sanitizer_common/sanitizer_libc.h"
21 1.3 mrg #include "sanitizer_common/sanitizer_placement_new.h"
22 1.1 mrg #include "sanitizer_common/sanitizer_stackdepot.h"
23 1.1 mrg #include "sanitizer_common/sanitizer_symbolizer.h"
24 1.1 mrg #include "tsan_defs.h"
25 1.3 mrg #include "tsan_interface.h"
26 1.3 mrg #include "tsan_mman.h"
27 1.1 mrg #include "tsan_platform.h"
28 1.1 mrg #include "tsan_suppressions.h"
29 1.1 mrg #include "tsan_symbolize.h"
30 1.1 mrg #include "ubsan/ubsan_init.h"
31 1.1 mrg
32 1.1 mrg volatile int __tsan_resumed = 0;
33 1.1 mrg
34 1.1 mrg extern "C" void __tsan_resume() {
35 1.1 mrg __tsan_resumed = 1;
36 1.1 mrg }
37 1.1 mrg
38 1.5 mrg SANITIZER_WEAK_DEFAULT_IMPL
39 1.5 mrg void __tsan_test_only_on_fork() {}
40 1.5 mrg
41 1.1 mrg namespace __tsan {
42 1.1 mrg
43 1.3 mrg #if !SANITIZER_GO
44 1.3 mrg void (*on_initialize)(void);
45 1.3 mrg int (*on_finalize)(int);
46 1.3 mrg #endif
47 1.3 mrg
48 1.4 riastrad // XXX PR lib/58349 (https://gnats.NetBSD.org/58349): NetBSD ld.elf_so
49 1.4 riastrad // doesn't support TLS alignment beyond void *, so we have to buffer
50 1.4 riastrad // some extra space and do the alignment ourselves at all the reference
51 1.4 riastrad // sites.
52 1.5 mrg #if !SANITIZER_GO && !SANITIZER_APPLE
53 1.1 mrg __attribute__((tls_model("initial-exec")))
54 1.4 riastrad THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState) + SANITIZER_CACHE_LINE_SIZE - 1] ALIGNED(
55 1.3 mrg SANITIZER_CACHE_LINE_SIZE);
56 1.1 mrg #endif
57 1.4 riastrad static char ctx_placeholder[sizeof(Context) + SANITIZER_CACHE_LINE_SIZE - 1] ALIGNED(SANITIZER_CACHE_LINE_SIZE);
58 1.1 mrg Context *ctx;
59 1.1 mrg
60 1.1 mrg // Can be overriden by a front-end.
61 1.1 mrg #ifdef TSAN_EXTERNAL_HOOKS
62 1.1 mrg bool OnFinalize(bool failed);
63 1.1 mrg void OnInitialize();
64 1.1 mrg #else
65 1.1 mrg SANITIZER_WEAK_CXX_DEFAULT_IMPL
66 1.1 mrg bool OnFinalize(bool failed) {
67 1.5 mrg # if !SANITIZER_GO
68 1.3 mrg if (on_finalize)
69 1.3 mrg return on_finalize(failed);
70 1.5 mrg # endif
71 1.1 mrg return failed;
72 1.1 mrg }
73 1.5 mrg
74 1.1 mrg SANITIZER_WEAK_CXX_DEFAULT_IMPL
75 1.3 mrg void OnInitialize() {
76 1.5 mrg # if !SANITIZER_GO
77 1.3 mrg if (on_initialize)
78 1.3 mrg on_initialize();
79 1.5 mrg # endif
80 1.5 mrg }
81 1.3 mrg #endif
82 1.5 mrg
83 1.5 mrg static TracePart* TracePartAlloc(ThreadState* thr) {
84 1.5 mrg TracePart* part = nullptr;
85 1.5 mrg {
86 1.5 mrg Lock lock(&ctx->slot_mtx);
87 1.5 mrg uptr max_parts = Trace::kMinParts + flags()->history_size;
88 1.5 mrg Trace* trace = &thr->tctx->trace;
89 1.5 mrg if (trace->parts_allocated == max_parts ||
90 1.5 mrg ctx->trace_part_finished_excess) {
91 1.5 mrg part = ctx->trace_part_recycle.PopFront();
92 1.5 mrg DPrintf("#%d: TracePartAlloc: part=%p\n", thr->tid, part);
93 1.5 mrg if (part && part->trace) {
94 1.5 mrg Trace* trace1 = part->trace;
95 1.5 mrg Lock trace_lock(&trace1->mtx);
96 1.5 mrg part->trace = nullptr;
97 1.5 mrg TracePart* part1 = trace1->parts.PopFront();
98 1.5 mrg CHECK_EQ(part, part1);
99 1.5 mrg if (trace1->parts_allocated > trace1->parts.Size()) {
100 1.5 mrg ctx->trace_part_finished_excess +=
101 1.5 mrg trace1->parts_allocated - trace1->parts.Size();
102 1.5 mrg trace1->parts_allocated = trace1->parts.Size();
103 1.5 mrg }
104 1.5 mrg }
105 1.5 mrg }
106 1.5 mrg if (trace->parts_allocated < max_parts) {
107 1.5 mrg trace->parts_allocated++;
108 1.5 mrg if (ctx->trace_part_finished_excess)
109 1.5 mrg ctx->trace_part_finished_excess--;
110 1.5 mrg }
111 1.5 mrg if (!part)
112 1.5 mrg ctx->trace_part_total_allocated++;
113 1.5 mrg else if (ctx->trace_part_recycle_finished)
114 1.5 mrg ctx->trace_part_recycle_finished--;
115 1.5 mrg }
116 1.5 mrg if (!part)
117 1.5 mrg part = new (MmapOrDie(sizeof(*part), "TracePart")) TracePart();
118 1.5 mrg return part;
119 1.5 mrg }
120 1.5 mrg
121 1.5 mrg static void TracePartFree(TracePart* part) SANITIZER_REQUIRES(ctx->slot_mtx) {
122 1.5 mrg DCHECK(part->trace);
123 1.5 mrg part->trace = nullptr;
124 1.5 mrg ctx->trace_part_recycle.PushFront(part);
125 1.5 mrg }
126 1.5 mrg
127 1.5 mrg void TraceResetForTesting() {
128 1.5 mrg Lock lock(&ctx->slot_mtx);
129 1.5 mrg while (auto* part = ctx->trace_part_recycle.PopFront()) {
130 1.5 mrg if (auto trace = part->trace)
131 1.5 mrg CHECK_EQ(trace->parts.PopFront(), part);
132 1.5 mrg UnmapOrDie(part, sizeof(*part));
133 1.5 mrg }
134 1.5 mrg ctx->trace_part_total_allocated = 0;
135 1.5 mrg ctx->trace_part_recycle_finished = 0;
136 1.5 mrg ctx->trace_part_finished_excess = 0;
137 1.5 mrg }
138 1.5 mrg
139 1.5 mrg static void DoResetImpl(uptr epoch) {
140 1.5 mrg ThreadRegistryLock lock0(&ctx->thread_registry);
141 1.5 mrg Lock lock1(&ctx->slot_mtx);
142 1.5 mrg CHECK_EQ(ctx->global_epoch, epoch);
143 1.5 mrg ctx->global_epoch++;
144 1.5 mrg CHECK(!ctx->resetting);
145 1.5 mrg ctx->resetting = true;
146 1.5 mrg for (u32 i = ctx->thread_registry.NumThreadsLocked(); i--;) {
147 1.5 mrg ThreadContext* tctx = (ThreadContext*)ctx->thread_registry.GetThreadLocked(
148 1.5 mrg static_cast<Tid>(i));
149 1.5 mrg // Potentially we could purge all ThreadStatusDead threads from the
150 1.5 mrg // registry. Since we reset all shadow, they can't race with anything
151 1.5 mrg // anymore. However, their tid's can still be stored in some aux places
152 1.5 mrg // (e.g. tid of thread that created something).
153 1.5 mrg auto trace = &tctx->trace;
154 1.5 mrg Lock lock(&trace->mtx);
155 1.5 mrg bool attached = tctx->thr && tctx->thr->slot;
156 1.5 mrg auto parts = &trace->parts;
157 1.5 mrg bool local = false;
158 1.5 mrg while (!parts->Empty()) {
159 1.5 mrg auto part = parts->Front();
160 1.5 mrg local = local || part == trace->local_head;
161 1.5 mrg if (local)
162 1.5 mrg CHECK(!ctx->trace_part_recycle.Queued(part));
163 1.5 mrg else
164 1.5 mrg ctx->trace_part_recycle.Remove(part);
165 1.5 mrg if (attached && parts->Size() == 1) {
166 1.5 mrg // The thread is running and this is the last/current part.
167 1.5 mrg // Set the trace position to the end of the current part
168 1.5 mrg // to force the thread to call SwitchTracePart and re-attach
169 1.5 mrg // to a new slot and allocate a new trace part.
170 1.5 mrg // Note: the thread is concurrently modifying the position as well,
171 1.5 mrg // so this is only best-effort. The thread can only modify position
172 1.5 mrg // within this part, because switching parts is protected by
173 1.5 mrg // slot/trace mutexes that we hold here.
174 1.5 mrg atomic_store_relaxed(
175 1.5 mrg &tctx->thr->trace_pos,
176 1.5 mrg reinterpret_cast<uptr>(&part->events[TracePart::kSize]));
177 1.5 mrg break;
178 1.5 mrg }
179 1.5 mrg parts->Remove(part);
180 1.5 mrg TracePartFree(part);
181 1.5 mrg }
182 1.5 mrg CHECK_LE(parts->Size(), 1);
183 1.5 mrg trace->local_head = parts->Front();
184 1.5 mrg if (tctx->thr && !tctx->thr->slot) {
185 1.5 mrg atomic_store_relaxed(&tctx->thr->trace_pos, 0);
186 1.5 mrg tctx->thr->trace_prev_pc = 0;
187 1.5 mrg }
188 1.5 mrg if (trace->parts_allocated > trace->parts.Size()) {
189 1.5 mrg ctx->trace_part_finished_excess +=
190 1.5 mrg trace->parts_allocated - trace->parts.Size();
191 1.5 mrg trace->parts_allocated = trace->parts.Size();
192 1.5 mrg }
193 1.5 mrg }
194 1.5 mrg while (ctx->slot_queue.PopFront()) {
195 1.5 mrg }
196 1.5 mrg for (auto& slot : ctx->slots) {
197 1.5 mrg slot.SetEpoch(kEpochZero);
198 1.5 mrg slot.journal.Reset();
199 1.5 mrg slot.thr = nullptr;
200 1.5 mrg ctx->slot_queue.PushBack(&slot);
201 1.5 mrg }
202 1.5 mrg
203 1.5 mrg DPrintf("Resetting shadow...\n");
204 1.5 mrg auto shadow_begin = ShadowBeg();
205 1.5 mrg auto shadow_end = ShadowEnd();
206 1.5 mrg #if SANITIZER_GO
207 1.5 mrg CHECK_NE(0, ctx->mapped_shadow_begin);
208 1.5 mrg shadow_begin = ctx->mapped_shadow_begin;
209 1.5 mrg shadow_end = ctx->mapped_shadow_end;
210 1.5 mrg VPrintf(2, "shadow_begin-shadow_end: (0x%zx-0x%zx)\n",
211 1.5 mrg shadow_begin, shadow_end);
212 1.1 mrg #endif
213 1.1 mrg
214 1.5 mrg #if SANITIZER_WINDOWS
215 1.5 mrg auto resetFailed =
216 1.5 mrg !ZeroMmapFixedRegion(shadow_begin, shadow_end - shadow_begin);
217 1.5 mrg #else
218 1.5 mrg auto resetFailed =
219 1.5 mrg !MmapFixedSuperNoReserve(shadow_begin, shadow_end-shadow_begin, "shadow");
220 1.5 mrg # if !SANITIZER_GO
221 1.5 mrg DontDumpShadow(shadow_begin, shadow_end - shadow_begin);
222 1.5 mrg # endif
223 1.5 mrg #endif
224 1.5 mrg if (resetFailed) {
225 1.5 mrg Printf("failed to reset shadow memory\n");
226 1.5 mrg Die();
227 1.5 mrg }
228 1.5 mrg DPrintf("Resetting meta shadow...\n");
229 1.5 mrg ctx->metamap.ResetClocks();
230 1.5 mrg StoreShadow(&ctx->last_spurious_race, Shadow::kEmpty);
231 1.5 mrg ctx->resetting = false;
232 1.5 mrg }
233 1.5 mrg
234 1.5 mrg // Clang does not understand locking all slots in the loop:
235 1.5 mrg // error: expecting mutex 'slot.mtx' to be held at start of each loop
236 1.5 mrg void DoReset(ThreadState* thr, uptr epoch) SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
237 1.5 mrg for (auto& slot : ctx->slots) {
238 1.5 mrg slot.mtx.Lock();
239 1.5 mrg if (UNLIKELY(epoch == 0))
240 1.5 mrg epoch = ctx->global_epoch;
241 1.5 mrg if (UNLIKELY(epoch != ctx->global_epoch)) {
242 1.5 mrg // Epoch can't change once we've locked the first slot.
243 1.5 mrg CHECK_EQ(slot.sid, 0);
244 1.5 mrg slot.mtx.Unlock();
245 1.5 mrg return;
246 1.3 mrg }
247 1.3 mrg }
248 1.5 mrg DPrintf("#%d: DoReset epoch=%lu\n", thr ? thr->tid : -1, epoch);
249 1.5 mrg DoResetImpl(epoch);
250 1.5 mrg for (auto& slot : ctx->slots) slot.mtx.Unlock();
251 1.5 mrg }
252 1.5 mrg
253 1.5 mrg void FlushShadowMemory() { DoReset(nullptr, 0); }
254 1.5 mrg
255 1.5 mrg static TidSlot* FindSlotAndLock(ThreadState* thr)
256 1.5 mrg SANITIZER_ACQUIRE(thr->slot->mtx) SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
257 1.5 mrg CHECK(!thr->slot);
258 1.5 mrg TidSlot* slot = nullptr;
259 1.5 mrg for (;;) {
260 1.5 mrg uptr epoch;
261 1.5 mrg {
262 1.5 mrg Lock lock(&ctx->slot_mtx);
263 1.5 mrg epoch = ctx->global_epoch;
264 1.5 mrg if (slot) {
265 1.5 mrg // This is an exhausted slot from the previous iteration.
266 1.5 mrg if (ctx->slot_queue.Queued(slot))
267 1.5 mrg ctx->slot_queue.Remove(slot);
268 1.5 mrg thr->slot_locked = false;
269 1.5 mrg slot->mtx.Unlock();
270 1.5 mrg }
271 1.5 mrg for (;;) {
272 1.5 mrg slot = ctx->slot_queue.PopFront();
273 1.5 mrg if (!slot)
274 1.5 mrg break;
275 1.5 mrg if (slot->epoch() != kEpochLast) {
276 1.5 mrg ctx->slot_queue.PushBack(slot);
277 1.5 mrg break;
278 1.5 mrg }
279 1.5 mrg }
280 1.5 mrg }
281 1.5 mrg if (!slot) {
282 1.5 mrg DoReset(thr, epoch);
283 1.5 mrg continue;
284 1.5 mrg }
285 1.5 mrg slot->mtx.Lock();
286 1.5 mrg CHECK(!thr->slot_locked);
287 1.5 mrg thr->slot_locked = true;
288 1.5 mrg if (slot->thr) {
289 1.5 mrg DPrintf("#%d: preempting sid=%d tid=%d\n", thr->tid, (u32)slot->sid,
290 1.5 mrg slot->thr->tid);
291 1.5 mrg slot->SetEpoch(slot->thr->fast_state.epoch());
292 1.5 mrg slot->thr = nullptr;
293 1.5 mrg }
294 1.5 mrg if (slot->epoch() != kEpochLast)
295 1.5 mrg return slot;
296 1.5 mrg }
297 1.1 mrg }
298 1.1 mrg
299 1.5 mrg void SlotAttachAndLock(ThreadState* thr) {
300 1.5 mrg TidSlot* slot = FindSlotAndLock(thr);
301 1.5 mrg DPrintf("#%d: SlotAttach: slot=%u\n", thr->tid, static_cast<int>(slot->sid));
302 1.5 mrg CHECK(!slot->thr);
303 1.5 mrg CHECK(!thr->slot);
304 1.5 mrg slot->thr = thr;
305 1.5 mrg thr->slot = slot;
306 1.5 mrg Epoch epoch = EpochInc(slot->epoch());
307 1.5 mrg CHECK(!EpochOverflow(epoch));
308 1.5 mrg slot->SetEpoch(epoch);
309 1.5 mrg thr->fast_state.SetSid(slot->sid);
310 1.5 mrg thr->fast_state.SetEpoch(epoch);
311 1.5 mrg if (thr->slot_epoch != ctx->global_epoch) {
312 1.5 mrg thr->slot_epoch = ctx->global_epoch;
313 1.5 mrg thr->clock.Reset();
314 1.1 mrg #if !SANITIZER_GO
315 1.5 mrg thr->last_sleep_stack_id = kInvalidStackID;
316 1.5 mrg thr->last_sleep_clock.Reset();
317 1.1 mrg #endif
318 1.5 mrg }
319 1.5 mrg thr->clock.Set(slot->sid, epoch);
320 1.5 mrg slot->journal.PushBack({thr->tid, epoch});
321 1.5 mrg }
322 1.5 mrg
323 1.5 mrg static void SlotDetachImpl(ThreadState* thr, bool exiting) {
324 1.5 mrg TidSlot* slot = thr->slot;
325 1.5 mrg thr->slot = nullptr;
326 1.5 mrg if (thr != slot->thr) {
327 1.5 mrg slot = nullptr; // we don't own the slot anymore
328 1.5 mrg if (thr->slot_epoch != ctx->global_epoch) {
329 1.5 mrg TracePart* part = nullptr;
330 1.5 mrg auto* trace = &thr->tctx->trace;
331 1.5 mrg {
332 1.5 mrg Lock l(&trace->mtx);
333 1.5 mrg auto* parts = &trace->parts;
334 1.5 mrg // The trace can be completely empty in an unlikely event
335 1.5 mrg // the thread is preempted right after it acquired the slot
336 1.5 mrg // in ThreadStart and did not trace any events yet.
337 1.5 mrg CHECK_LE(parts->Size(), 1);
338 1.5 mrg part = parts->PopFront();
339 1.5 mrg thr->tctx->trace.local_head = nullptr;
340 1.5 mrg atomic_store_relaxed(&thr->trace_pos, 0);
341 1.5 mrg thr->trace_prev_pc = 0;
342 1.5 mrg }
343 1.5 mrg if (part) {
344 1.5 mrg Lock l(&ctx->slot_mtx);
345 1.5 mrg TracePartFree(part);
346 1.5 mrg }
347 1.5 mrg }
348 1.5 mrg return;
349 1.5 mrg }
350 1.5 mrg CHECK(exiting || thr->fast_state.epoch() == kEpochLast);
351 1.5 mrg slot->SetEpoch(thr->fast_state.epoch());
352 1.5 mrg slot->thr = nullptr;
353 1.5 mrg }
354 1.5 mrg
355 1.5 mrg void SlotDetach(ThreadState* thr) {
356 1.5 mrg Lock lock(&thr->slot->mtx);
357 1.5 mrg SlotDetachImpl(thr, true);
358 1.5 mrg }
359 1.5 mrg
360 1.5 mrg void SlotLock(ThreadState* thr) SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
361 1.5 mrg DCHECK(!thr->slot_locked);
362 1.5 mrg #if SANITIZER_DEBUG
363 1.5 mrg // Check these mutexes are not locked.
364 1.5 mrg // We can call DoReset from SlotAttachAndLock, which will lock
365 1.5 mrg // these mutexes, but it happens only every once in a while.
366 1.5 mrg { ThreadRegistryLock lock(&ctx->thread_registry); }
367 1.5 mrg { Lock lock(&ctx->slot_mtx); }
368 1.5 mrg #endif
369 1.5 mrg TidSlot* slot = thr->slot;
370 1.5 mrg slot->mtx.Lock();
371 1.5 mrg thr->slot_locked = true;
372 1.5 mrg if (LIKELY(thr == slot->thr && thr->fast_state.epoch() != kEpochLast))
373 1.5 mrg return;
374 1.5 mrg SlotDetachImpl(thr, false);
375 1.5 mrg thr->slot_locked = false;
376 1.5 mrg slot->mtx.Unlock();
377 1.5 mrg SlotAttachAndLock(thr);
378 1.5 mrg }
379 1.5 mrg
380 1.5 mrg void SlotUnlock(ThreadState* thr) {
381 1.5 mrg DCHECK(thr->slot_locked);
382 1.5 mrg thr->slot_locked = false;
383 1.5 mrg thr->slot->mtx.Unlock();
384 1.5 mrg }
385 1.1 mrg
386 1.1 mrg Context::Context()
387 1.3 mrg : initialized(),
388 1.3 mrg report_mtx(MutexTypeReport),
389 1.3 mrg nreported(),
390 1.5 mrg thread_registry([](Tid tid) -> ThreadContextBase* {
391 1.5 mrg return new (Alloc(sizeof(ThreadContext))) ThreadContext(tid);
392 1.5 mrg }),
393 1.3 mrg racy_mtx(MutexTypeRacy),
394 1.3 mrg racy_stacks(),
395 1.3 mrg fired_suppressions_mtx(MutexTypeFired),
396 1.5 mrg slot_mtx(MutexTypeSlots),
397 1.5 mrg resetting() {
398 1.1 mrg fired_suppressions.reserve(8);
399 1.5 mrg for (uptr i = 0; i < ARRAY_SIZE(slots); i++) {
400 1.5 mrg TidSlot* slot = &slots[i];
401 1.5 mrg slot->sid = static_cast<Sid>(i);
402 1.5 mrg slot_queue.PushBack(slot);
403 1.5 mrg }
404 1.5 mrg global_epoch = 1;
405 1.1 mrg }
406 1.1 mrg
407 1.5 mrg TidSlot::TidSlot() : mtx(MutexTypeSlot) {}
408 1.5 mrg
409 1.1 mrg // The objects are allocated in TLS, so one may rely on zero-initialization.
410 1.5 mrg ThreadState::ThreadState(Tid tid)
411 1.5 mrg // Do not touch these, rely on zero initialization,
412 1.5 mrg // they may be accessed before the ctor.
413 1.5 mrg // ignore_reads_and_writes()
414 1.5 mrg // ignore_interceptors()
415 1.5 mrg : tid(tid) {
416 1.3 mrg CHECK_EQ(reinterpret_cast<uptr>(this) % SANITIZER_CACHE_LINE_SIZE, 0);
417 1.3 mrg #if !SANITIZER_GO
418 1.5 mrg // C/C++ uses fixed size shadow stack.
419 1.5 mrg const int kInitStackSize = kShadowStackSize;
420 1.5 mrg shadow_stack = static_cast<uptr*>(
421 1.5 mrg MmapNoReserveOrDie(kInitStackSize * sizeof(uptr), "shadow stack"));
422 1.5 mrg SetShadowRegionHugePageMode(reinterpret_cast<uptr>(shadow_stack),
423 1.5 mrg kInitStackSize * sizeof(uptr));
424 1.3 mrg #else
425 1.5 mrg // Go uses malloc-allocated shadow stack with dynamic size.
426 1.3 mrg const int kInitStackSize = 8;
427 1.5 mrg shadow_stack = static_cast<uptr*>(Alloc(kInitStackSize * sizeof(uptr)));
428 1.5 mrg #endif
429 1.3 mrg shadow_stack_pos = shadow_stack;
430 1.3 mrg shadow_stack_end = shadow_stack + kInitStackSize;
431 1.1 mrg }
432 1.1 mrg
433 1.1 mrg #if !SANITIZER_GO
434 1.3 mrg void MemoryProfiler(u64 uptime) {
435 1.3 mrg if (ctx->memprof_fd == kInvalidFd)
436 1.3 mrg return;
437 1.1 mrg InternalMmapVector<char> buf(4096);
438 1.3 mrg WriteMemoryProfile(buf.data(), buf.size(), uptime);
439 1.3 mrg WriteToFile(ctx->memprof_fd, buf.data(), internal_strlen(buf.data()));
440 1.1 mrg }
441 1.1 mrg
442 1.5 mrg static bool InitializeMemoryProfiler() {
443 1.3 mrg ctx->memprof_fd = kInvalidFd;
444 1.3 mrg const char *fname = flags()->profile_memory;
445 1.3 mrg if (!fname || !fname[0])
446 1.5 mrg return false;
447 1.3 mrg if (internal_strcmp(fname, "stdout") == 0) {
448 1.3 mrg ctx->memprof_fd = 1;
449 1.3 mrg } else if (internal_strcmp(fname, "stderr") == 0) {
450 1.3 mrg ctx->memprof_fd = 2;
451 1.3 mrg } else {
452 1.3 mrg InternalScopedString filename;
453 1.5 mrg filename.AppendF("%s.%d", fname, (int)internal_getpid());
454 1.3 mrg ctx->memprof_fd = OpenFile(filename.data(), WrOnly);
455 1.3 mrg if (ctx->memprof_fd == kInvalidFd) {
456 1.3 mrg Printf("ThreadSanitizer: failed to open memory profile file '%s'\n",
457 1.3 mrg filename.data());
458 1.5 mrg return false;
459 1.3 mrg }
460 1.3 mrg }
461 1.3 mrg MemoryProfiler(0);
462 1.5 mrg return true;
463 1.3 mrg }
464 1.3 mrg
465 1.3 mrg static void *BackgroundThread(void *arg) {
466 1.1 mrg // This is a non-initialized non-user thread, nothing to see here.
467 1.1 mrg // We don't use ScopedIgnoreInterceptors, because we want ignores to be
468 1.1 mrg // enabled even when the thread function exits (e.g. during pthread thread
469 1.1 mrg // shutdown code).
470 1.3 mrg cur_thread_init()->ignore_interceptors++;
471 1.1 mrg const u64 kMs2Ns = 1000 * 1000;
472 1.3 mrg const u64 start = NanoTime();
473 1.1 mrg
474 1.5 mrg u64 last_flush = start;
475 1.1 mrg uptr last_rss = 0;
476 1.5 mrg while (!atomic_load_relaxed(&ctx->stop_background_thread)) {
477 1.1 mrg SleepForMillis(100);
478 1.1 mrg u64 now = NanoTime();
479 1.1 mrg
480 1.1 mrg // Flush memory if requested.
481 1.1 mrg if (flags()->flush_memory_ms > 0) {
482 1.1 mrg if (last_flush + flags()->flush_memory_ms * kMs2Ns < now) {
483 1.5 mrg VReport(1, "ThreadSanitizer: periodic memory flush\n");
484 1.1 mrg FlushShadowMemory();
485 1.5 mrg now = last_flush = NanoTime();
486 1.1 mrg }
487 1.1 mrg }
488 1.1 mrg if (flags()->memory_limit_mb > 0) {
489 1.1 mrg uptr rss = GetRSS();
490 1.1 mrg uptr limit = uptr(flags()->memory_limit_mb) << 20;
491 1.5 mrg VReport(1,
492 1.5 mrg "ThreadSanitizer: memory flush check"
493 1.5 mrg " RSS=%llu LAST=%llu LIMIT=%llu\n",
494 1.1 mrg (u64)rss >> 20, (u64)last_rss >> 20, (u64)limit >> 20);
495 1.1 mrg if (2 * rss > limit + last_rss) {
496 1.5 mrg VReport(1, "ThreadSanitizer: flushing memory due to RSS\n");
497 1.1 mrg FlushShadowMemory();
498 1.1 mrg rss = GetRSS();
499 1.5 mrg now = NanoTime();
500 1.5 mrg VReport(1, "ThreadSanitizer: memory flushed RSS=%llu\n",
501 1.5 mrg (u64)rss >> 20);
502 1.1 mrg }
503 1.1 mrg last_rss = rss;
504 1.1 mrg }
505 1.1 mrg
506 1.3 mrg MemoryProfiler(now - start);
507 1.1 mrg
508 1.1 mrg // Flush symbolizer cache if requested.
509 1.1 mrg if (flags()->flush_symbolizer_ms > 0) {
510 1.1 mrg u64 last = atomic_load(&ctx->last_symbolize_time_ns,
511 1.1 mrg memory_order_relaxed);
512 1.1 mrg if (last != 0 && last + flags()->flush_symbolizer_ms * kMs2Ns < now) {
513 1.1 mrg Lock l(&ctx->report_mtx);
514 1.1 mrg ScopedErrorReportLock l2;
515 1.1 mrg SymbolizeFlush();
516 1.1 mrg atomic_store(&ctx->last_symbolize_time_ns, 0, memory_order_relaxed);
517 1.1 mrg }
518 1.1 mrg }
519 1.1 mrg }
520 1.3 mrg return nullptr;
521 1.1 mrg }
522 1.1 mrg
523 1.1 mrg static void StartBackgroundThread() {
524 1.1 mrg ctx->background_thread = internal_start_thread(&BackgroundThread, 0);
525 1.1 mrg }
526 1.1 mrg
527 1.1 mrg #ifndef __mips__
528 1.1 mrg static void StopBackgroundThread() {
529 1.1 mrg atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed);
530 1.1 mrg internal_join_thread(ctx->background_thread);
531 1.1 mrg ctx->background_thread = 0;
532 1.1 mrg }
533 1.1 mrg #endif
534 1.1 mrg #endif
535 1.1 mrg
536 1.1 mrg void DontNeedShadowFor(uptr addr, uptr size) {
537 1.3 mrg ReleaseMemoryPagesToOS(reinterpret_cast<uptr>(MemToShadow(addr)),
538 1.3 mrg reinterpret_cast<uptr>(MemToShadow(addr + size)));
539 1.1 mrg }
540 1.1 mrg
541 1.1 mrg #if !SANITIZER_GO
542 1.5 mrg // We call UnmapShadow before the actual munmap, at that point we don't yet
543 1.5 mrg // know if the provided address/size are sane. We can't call UnmapShadow
544 1.5 mrg // after the actual munmap becuase at that point the memory range can
545 1.5 mrg // already be reused for something else, so we can't rely on the munmap
546 1.5 mrg // return value to understand is the values are sane.
547 1.5 mrg // While calling munmap with insane values (non-canonical address, negative
548 1.5 mrg // size, etc) is an error, the kernel won't crash. We must also try to not
549 1.5 mrg // crash as the failure mode is very confusing (paging fault inside of the
550 1.5 mrg // runtime on some derived shadow address).
551 1.5 mrg static bool IsValidMmapRange(uptr addr, uptr size) {
552 1.5 mrg if (size == 0)
553 1.5 mrg return true;
554 1.5 mrg if (static_cast<sptr>(size) < 0)
555 1.5 mrg return false;
556 1.5 mrg if (!IsAppMem(addr) || !IsAppMem(addr + size - 1))
557 1.5 mrg return false;
558 1.5 mrg // Check that if the start of the region belongs to one of app ranges,
559 1.5 mrg // end of the region belongs to the same region.
560 1.5 mrg const uptr ranges[][2] = {
561 1.5 mrg {LoAppMemBeg(), LoAppMemEnd()},
562 1.5 mrg {MidAppMemBeg(), MidAppMemEnd()},
563 1.5 mrg {HiAppMemBeg(), HiAppMemEnd()},
564 1.5 mrg };
565 1.5 mrg for (auto range : ranges) {
566 1.5 mrg if (addr >= range[0] && addr < range[1])
567 1.5 mrg return addr + size <= range[1];
568 1.5 mrg }
569 1.5 mrg return false;
570 1.5 mrg }
571 1.5 mrg
572 1.1 mrg void UnmapShadow(ThreadState *thr, uptr addr, uptr size) {
573 1.5 mrg if (size == 0 || !IsValidMmapRange(addr, size))
574 1.5 mrg return;
575 1.1 mrg DontNeedShadowFor(addr, size);
576 1.1 mrg ScopedGlobalProcessor sgp;
577 1.5 mrg SlotLocker locker(thr, true);
578 1.5 mrg ctx->metamap.ResetRange(thr->proc(), addr, size, true);
579 1.1 mrg }
580 1.1 mrg #endif
581 1.1 mrg
582 1.1 mrg void MapShadow(uptr addr, uptr size) {
583 1.5 mrg // Ensure thead registry lock held, so as to synchronize
584 1.5 mrg // with DoReset, which also access the mapped_shadow_* ctxt fields.
585 1.5 mrg ThreadRegistryLock lock0(&ctx->thread_registry);
586 1.5 mrg static bool data_mapped = false;
587 1.5 mrg
588 1.5 mrg #if !SANITIZER_GO
589 1.1 mrg // Global data is not 64K aligned, but there are no adjacent mappings,
590 1.1 mrg // so we can get away with unaligned mapping.
591 1.1 mrg // CHECK_EQ(addr, addr & ~((64 << 10) - 1)); // windows wants 64K alignment
592 1.1 mrg const uptr kPageSize = GetPageSizeCached();
593 1.1 mrg uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), kPageSize);
594 1.1 mrg uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), kPageSize);
595 1.5 mrg if (!MmapFixedNoReserve(shadow_begin, shadow_end - shadow_begin, "shadow"))
596 1.1 mrg Die();
597 1.5 mrg #else
598 1.5 mrg uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), (64 << 10));
599 1.5 mrg uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), (64 << 10));
600 1.5 mrg VPrintf(2, "MapShadow for (0x%zx-0x%zx), begin/end: (0x%zx-0x%zx)\n",
601 1.5 mrg addr, addr + size, shadow_begin, shadow_end);
602 1.5 mrg
603 1.5 mrg if (!data_mapped) {
604 1.5 mrg // First call maps data+bss.
605 1.5 mrg if (!MmapFixedSuperNoReserve(shadow_begin, shadow_end - shadow_begin, "shadow"))
606 1.5 mrg Die();
607 1.5 mrg } else {
608 1.5 mrg VPrintf(2, "ctx->mapped_shadow_{begin,end} = (0x%zx-0x%zx)\n",
609 1.5 mrg ctx->mapped_shadow_begin, ctx->mapped_shadow_end);
610 1.5 mrg // Second and subsequent calls map heap.
611 1.5 mrg if (shadow_end <= ctx->mapped_shadow_end)
612 1.5 mrg return;
613 1.5 mrg if (!ctx->mapped_shadow_begin || ctx->mapped_shadow_begin > shadow_begin)
614 1.5 mrg ctx->mapped_shadow_begin = shadow_begin;
615 1.5 mrg if (shadow_begin < ctx->mapped_shadow_end)
616 1.5 mrg shadow_begin = ctx->mapped_shadow_end;
617 1.5 mrg VPrintf(2, "MapShadow begin/end = (0x%zx-0x%zx)\n",
618 1.5 mrg shadow_begin, shadow_end);
619 1.5 mrg if (!MmapFixedSuperNoReserve(shadow_begin, shadow_end - shadow_begin,
620 1.5 mrg "shadow"))
621 1.5 mrg Die();
622 1.5 mrg ctx->mapped_shadow_end = shadow_end;
623 1.5 mrg }
624 1.5 mrg #endif
625 1.1 mrg
626 1.1 mrg // Meta shadow is 2:1, so tread carefully.
627 1.1 mrg static uptr mapped_meta_end = 0;
628 1.1 mrg uptr meta_begin = (uptr)MemToMeta(addr);
629 1.1 mrg uptr meta_end = (uptr)MemToMeta(addr + size);
630 1.1 mrg meta_begin = RoundDownTo(meta_begin, 64 << 10);
631 1.1 mrg meta_end = RoundUpTo(meta_end, 64 << 10);
632 1.1 mrg if (!data_mapped) {
633 1.1 mrg // First call maps data+bss.
634 1.1 mrg data_mapped = true;
635 1.3 mrg if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin,
636 1.3 mrg "meta shadow"))
637 1.1 mrg Die();
638 1.1 mrg } else {
639 1.3 mrg // Mapping continuous heap.
640 1.1 mrg // Windows wants 64K alignment.
641 1.1 mrg meta_begin = RoundDownTo(meta_begin, 64 << 10);
642 1.1 mrg meta_end = RoundUpTo(meta_end, 64 << 10);
643 1.5 mrg CHECK_GT(meta_end, mapped_meta_end);
644 1.1 mrg if (meta_begin < mapped_meta_end)
645 1.1 mrg meta_begin = mapped_meta_end;
646 1.3 mrg if (!MmapFixedSuperNoReserve(meta_begin, meta_end - meta_begin,
647 1.3 mrg "meta shadow"))
648 1.1 mrg Die();
649 1.1 mrg mapped_meta_end = meta_end;
650 1.1 mrg }
651 1.3 mrg VPrintf(2, "mapped meta shadow for (0x%zx-0x%zx) at (0x%zx-0x%zx)\n", addr,
652 1.3 mrg addr + size, meta_begin, meta_end);
653 1.1 mrg }
654 1.1 mrg
655 1.1 mrg #if !SANITIZER_GO
656 1.1 mrg static void OnStackUnwind(const SignalContext &sig, const void *,
657 1.1 mrg BufferedStackTrace *stack) {
658 1.1 mrg stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
659 1.1 mrg common_flags()->fast_unwind_on_fatal);
660 1.1 mrg }
661 1.1 mrg
662 1.1 mrg static void TsanOnDeadlySignal(int signo, void *siginfo, void *context) {
663 1.1 mrg HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr);
664 1.1 mrg }
665 1.1 mrg #endif
666 1.1 mrg
667 1.3 mrg void CheckUnwind() {
668 1.3 mrg // There is high probability that interceptors will check-fail as well,
669 1.3 mrg // on the other hand there is no sense in processing interceptors
670 1.3 mrg // since we are going to die soon.
671 1.3 mrg ScopedIgnoreInterceptors ignore;
672 1.3 mrg #if !SANITIZER_GO
673 1.5 mrg ThreadState* thr = cur_thread();
674 1.5 mrg thr->nomalloc = false;
675 1.5 mrg thr->ignore_sync++;
676 1.5 mrg thr->ignore_reads_and_writes++;
677 1.5 mrg atomic_store_relaxed(&thr->in_signal_handler, 0);
678 1.3 mrg #endif
679 1.3 mrg PrintCurrentStackSlow(StackTrace::GetCurrentPc());
680 1.3 mrg }
681 1.3 mrg
682 1.3 mrg bool is_initialized;
683 1.3 mrg
684 1.1 mrg void Initialize(ThreadState *thr) {
685 1.1 mrg // Thread safe because done before all threads exist.
686 1.1 mrg if (is_initialized)
687 1.1 mrg return;
688 1.1 mrg is_initialized = true;
689 1.1 mrg // We are not ready to handle interceptors yet.
690 1.1 mrg ScopedIgnoreInterceptors ignore;
691 1.1 mrg SanitizerToolName = "ThreadSanitizer";
692 1.1 mrg // Install tool-specific callbacks in sanitizer_common.
693 1.3 mrg SetCheckUnwindCallback(CheckUnwind);
694 1.1 mrg
695 1.4 riastrad ctx = new(reinterpret_cast<char *>((reinterpret_cast<uptr>(ctx_placeholder) + SANITIZER_CACHE_LINE_SIZE - 1) & ~static_cast<uptr>(SANITIZER_CACHE_LINE_SIZE - 1))) Context;
696 1.1 mrg const char *env_name = SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS";
697 1.1 mrg const char *options = GetEnv(env_name);
698 1.1 mrg CacheBinaryName();
699 1.1 mrg CheckASLR();
700 1.1 mrg InitializeFlags(&ctx->flags, options, env_name);
701 1.1 mrg AvoidCVE_2016_2143();
702 1.1 mrg __sanitizer::InitializePlatformEarly();
703 1.1 mrg __tsan::InitializePlatformEarly();
704 1.1 mrg
705 1.1 mrg #if !SANITIZER_GO
706 1.1 mrg InitializeAllocator();
707 1.1 mrg ReplaceSystemMalloc();
708 1.1 mrg #endif
709 1.1 mrg if (common_flags()->detect_deadlocks)
710 1.1 mrg ctx->dd = DDetector::Create(flags());
711 1.1 mrg Processor *proc = ProcCreate();
712 1.1 mrg ProcWire(proc, thr);
713 1.1 mrg InitializeInterceptors();
714 1.1 mrg InitializePlatform();
715 1.1 mrg InitializeDynamicAnnotations();
716 1.1 mrg #if !SANITIZER_GO
717 1.1 mrg InitializeShadowMemory();
718 1.1 mrg InitializeAllocatorLate();
719 1.1 mrg InstallDeadlySignalHandlers(TsanOnDeadlySignal);
720 1.1 mrg #endif
721 1.1 mrg // Setup correct file descriptor for error reports.
722 1.1 mrg __sanitizer_set_report_path(common_flags()->log_path);
723 1.1 mrg InitializeSuppressions();
724 1.1 mrg #if !SANITIZER_GO
725 1.1 mrg InitializeLibIgnore();
726 1.1 mrg Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer);
727 1.1 mrg #endif
728 1.1 mrg
729 1.5 mrg VPrintf(1, "***** Running under ThreadSanitizer v3 (pid %d) *****\n",
730 1.1 mrg (int)internal_getpid());
731 1.1 mrg
732 1.1 mrg // Initialize thread 0.
733 1.5 mrg Tid tid = ThreadCreate(nullptr, 0, 0, true);
734 1.3 mrg CHECK_EQ(tid, kMainTid);
735 1.1 mrg ThreadStart(thr, tid, GetTid(), ThreadType::Regular);
736 1.1 mrg #if TSAN_CONTAINS_UBSAN
737 1.1 mrg __ubsan::InitAsPlugin();
738 1.1 mrg #endif
739 1.1 mrg
740 1.1 mrg #if !SANITIZER_GO
741 1.1 mrg Symbolizer::LateInitialize();
742 1.5 mrg if (InitializeMemoryProfiler() || flags()->force_background_thread)
743 1.5 mrg MaybeSpawnBackgroundThread();
744 1.1 mrg #endif
745 1.5 mrg ctx->initialized = true;
746 1.1 mrg
747 1.1 mrg if (flags()->stop_on_start) {
748 1.1 mrg Printf("ThreadSanitizer is suspended at startup (pid %d)."
749 1.1 mrg " Call __tsan_resume().\n",
750 1.1 mrg (int)internal_getpid());
751 1.1 mrg while (__tsan_resumed == 0) {}
752 1.1 mrg }
753 1.1 mrg
754 1.1 mrg OnInitialize();
755 1.1 mrg }
756 1.1 mrg
757 1.1 mrg void MaybeSpawnBackgroundThread() {
758 1.1 mrg // On MIPS, TSan initialization is run before
759 1.1 mrg // __pthread_initialize_minimal_internal() is finished, so we can not spawn
760 1.1 mrg // new threads.
761 1.1 mrg #if !SANITIZER_GO && !defined(__mips__)
762 1.1 mrg static atomic_uint32_t bg_thread = {};
763 1.1 mrg if (atomic_load(&bg_thread, memory_order_relaxed) == 0 &&
764 1.1 mrg atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) {
765 1.1 mrg StartBackgroundThread();
766 1.1 mrg SetSandboxingCallback(StopBackgroundThread);
767 1.1 mrg }
768 1.1 mrg #endif
769 1.1 mrg }
770 1.1 mrg
771 1.1 mrg int Finalize(ThreadState *thr) {
772 1.1 mrg bool failed = false;
773 1.1 mrg
774 1.5 mrg #if !SANITIZER_GO
775 1.3 mrg if (common_flags()->print_module_map == 1)
776 1.3 mrg DumpProcessMap();
777 1.5 mrg #endif
778 1.1 mrg
779 1.1 mrg if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1)
780 1.5 mrg internal_usleep(u64(flags()->atexit_sleep_ms) * 1000);
781 1.1 mrg
782 1.5 mrg {
783 1.5 mrg // Wait for pending reports.
784 1.5 mrg ScopedErrorReportLock lock;
785 1.5 mrg }
786 1.1 mrg
787 1.1 mrg #if !SANITIZER_GO
788 1.1 mrg if (Verbosity()) AllocatorPrintStats();
789 1.1 mrg #endif
790 1.1 mrg
791 1.1 mrg ThreadFinalize(thr);
792 1.1 mrg
793 1.1 mrg if (ctx->nreported) {
794 1.1 mrg failed = true;
795 1.1 mrg #if !SANITIZER_GO
796 1.1 mrg Printf("ThreadSanitizer: reported %d warnings\n", ctx->nreported);
797 1.1 mrg #else
798 1.1 mrg Printf("Found %d data race(s)\n", ctx->nreported);
799 1.1 mrg #endif
800 1.1 mrg }
801 1.1 mrg
802 1.1 mrg if (common_flags()->print_suppressions)
803 1.1 mrg PrintMatchedSuppressions();
804 1.1 mrg
805 1.1 mrg failed = OnFinalize(failed);
806 1.1 mrg
807 1.1 mrg return failed ? common_flags()->exitcode : 0;
808 1.1 mrg }
809 1.1 mrg
810 1.1 mrg #if !SANITIZER_GO
811 1.5 mrg void ForkBefore(ThreadState* thr, uptr pc) SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
812 1.5 mrg GlobalProcessorLock();
813 1.5 mrg // Detaching from the slot makes OnUserFree skip writing to the shadow.
814 1.5 mrg // The slot will be locked so any attempts to use it will deadlock anyway.
815 1.5 mrg SlotDetach(thr);
816 1.5 mrg for (auto& slot : ctx->slots) slot.mtx.Lock();
817 1.3 mrg ctx->thread_registry.Lock();
818 1.5 mrg ctx->slot_mtx.Lock();
819 1.3 mrg ScopedErrorReportLock::Lock();
820 1.5 mrg AllocatorLock();
821 1.3 mrg // Suppress all reports in the pthread_atfork callbacks.
822 1.3 mrg // Reports will deadlock on the report_mtx.
823 1.3 mrg // We could ignore sync operations as well,
824 1.3 mrg // but so far it's unclear if it will do more good or harm.
825 1.3 mrg // Unnecessarily ignoring things can lead to false positives later.
826 1.3 mrg thr->suppress_reports++;
827 1.3 mrg // On OS X, REAL(fork) can call intercepted functions (OSSpinLockLock), and
828 1.3 mrg // we'll assert in CheckNoLocks() unless we ignore interceptors.
829 1.5 mrg // On OS X libSystem_atfork_prepare/parent/child callbacks are called
830 1.5 mrg // after/before our callbacks and they call free.
831 1.3 mrg thr->ignore_interceptors++;
832 1.5 mrg // Disables memory write in OnUserAlloc/Free.
833 1.5 mrg thr->ignore_reads_and_writes++;
834 1.5 mrg
835 1.5 mrg __tsan_test_only_on_fork();
836 1.3 mrg }
837 1.3 mrg
838 1.5 mrg static void ForkAfter(ThreadState* thr) SANITIZER_NO_THREAD_SAFETY_ANALYSIS {
839 1.3 mrg thr->suppress_reports--; // Enabled in ForkBefore.
840 1.3 mrg thr->ignore_interceptors--;
841 1.5 mrg thr->ignore_reads_and_writes--;
842 1.5 mrg AllocatorUnlock();
843 1.3 mrg ScopedErrorReportLock::Unlock();
844 1.5 mrg ctx->slot_mtx.Unlock();
845 1.3 mrg ctx->thread_registry.Unlock();
846 1.5 mrg for (auto& slot : ctx->slots) slot.mtx.Unlock();
847 1.5 mrg SlotAttachAndLock(thr);
848 1.5 mrg SlotUnlock(thr);
849 1.5 mrg GlobalProcessorUnlock();
850 1.1 mrg }
851 1.1 mrg
852 1.5 mrg void ForkParentAfter(ThreadState* thr, uptr pc) { ForkAfter(thr); }
853 1.5 mrg
854 1.5 mrg void ForkChildAfter(ThreadState* thr, uptr pc, bool start_thread) {
855 1.5 mrg ForkAfter(thr);
856 1.5 mrg u32 nthread = ctx->thread_registry.OnFork(thr->tid);
857 1.5 mrg VPrintf(1,
858 1.5 mrg "ThreadSanitizer: forked new process with pid %d,"
859 1.5 mrg " parent had %d threads\n",
860 1.5 mrg (int)internal_getpid(), (int)nthread);
861 1.1 mrg if (nthread == 1) {
862 1.3 mrg if (start_thread)
863 1.3 mrg StartBackgroundThread();
864 1.1 mrg } else {
865 1.1 mrg // We've just forked a multi-threaded process. We cannot reasonably function
866 1.1 mrg // after that (some mutexes may be locked before fork). So just enable
867 1.1 mrg // ignores for everything in the hope that we will exec soon.
868 1.1 mrg ctx->after_multithreaded_fork = true;
869 1.1 mrg thr->ignore_interceptors++;
870 1.5 mrg thr->suppress_reports++;
871 1.1 mrg ThreadIgnoreBegin(thr, pc);
872 1.1 mrg ThreadIgnoreSyncBegin(thr, pc);
873 1.1 mrg }
874 1.1 mrg }
875 1.1 mrg #endif
876 1.1 mrg
877 1.1 mrg #if SANITIZER_GO
878 1.1 mrg NOINLINE
879 1.1 mrg void GrowShadowStack(ThreadState *thr) {
880 1.1 mrg const int sz = thr->shadow_stack_end - thr->shadow_stack;
881 1.1 mrg const int newsz = 2 * sz;
882 1.3 mrg auto *newstack = (uptr *)Alloc(newsz * sizeof(uptr));
883 1.1 mrg internal_memcpy(newstack, thr->shadow_stack, sz * sizeof(uptr));
884 1.3 mrg Free(thr->shadow_stack);
885 1.1 mrg thr->shadow_stack = newstack;
886 1.1 mrg thr->shadow_stack_pos = newstack + sz;
887 1.1 mrg thr->shadow_stack_end = newstack + newsz;
888 1.1 mrg }
889 1.1 mrg #endif
890 1.1 mrg
891 1.3 mrg StackID CurrentStackId(ThreadState *thr, uptr pc) {
892 1.5 mrg #if !SANITIZER_GO
893 1.1 mrg if (!thr->is_inited) // May happen during bootstrap.
894 1.3 mrg return kInvalidStackID;
895 1.5 mrg #endif
896 1.1 mrg if (pc != 0) {
897 1.1 mrg #if !SANITIZER_GO
898 1.1 mrg DCHECK_LT(thr->shadow_stack_pos, thr->shadow_stack_end);
899 1.1 mrg #else
900 1.1 mrg if (thr->shadow_stack_pos == thr->shadow_stack_end)
901 1.1 mrg GrowShadowStack(thr);
902 1.1 mrg #endif
903 1.1 mrg thr->shadow_stack_pos[0] = pc;
904 1.1 mrg thr->shadow_stack_pos++;
905 1.1 mrg }
906 1.3 mrg StackID id = StackDepotPut(
907 1.1 mrg StackTrace(thr->shadow_stack, thr->shadow_stack_pos - thr->shadow_stack));
908 1.1 mrg if (pc != 0)
909 1.1 mrg thr->shadow_stack_pos--;
910 1.1 mrg return id;
911 1.1 mrg }
912 1.1 mrg
913 1.5 mrg static bool TraceSkipGap(ThreadState* thr) {
914 1.3 mrg Trace *trace = &thr->tctx->trace;
915 1.3 mrg Event *pos = reinterpret_cast<Event *>(atomic_load_relaxed(&thr->trace_pos));
916 1.3 mrg DCHECK_EQ(reinterpret_cast<uptr>(pos + 1) & TracePart::kAlignment, 0);
917 1.3 mrg auto *part = trace->parts.Back();
918 1.5 mrg DPrintf("#%d: TraceSwitchPart enter trace=%p parts=%p-%p pos=%p\n", thr->tid,
919 1.5 mrg trace, trace->parts.Front(), part, pos);
920 1.5 mrg if (!part)
921 1.5 mrg return false;
922 1.5 mrg // We can get here when we still have space in the current trace part.
923 1.5 mrg // The fast-path check in TraceAcquire has false positives in the middle of
924 1.5 mrg // the part. Check if we are indeed at the end of the current part or not,
925 1.5 mrg // and fill any gaps with NopEvent's.
926 1.5 mrg Event* end = &part->events[TracePart::kSize];
927 1.5 mrg DCHECK_GE(pos, &part->events[0]);
928 1.5 mrg DCHECK_LE(pos, end);
929 1.5 mrg if (pos + 1 < end) {
930 1.5 mrg if ((reinterpret_cast<uptr>(pos) & TracePart::kAlignment) ==
931 1.5 mrg TracePart::kAlignment)
932 1.3 mrg *pos++ = NopEvent;
933 1.5 mrg *pos++ = NopEvent;
934 1.5 mrg DCHECK_LE(pos + 2, end);
935 1.5 mrg atomic_store_relaxed(&thr->trace_pos, reinterpret_cast<uptr>(pos));
936 1.5 mrg return true;
937 1.3 mrg }
938 1.5 mrg // We are indeed at the end.
939 1.5 mrg for (; pos < end; pos++) *pos = NopEvent;
940 1.5 mrg return false;
941 1.5 mrg }
942 1.5 mrg
943 1.5 mrg NOINLINE
944 1.5 mrg void TraceSwitchPart(ThreadState* thr) {
945 1.5 mrg if (TraceSkipGap(thr))
946 1.5 mrg return;
947 1.3 mrg #if !SANITIZER_GO
948 1.3 mrg if (ctx->after_multithreaded_fork) {
949 1.3 mrg // We just need to survive till exec.
950 1.5 mrg TracePart* part = thr->tctx->trace.parts.Back();
951 1.5 mrg if (part) {
952 1.5 mrg atomic_store_relaxed(&thr->trace_pos,
953 1.5 mrg reinterpret_cast<uptr>(&part->events[0]));
954 1.5 mrg return;
955 1.5 mrg }
956 1.3 mrg }
957 1.3 mrg #endif
958 1.5 mrg TraceSwitchPartImpl(thr);
959 1.5 mrg }
960 1.5 mrg
961 1.5 mrg void TraceSwitchPartImpl(ThreadState* thr) {
962 1.5 mrg SlotLocker locker(thr, true);
963 1.5 mrg Trace* trace = &thr->tctx->trace;
964 1.5 mrg TracePart* part = TracePartAlloc(thr);
965 1.3 mrg part->trace = trace;
966 1.3 mrg thr->trace_prev_pc = 0;
967 1.5 mrg TracePart* recycle = nullptr;
968 1.5 mrg // Keep roughly half of parts local to the thread
969 1.5 mrg // (not queued into the recycle queue).
970 1.5 mrg uptr local_parts = (Trace::kMinParts + flags()->history_size + 1) / 2;
971 1.3 mrg {
972 1.3 mrg Lock lock(&trace->mtx);
973 1.5 mrg if (trace->parts.Empty())
974 1.5 mrg trace->local_head = part;
975 1.5 mrg if (trace->parts.Size() >= local_parts) {
976 1.5 mrg recycle = trace->local_head;
977 1.5 mrg trace->local_head = trace->parts.Next(recycle);
978 1.5 mrg }
979 1.3 mrg trace->parts.PushBack(part);
980 1.3 mrg atomic_store_relaxed(&thr->trace_pos,
981 1.3 mrg reinterpret_cast<uptr>(&part->events[0]));
982 1.3 mrg }
983 1.3 mrg // Make this part self-sufficient by restoring the current stack
984 1.3 mrg // and mutex set in the beginning of the trace.
985 1.3 mrg TraceTime(thr);
986 1.5 mrg {
987 1.5 mrg // Pathologically large stacks may not fit into the part.
988 1.5 mrg // In these cases we log only fixed number of top frames.
989 1.5 mrg const uptr kMaxFrames = 1000;
990 1.5 mrg // Check that kMaxFrames won't consume the whole part.
991 1.5 mrg static_assert(kMaxFrames < TracePart::kSize / 2, "kMaxFrames is too big");
992 1.5 mrg uptr* pos = Max(&thr->shadow_stack[0], thr->shadow_stack_pos - kMaxFrames);
993 1.5 mrg for (; pos < thr->shadow_stack_pos; pos++) {
994 1.5 mrg if (TryTraceFunc(thr, *pos))
995 1.5 mrg continue;
996 1.5 mrg CHECK(TraceSkipGap(thr));
997 1.5 mrg CHECK(TryTraceFunc(thr, *pos));
998 1.5 mrg }
999 1.5 mrg }
1000 1.3 mrg for (uptr i = 0; i < thr->mset.Size(); i++) {
1001 1.3 mrg MutexSet::Desc d = thr->mset.Get(i);
1002 1.5 mrg for (uptr i = 0; i < d.count; i++)
1003 1.5 mrg TraceMutexLock(thr, d.write ? EventType::kLock : EventType::kRLock, 0,
1004 1.5 mrg d.addr, d.stack_id);
1005 1.5 mrg }
1006 1.5 mrg // Callers of TraceSwitchPart expect that TraceAcquire will always succeed
1007 1.5 mrg // after the call. It's possible that TryTraceFunc/TraceMutexLock above
1008 1.5 mrg // filled the trace part exactly up to the TracePart::kAlignment gap
1009 1.5 mrg // and the next TraceAcquire won't succeed. Skip the gap to avoid that.
1010 1.5 mrg EventFunc *ev;
1011 1.5 mrg if (!TraceAcquire(thr, &ev)) {
1012 1.5 mrg CHECK(TraceSkipGap(thr));
1013 1.5 mrg CHECK(TraceAcquire(thr, &ev));
1014 1.3 mrg }
1015 1.5 mrg {
1016 1.5 mrg Lock lock(&ctx->slot_mtx);
1017 1.5 mrg // There is a small chance that the slot may be not queued at this point.
1018 1.5 mrg // This can happen if the slot has kEpochLast epoch and another thread
1019 1.5 mrg // in FindSlotAndLock discovered that it's exhausted and removed it from
1020 1.5 mrg // the slot queue. kEpochLast can happen in 2 cases: (1) if TraceSwitchPart
1021 1.5 mrg // was called with the slot locked and epoch already at kEpochLast,
1022 1.5 mrg // or (2) if we've acquired a new slot in SlotLock in the beginning
1023 1.5 mrg // of the function and the slot was at kEpochLast - 1, so after increment
1024 1.5 mrg // in SlotAttachAndLock it become kEpochLast.
1025 1.5 mrg if (ctx->slot_queue.Queued(thr->slot)) {
1026 1.5 mrg ctx->slot_queue.Remove(thr->slot);
1027 1.5 mrg ctx->slot_queue.PushBack(thr->slot);
1028 1.5 mrg }
1029 1.5 mrg if (recycle)
1030 1.5 mrg ctx->trace_part_recycle.PushBack(recycle);
1031 1.5 mrg }
1032 1.5 mrg DPrintf("#%d: TraceSwitchPart exit parts=%p-%p pos=0x%zx\n", thr->tid,
1033 1.5 mrg trace->parts.Front(), trace->parts.Back(),
1034 1.5 mrg atomic_load_relaxed(&thr->trace_pos));
1035 1.3 mrg }
1036 1.3 mrg
1037 1.5 mrg void ThreadIgnoreBegin(ThreadState* thr, uptr pc) {
1038 1.1 mrg DPrintf("#%d: ThreadIgnoreBegin\n", thr->tid);
1039 1.1 mrg thr->ignore_reads_and_writes++;
1040 1.1 mrg CHECK_GT(thr->ignore_reads_and_writes, 0);
1041 1.1 mrg thr->fast_state.SetIgnoreBit();
1042 1.1 mrg #if !SANITIZER_GO
1043 1.3 mrg if (pc && !ctx->after_multithreaded_fork)
1044 1.1 mrg thr->mop_ignore_set.Add(CurrentStackId(thr, pc));
1045 1.1 mrg #endif
1046 1.1 mrg }
1047 1.1 mrg
1048 1.3 mrg void ThreadIgnoreEnd(ThreadState *thr) {
1049 1.1 mrg DPrintf("#%d: ThreadIgnoreEnd\n", thr->tid);
1050 1.1 mrg CHECK_GT(thr->ignore_reads_and_writes, 0);
1051 1.1 mrg thr->ignore_reads_and_writes--;
1052 1.1 mrg if (thr->ignore_reads_and_writes == 0) {
1053 1.1 mrg thr->fast_state.ClearIgnoreBit();
1054 1.1 mrg #if !SANITIZER_GO
1055 1.1 mrg thr->mop_ignore_set.Reset();
1056 1.1 mrg #endif
1057 1.1 mrg }
1058 1.1 mrg }
1059 1.1 mrg
1060 1.1 mrg #if !SANITIZER_GO
1061 1.1 mrg extern "C" SANITIZER_INTERFACE_ATTRIBUTE
1062 1.1 mrg uptr __tsan_testonly_shadow_stack_current_size() {
1063 1.1 mrg ThreadState *thr = cur_thread();
1064 1.1 mrg return thr->shadow_stack_pos - thr->shadow_stack;
1065 1.1 mrg }
1066 1.1 mrg #endif
1067 1.1 mrg
1068 1.3 mrg void ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc) {
1069 1.1 mrg DPrintf("#%d: ThreadIgnoreSyncBegin\n", thr->tid);
1070 1.1 mrg thr->ignore_sync++;
1071 1.1 mrg CHECK_GT(thr->ignore_sync, 0);
1072 1.1 mrg #if !SANITIZER_GO
1073 1.3 mrg if (pc && !ctx->after_multithreaded_fork)
1074 1.1 mrg thr->sync_ignore_set.Add(CurrentStackId(thr, pc));
1075 1.1 mrg #endif
1076 1.1 mrg }
1077 1.1 mrg
1078 1.3 mrg void ThreadIgnoreSyncEnd(ThreadState *thr) {
1079 1.1 mrg DPrintf("#%d: ThreadIgnoreSyncEnd\n", thr->tid);
1080 1.1 mrg CHECK_GT(thr->ignore_sync, 0);
1081 1.1 mrg thr->ignore_sync--;
1082 1.1 mrg #if !SANITIZER_GO
1083 1.1 mrg if (thr->ignore_sync == 0)
1084 1.1 mrg thr->sync_ignore_set.Reset();
1085 1.1 mrg #endif
1086 1.1 mrg }
1087 1.1 mrg
1088 1.1 mrg bool MD5Hash::operator==(const MD5Hash &other) const {
1089 1.1 mrg return hash[0] == other.hash[0] && hash[1] == other.hash[1];
1090 1.1 mrg }
1091 1.1 mrg
1092 1.1 mrg #if SANITIZER_DEBUG
1093 1.1 mrg void build_consistency_debug() {}
1094 1.1 mrg #else
1095 1.1 mrg void build_consistency_release() {}
1096 1.1 mrg #endif
1097 1.3 mrg } // namespace __tsan
1098 1.1 mrg
1099 1.3 mrg #if SANITIZER_CHECK_DEADLOCKS
1100 1.3 mrg namespace __sanitizer {
1101 1.3 mrg using namespace __tsan;
1102 1.3 mrg MutexMeta mutex_meta[] = {
1103 1.3 mrg {MutexInvalid, "Invalid", {}},
1104 1.5 mrg {MutexThreadRegistry,
1105 1.5 mrg "ThreadRegistry",
1106 1.5 mrg {MutexTypeSlots, MutexTypeTrace, MutexTypeReport}},
1107 1.5 mrg {MutexTypeReport, "Report", {MutexTypeTrace}},
1108 1.5 mrg {MutexTypeSyncVar, "SyncVar", {MutexTypeReport, MutexTypeTrace}},
1109 1.3 mrg {MutexTypeAnnotations, "Annotations", {}},
1110 1.5 mrg {MutexTypeAtExit, "AtExit", {}},
1111 1.3 mrg {MutexTypeFired, "Fired", {MutexLeaf}},
1112 1.3 mrg {MutexTypeRacy, "Racy", {MutexLeaf}},
1113 1.5 mrg {MutexTypeGlobalProc, "GlobalProc", {MutexTypeSlot, MutexTypeSlots}},
1114 1.5 mrg {MutexTypeInternalAlloc, "InternalAlloc", {MutexLeaf}},
1115 1.5 mrg {MutexTypeTrace, "Trace", {}},
1116 1.5 mrg {MutexTypeSlot,
1117 1.5 mrg "Slot",
1118 1.5 mrg {MutexMulti, MutexTypeTrace, MutexTypeSyncVar, MutexThreadRegistry,
1119 1.5 mrg MutexTypeSlots}},
1120 1.5 mrg {MutexTypeSlots, "Slots", {MutexTypeTrace, MutexTypeReport}},
1121 1.3 mrg {},
1122 1.3 mrg };
1123 1.1 mrg
1124 1.3 mrg void PrintMutexPC(uptr pc) { StackTrace(&pc, 1).Print(); }
1125 1.5 mrg
1126 1.3 mrg } // namespace __sanitizer
1127 1.1 mrg #endif
1128