1353944Sdim//===-- asan_stack.cpp ----------------------------------------------------===// 2353944Sdim// 3353944Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353944Sdim// See https://llvm.org/LICENSE.txt for license information. 5353944Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353944Sdim// 7353944Sdim//===----------------------------------------------------------------------===// 8353944Sdim// 9353944Sdim// This file is a part of AddressSanitizer, an address sanity checker. 10353944Sdim// 11353944Sdim// Code for ASan stack trace. 12353944Sdim//===----------------------------------------------------------------------===// 13353944Sdim#include "asan_internal.h" 14353944Sdim#include "asan_stack.h" 15353944Sdim#include "sanitizer_common/sanitizer_atomic.h" 16353944Sdim 17353944Sdimnamespace __asan { 18353944Sdim 19353944Sdimstatic atomic_uint32_t malloc_context_size; 20353944Sdim 21353944Sdimvoid SetMallocContextSize(u32 size) { 22353944Sdim atomic_store(&malloc_context_size, size, memory_order_release); 23353944Sdim} 24353944Sdim 25353944Sdimu32 GetMallocContextSize() { 26353944Sdim return atomic_load(&malloc_context_size, memory_order_acquire); 27353944Sdim} 28353944Sdim 29353944Sdimnamespace { 30353944Sdim 31353944Sdim// ScopedUnwinding is a scope for stacktracing member of a context 32353944Sdimclass ScopedUnwinding { 33353944Sdim public: 34353944Sdim explicit ScopedUnwinding(AsanThread *t) : thread(t) { 35353944Sdim if (thread) { 36353944Sdim can_unwind = !thread->isUnwinding(); 37353944Sdim thread->setUnwinding(true); 38353944Sdim } 39353944Sdim } 40353944Sdim ~ScopedUnwinding() { 41353944Sdim if (thread) 42353944Sdim thread->setUnwinding(false); 43353944Sdim } 44353944Sdim 45353944Sdim bool CanUnwind() const { return can_unwind; } 46353944Sdim 47353944Sdim private: 48353944Sdim AsanThread *thread = nullptr; 49353944Sdim bool can_unwind = true; 50353944Sdim}; 51353944Sdim 52353944Sdim} // namespace 53353944Sdim 54353944Sdim} // namespace __asan 55353944Sdim 56353944Sdimvoid __sanitizer::BufferedStackTrace::UnwindImpl( 57353944Sdim uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { 58353944Sdim using namespace __asan; 59353944Sdim size = 0; 60353944Sdim if (UNLIKELY(!asan_inited)) 61353944Sdim return; 62353944Sdim request_fast = StackTrace::WillUseFastUnwind(request_fast); 63353944Sdim AsanThread *t = GetCurrentThread(); 64353944Sdim ScopedUnwinding unwind_scope(t); 65353944Sdim if (!unwind_scope.CanUnwind()) 66353944Sdim return; 67353944Sdim if (request_fast) { 68353944Sdim if (t) { 69353944Sdim Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), 70353944Sdim true); 71353944Sdim } 72353944Sdim return; 73353944Sdim } 74353944Sdim if (SANITIZER_MIPS && t && 75353944Sdim !IsValidFrame(bp, t->stack_top(), t->stack_bottom())) 76353944Sdim return; 77353944Sdim Unwind(max_depth, pc, bp, context, 0, 0, false); 78353944Sdim} 79353944Sdim 80353944Sdim// ------------------ Interface -------------- {{{1 81353944Sdim 82353944Sdimextern "C" { 83353944SdimSANITIZER_INTERFACE_ATTRIBUTE 84353944Sdimvoid __sanitizer_print_stack_trace() { 85353944Sdim using namespace __asan; 86353944Sdim PRINT_CURRENT_STACK(); 87353944Sdim} 88353944Sdim} // extern "C" 89