1//===-- asan_stack.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 AddressSanitizer, an address sanity checker. 10// 11// Code for ASan stack trace. 12//===----------------------------------------------------------------------===// 13#include "asan_internal.h" 14#include "asan_stack.h" 15#include "sanitizer_common/sanitizer_atomic.h" 16 17namespace __asan { 18 19static atomic_uint32_t malloc_context_size; 20 21void SetMallocContextSize(u32 size) { 22 atomic_store(&malloc_context_size, size, memory_order_release); 23} 24 25u32 GetMallocContextSize() { 26 return atomic_load(&malloc_context_size, memory_order_acquire); 27} 28 29namespace { 30 31// ScopedUnwinding is a scope for stacktracing member of a context 32class ScopedUnwinding { 33 public: 34 explicit ScopedUnwinding(AsanThread *t) : thread(t) { 35 if (thread) { 36 can_unwind = !thread->isUnwinding(); 37 thread->setUnwinding(true); 38 } 39 } 40 ~ScopedUnwinding() { 41 if (thread) 42 thread->setUnwinding(false); 43 } 44 45 bool CanUnwind() const { return can_unwind; } 46 47 private: 48 AsanThread *thread = nullptr; 49 bool can_unwind = true; 50}; 51 52} // namespace 53 54} // namespace __asan 55 56void __sanitizer::BufferedStackTrace::UnwindImpl( 57 uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { 58 using namespace __asan; 59 size = 0; 60 if (UNLIKELY(!asan_inited)) 61 return; 62 request_fast = StackTrace::WillUseFastUnwind(request_fast); 63 AsanThread *t = GetCurrentThread(); 64 ScopedUnwinding unwind_scope(t); 65 if (!unwind_scope.CanUnwind()) 66 return; 67 if (request_fast) { 68 if (t) { 69 Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), 70 true); 71 } 72 return; 73 } 74 if (SANITIZER_MIPS && t && 75 !IsValidFrame(bp, t->stack_top(), t->stack_bottom())) 76 return; 77 Unwind(max_depth, pc, bp, context, 0, 0, false); 78} 79 80// ------------------ Interface -------------- {{{1 81 82extern "C" { 83SANITIZER_INTERFACE_ATTRIBUTE 84void __sanitizer_print_stack_trace() { 85 using namespace __asan; 86 PRINT_CURRENT_STACK(); 87} 88} // extern "C" 89