llvm-project

Форк
0
/
lsan_fuchsia.cpp 
131 строка · 4.6 Кб
1
//=-- lsan_fuchsia.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 LeakSanitizer.
10
// Standalone LSan RTL code specific to Fuchsia.
11
//
12
//===---------------------------------------------------------------------===//
13

14
#include "sanitizer_common/sanitizer_platform.h"
15

16
#if SANITIZER_FUCHSIA
17
#include <zircon/sanitizer.h>
18

19
#include "lsan.h"
20
#include "lsan_allocator.h"
21

22
using namespace __lsan;
23

24
namespace __lsan {
25

26
void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {}
27

28
ThreadContext::ThreadContext(int tid) : ThreadContextLsanBase(tid) {}
29

30
struct OnCreatedArgs {
31
  uptr stack_begin, stack_end;
32
};
33

34
// On Fuchsia, the stack bounds of a new thread are available before
35
// the thread itself has started running.
36
void ThreadContext::OnCreated(void *arg) {
37
  // Stack bounds passed through from __sanitizer_before_thread_create_hook
38
  // or InitializeMainThread.
39
  auto args = reinterpret_cast<const OnCreatedArgs *>(arg);
40
  stack_begin_ = args->stack_begin;
41
  stack_end_ = args->stack_end;
42
}
43

44
struct OnStartedArgs {
45
  uptr cache_begin, cache_end;
46
};
47

48
void ThreadContext::OnStarted(void *arg) {
49
  ThreadContextLsanBase::OnStarted(arg);
50
  auto args = reinterpret_cast<const OnStartedArgs *>(arg);
51
  cache_begin_ = args->cache_begin;
52
  cache_end_ = args->cache_end;
53
}
54

55
void ThreadStart(u32 tid) {
56
  OnStartedArgs args;
57
  GetAllocatorCacheRange(&args.cache_begin, &args.cache_end);
58
  CHECK_EQ(args.cache_end - args.cache_begin, sizeof(AllocatorCache));
59
  ThreadContextLsanBase::ThreadStart(tid, GetTid(), ThreadType::Regular, &args);
60
}
61

62
void InitializeMainThread() {
63
  OnCreatedArgs args;
64
  __sanitizer::GetThreadStackTopAndBottom(true, &args.stack_end,
65
                                          &args.stack_begin);
66
  u32 tid = ThreadCreate(kMainTid, true, &args);
67
  CHECK_EQ(tid, 0);
68
  ThreadStart(tid);
69
}
70

71
void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches) {
72
  GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked(
73
      [](ThreadContextBase *tctx, void *arg) {
74
        auto ctx = static_cast<ThreadContext *>(tctx);
75
        static_cast<decltype(caches)>(arg)->push_back(ctx->cache_begin());
76
      },
77
      caches);
78
}
79

80
// On Fuchsia, leak detection is done by a special hook after atexit hooks.
81
// So this doesn't install any atexit hook like on other platforms.
82
void InstallAtExitCheckLeaks() {}
83
void InstallAtForkHandler() {}
84

85
// ASan defines this to check its `halt_on_error` flag.
86
bool UseExitcodeOnLeak() { return true; }
87

88
}  // namespace __lsan
89

90
// These are declared (in extern "C") by <zircon/sanitizer.h>.
91
// The system runtime will call our definitions directly.
92

93
// This is called before each thread creation is attempted.  So, in
94
// its first call, the calling thread is the initial and sole thread.
95
void *__sanitizer_before_thread_create_hook(thrd_t thread, bool detached,
96
                                            const char *name, void *stack_base,
97
                                            size_t stack_size) {
98
  ENSURE_LSAN_INITED;
99
  EnsureMainThreadIDIsCorrect();
100
  OnCreatedArgs args;
101
  args.stack_begin = reinterpret_cast<uptr>(stack_base);
102
  args.stack_end = args.stack_begin + stack_size;
103
  u32 parent_tid = GetCurrentThreadId();
104
  u32 tid = ThreadCreate(parent_tid, detached, &args);
105
  return reinterpret_cast<void *>(static_cast<uptr>(tid));
106
}
107

108
// This is called after creating a new thread (in the creating thread),
109
// with the pointer returned by __sanitizer_before_thread_create_hook (above).
110
void __sanitizer_thread_create_hook(void *hook, thrd_t thread, int error) {
111
  u32 tid = static_cast<u32>(reinterpret_cast<uptr>(hook));
112
  // On success, there is nothing to do here.
113
  if (error != thrd_success) {
114
    // Clean up the thread registry for the thread creation that didn't happen.
115
    GetLsanThreadRegistryLocked()->FinishThread(tid);
116
  }
117
}
118

119
// This is called in the newly-created thread before it runs anything else,
120
// with the pointer returned by __sanitizer_before_thread_create_hook (above).
121
void __sanitizer_thread_start_hook(void *hook, thrd_t self) {
122
  u32 tid = static_cast<u32>(reinterpret_cast<uptr>(hook));
123
  ThreadStart(tid);
124
}
125

126
// Each thread runs this just before it exits,
127
// with the pointer returned by BeforeThreadCreateHook (above).
128
// All per-thread destructors have already been called.
129
void __sanitizer_thread_exit_hook(void *hook, thrd_t self) { ThreadFinish(); }
130

131
#endif  // SANITIZER_FUCHSIA
132

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.