xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/rtsan/rtsan_stack.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===--- rtsan_stack.cpp - Realtime Sanitizer -------------------*- C++ -*-===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
10*0fca6ea1SDimitry Andric 
11*0fca6ea1SDimitry Andric #include "rtsan_stack.h"
12*0fca6ea1SDimitry Andric 
13*0fca6ea1SDimitry Andric #include <sanitizer_common/sanitizer_flags.h>
14*0fca6ea1SDimitry Andric #include <sanitizer_common/sanitizer_stacktrace.h>
15*0fca6ea1SDimitry Andric 
16*0fca6ea1SDimitry Andric using namespace __sanitizer;
17*0fca6ea1SDimitry Andric using namespace __rtsan;
18*0fca6ea1SDimitry Andric 
19*0fca6ea1SDimitry Andric // We must define our own implementation of this method for our runtime.
20*0fca6ea1SDimitry Andric // This one is just copied from UBSan.
21*0fca6ea1SDimitry Andric namespace __sanitizer {
22*0fca6ea1SDimitry Andric void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context,
23*0fca6ea1SDimitry Andric                                     bool request_fast, u32 max_depth) {
24*0fca6ea1SDimitry Andric   uptr top = 0;
25*0fca6ea1SDimitry Andric   uptr bottom = 0;
26*0fca6ea1SDimitry Andric   GetThreadStackTopAndBottom(false, &top, &bottom);
27*0fca6ea1SDimitry Andric   bool fast = StackTrace::WillUseFastUnwind(request_fast);
28*0fca6ea1SDimitry Andric   Unwind(max_depth, pc, bp, context, top, bottom, fast);
29*0fca6ea1SDimitry Andric }
30*0fca6ea1SDimitry Andric } // namespace __sanitizer
31*0fca6ea1SDimitry Andric 
32*0fca6ea1SDimitry Andric static void SetGlobalStackTraceFormat() {
33*0fca6ea1SDimitry Andric   SetCommonFlagsDefaults();
34*0fca6ea1SDimitry Andric   CommonFlags cf;
35*0fca6ea1SDimitry Andric   cf.CopyFrom(*common_flags());
36*0fca6ea1SDimitry Andric   cf.stack_trace_format = "DEFAULT";
37*0fca6ea1SDimitry Andric   cf.external_symbolizer_path = GetEnv("RTSAN_SYMBOLIZER_PATH");
38*0fca6ea1SDimitry Andric   OverrideCommonFlags(cf);
39*0fca6ea1SDimitry Andric }
40*0fca6ea1SDimitry Andric 
41*0fca6ea1SDimitry Andric void __rtsan::PrintStackTrace() {
42*0fca6ea1SDimitry Andric 
43*0fca6ea1SDimitry Andric   BufferedStackTrace stack{};
44*0fca6ea1SDimitry Andric 
45*0fca6ea1SDimitry Andric   GET_CURRENT_PC_BP;
46*0fca6ea1SDimitry Andric   stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal);
47*0fca6ea1SDimitry Andric 
48*0fca6ea1SDimitry Andric   SetGlobalStackTraceFormat();
49*0fca6ea1SDimitry Andric   stack.Print();
50*0fca6ea1SDimitry Andric }
51