1217222abSNico Weber //===-- asan_stack.cpp ----------------------------------------------------===//
2217222abSNico Weber //
3217222abSNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4217222abSNico Weber // See https://llvm.org/LICENSE.txt for license information.
5217222abSNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6217222abSNico Weber //
7217222abSNico Weber //===----------------------------------------------------------------------===//
8217222abSNico Weber //
9217222abSNico Weber // This file is a part of AddressSanitizer, an address sanity checker.
10217222abSNico Weber //
11217222abSNico Weber // Code for ASan stack trace.
12217222abSNico Weber //===----------------------------------------------------------------------===//
13217222abSNico Weber #include "asan_internal.h"
14217222abSNico Weber #include "asan_stack.h"
15217222abSNico Weber #include "sanitizer_common/sanitizer_atomic.h"
16217222abSNico Weber
17217222abSNico Weber namespace __asan {
18217222abSNico Weber
19217222abSNico Weber static atomic_uint32_t malloc_context_size;
20217222abSNico Weber
SetMallocContextSize(u32 size)21217222abSNico Weber void SetMallocContextSize(u32 size) {
22217222abSNico Weber atomic_store(&malloc_context_size, size, memory_order_release);
23217222abSNico Weber }
24217222abSNico Weber
GetMallocContextSize()25217222abSNico Weber u32 GetMallocContextSize() {
26217222abSNico Weber return atomic_load(&malloc_context_size, memory_order_acquire);
27217222abSNico Weber }
28217222abSNico Weber
29217222abSNico Weber namespace {
30217222abSNico Weber
31217222abSNico Weber // ScopedUnwinding is a scope for stacktracing member of a context
32217222abSNico Weber class ScopedUnwinding {
33217222abSNico Weber public:
ScopedUnwinding(AsanThread * t)34217222abSNico Weber explicit ScopedUnwinding(AsanThread *t) : thread(t) {
35217222abSNico Weber if (thread) {
36217222abSNico Weber can_unwind = !thread->isUnwinding();
37217222abSNico Weber thread->setUnwinding(true);
38217222abSNico Weber }
39217222abSNico Weber }
~ScopedUnwinding()40217222abSNico Weber ~ScopedUnwinding() {
41217222abSNico Weber if (thread)
42217222abSNico Weber thread->setUnwinding(false);
43217222abSNico Weber }
44217222abSNico Weber
CanUnwind() const45217222abSNico Weber bool CanUnwind() const { return can_unwind; }
46217222abSNico Weber
47217222abSNico Weber private:
48217222abSNico Weber AsanThread *thread = nullptr;
49217222abSNico Weber bool can_unwind = true;
50217222abSNico Weber };
51217222abSNico Weber
52217222abSNico Weber } // namespace
53217222abSNico Weber
54217222abSNico Weber } // namespace __asan
55217222abSNico Weber
UnwindImpl(uptr pc,uptr bp,void * context,bool request_fast,u32 max_depth)56217222abSNico Weber void __sanitizer::BufferedStackTrace::UnwindImpl(
57217222abSNico Weber uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
58217222abSNico Weber using namespace __asan;
59217222abSNico Weber size = 0;
60*5d6304f0SZachary Johnson if (UNLIKELY(!AsanInited()))
61217222abSNico Weber return;
62217222abSNico Weber request_fast = StackTrace::WillUseFastUnwind(request_fast);
63217222abSNico Weber AsanThread *t = GetCurrentThread();
64217222abSNico Weber ScopedUnwinding unwind_scope(t);
65217222abSNico Weber if (!unwind_scope.CanUnwind())
66217222abSNico Weber return;
67217222abSNico Weber if (request_fast) {
68217222abSNico Weber if (t) {
69217222abSNico Weber Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
70217222abSNico Weber true);
71217222abSNico Weber }
72217222abSNico Weber return;
73217222abSNico Weber }
74217222abSNico Weber if (SANITIZER_MIPS && t &&
75217222abSNico Weber !IsValidFrame(bp, t->stack_top(), t->stack_bottom()))
76217222abSNico Weber return;
77261d6e05SFangrui Song Unwind(max_depth, pc, bp, context, t ? t->stack_top() : 0,
78261d6e05SFangrui Song t ? t->stack_bottom() : 0, false);
79217222abSNico Weber }
80217222abSNico Weber
81217222abSNico Weber // ------------------ Interface -------------- {{{1
82217222abSNico Weber
83217222abSNico Weber extern "C" {
84217222abSNico Weber SANITIZER_INTERFACE_ATTRIBUTE
__sanitizer_print_stack_trace()85217222abSNico Weber void __sanitizer_print_stack_trace() {
86217222abSNico Weber using namespace __asan;
87217222abSNico Weber PRINT_CURRENT_STACK();
88217222abSNico Weber }
89217222abSNico Weber } // extern "C"
90