brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · ae1590b Raw
127 lines · cpp
1//=-- lsan_posix.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-exception6//7//===---------------------------------------------------------------------===//8//9// This file is a part of LeakSanitizer.10// Standalone LSan RTL code common to POSIX-like systems.11//12//===---------------------------------------------------------------------===//13 14#include "sanitizer_common/sanitizer_platform.h"15 16#if SANITIZER_POSIX17#  include <pthread.h>18 19#  include "lsan.h"20#  include "lsan_allocator.h"21#  include "lsan_thread.h"22#  include "sanitizer_common/sanitizer_stacktrace.h"23#  include "sanitizer_common/sanitizer_tls_get_addr.h"24 25namespace __lsan {26 27ThreadContext::ThreadContext(int tid) : ThreadContextLsanBase(tid) {}28 29struct OnStartedArgs {30  uptr stack_begin;31  uptr stack_end;32  uptr cache_begin;33  uptr cache_end;34  uptr tls_begin;35  uptr tls_end;36  DTLS *dtls;37};38 39void ThreadContext::OnStarted(void *arg) {40  ThreadContextLsanBase::OnStarted(arg);41  auto args = reinterpret_cast<const OnStartedArgs *>(arg);42  stack_begin_ = args->stack_begin;43  stack_end_ = args->stack_end;44  tls_begin_ = args->tls_begin;45  tls_end_ = args->tls_end;46  cache_begin_ = args->cache_begin;47  cache_end_ = args->cache_end;48  dtls_ = args->dtls;49}50 51void ThreadStart(u32 tid, ThreadID os_id, ThreadType thread_type) {52  OnStartedArgs args;53  GetThreadStackAndTls(tid == kMainTid, &args.stack_begin, &args.stack_end,54                       &args.tls_begin, &args.tls_end);55  GetAllocatorCacheRange(&args.cache_begin, &args.cache_end);56  args.dtls = DTLS_Get();57  ThreadContextLsanBase::ThreadStart(tid, os_id, thread_type, &args);58}59 60bool GetThreadRangesLocked(ThreadID os_id, uptr *stack_begin, uptr *stack_end,61                           uptr *tls_begin, uptr *tls_end, uptr *cache_begin,62                           uptr *cache_end, DTLS **dtls) {63  ThreadContext *context = static_cast<ThreadContext *>(64      GetLsanThreadRegistryLocked()->FindThreadContextByOsIDLocked(os_id));65  if (!context)66    return false;67  *stack_begin = context->stack_begin();68  *stack_end = context->stack_end();69  *tls_begin = context->tls_begin();70  *tls_end = context->tls_end();71  *cache_begin = context->cache_begin();72  *cache_end = context->cache_end();73  *dtls = context->dtls();74  return true;75}76 77void InitializeMainThread() {78  u32 tid = ThreadCreate(kMainTid, true);79  CHECK_EQ(tid, kMainTid);80  ThreadStart(tid, GetTid());81}82 83static void OnStackUnwind(const SignalContext &sig, const void *,84                          BufferedStackTrace *stack) {85  stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,86                common_flags()->fast_unwind_on_fatal);87}88 89void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {90  HandleDeadlySignal(siginfo, context, GetCurrentThreadId(), &OnStackUnwind,91                     nullptr);92}93 94void InstallAtExitCheckLeaks() {95  if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit)96    Atexit(DoLeakCheck);97}98 99static void BeforeFork() {100  VReport(2, "BeforeFork tid: %llu\n", GetTid());101  LockGlobal();102  LockThreads();103  LockAllocator();104  StackDepotLockBeforeFork();105}106 107static void AfterFork(bool fork_child) {108  StackDepotUnlockAfterFork(fork_child);109  UnlockAllocator();110  UnlockThreads();111  UnlockGlobal();112  VReport(2, "AfterFork tid: %llu\n", GetTid());113}114 115void InstallAtForkHandler() {116#  if SANITIZER_SOLARIS || SANITIZER_NETBSD || SANITIZER_APPLE117  return;  // FIXME: Implement FutexWait.118#  endif119  pthread_atfork(120      &BeforeFork, []() { AfterFork(/* fork_child= */ false); },121      []() { AfterFork(/* fork_child= */ true); });122}123 124}  // namespace __lsan125 126#endif  // SANITIZER_POSIX127