lsan.cpp revision 360784
1//=-- lsan.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.
11//
12//===----------------------------------------------------------------------===//
13
14#include "lsan.h"
15
16#include "sanitizer_common/sanitizer_flags.h"
17#include "sanitizer_common/sanitizer_flag_parser.h"
18#include "sanitizer_common/sanitizer_stacktrace.h"
19#include "lsan_allocator.h"
20#include "lsan_common.h"
21#include "lsan_thread.h"
22
23bool lsan_inited;
24bool lsan_init_is_running;
25
26namespace __lsan {
27
28///// Interface to the common LSan module. /////
29bool WordIsPoisoned(uptr addr) {
30  return false;
31}
32
33}  // namespace __lsan
34
35void __sanitizer::BufferedStackTrace::UnwindImpl(
36    uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
37  using namespace __lsan;
38  uptr stack_top = 0, stack_bottom = 0;
39  ThreadContext *t;
40  if (StackTrace::WillUseFastUnwind(request_fast) &&
41      (t = CurrentThreadContext())) {
42    stack_top = t->stack_end();
43    stack_bottom = t->stack_begin();
44  }
45  if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
46    if (StackTrace::WillUseFastUnwind(request_fast))
47      Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
48    else
49      Unwind(max_depth, pc, 0, context, 0, 0, false);
50  }
51}
52
53using namespace __lsan;
54
55static void InitializeFlags() {
56  // Set all the default values.
57  SetCommonFlagsDefaults();
58  {
59    CommonFlags cf;
60    cf.CopyFrom(*common_flags());
61    cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
62    cf.malloc_context_size = 30;
63    cf.intercept_tls_get_addr = true;
64    cf.detect_leaks = true;
65    cf.exitcode = 23;
66    OverrideCommonFlags(cf);
67  }
68
69  Flags *f = flags();
70  f->SetDefaults();
71
72  FlagParser parser;
73  RegisterLsanFlags(&parser, f);
74  RegisterCommonFlags(&parser);
75
76  // Override from user-specified string.
77  const char *lsan_default_options = MaybeCallLsanDefaultOptions();
78  parser.ParseString(lsan_default_options);
79  parser.ParseStringFromEnv("LSAN_OPTIONS");
80
81  SetVerbosity(common_flags()->verbosity);
82
83  if (Verbosity()) ReportUnrecognizedFlags();
84
85  if (common_flags()->help) parser.PrintFlagDescriptions();
86
87  __sanitizer_set_report_path(common_flags()->log_path);
88}
89
90static void OnStackUnwind(const SignalContext &sig, const void *,
91                          BufferedStackTrace *stack) {
92  stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
93                common_flags()->fast_unwind_on_fatal);
94}
95
96static void LsanOnDeadlySignal(int signo, void *siginfo, void *context) {
97  HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind,
98                     nullptr);
99}
100
101extern "C" void __lsan_init() {
102  CHECK(!lsan_init_is_running);
103  if (lsan_inited)
104    return;
105  lsan_init_is_running = true;
106  SanitizerToolName = "LeakSanitizer";
107  CacheBinaryName();
108  AvoidCVE_2016_2143();
109  InitializeFlags();
110  InitCommonLsan();
111  InitializeAllocator();
112  ReplaceSystemMalloc();
113  InitTlsSize();
114  InitializeInterceptors();
115  InitializeThreadRegistry();
116  InstallDeadlySignalHandlers(LsanOnDeadlySignal);
117  u32 tid = ThreadCreate(0, 0, true);
118  CHECK_EQ(tid, 0);
119  ThreadStart(tid, GetTid());
120  SetCurrentThread(tid);
121
122  if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit)
123    Atexit(DoLeakCheck);
124
125  InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
126
127  lsan_inited = true;
128  lsan_init_is_running = false;
129}
130
131extern "C" SANITIZER_INTERFACE_ATTRIBUTE
132void __sanitizer_print_stack_trace() {
133  GET_STACK_TRACE_FATAL;
134  stack.Print();
135}
136