//===-- asan_stack.h --------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file is a part of AddressSanitizer, an address sanity checker. // // ASan-private header for asan_stack.cc. //===----------------------------------------------------------------------===// #ifndef ASAN_STACK_H #define ASAN_STACK_H #include "asan_internal.h" namespace __asan { static const uptr kStackTraceMax = 64; struct AsanStackTrace { uptr size; uptr max_size; uptr trace[kStackTraceMax]; static void PrintStack(uptr *addr, uptr size); void PrintStack() { PrintStack(this->trace, this->size); } void CopyTo(uptr *dst, uptr dst_size) { for (uptr i = 0; i < size && i < dst_size; i++) dst[i] = trace[i]; for (uptr i = size; i < dst_size; i++) dst[i] = 0; } void CopyFrom(uptr *src, uptr src_size) { size = src_size; if (size > kStackTraceMax) size = kStackTraceMax; for (uptr i = 0; i < size; i++) { trace[i] = src[i]; } } void GetStackTrace(uptr max_s, uptr pc, uptr bp); void FastUnwindStack(uptr pc, uptr bp); static uptr GetCurrentPc(); static uptr CompressStack(AsanStackTrace *stack, u32 *compressed, uptr size); static void UncompressStack(AsanStackTrace *stack, u32 *compressed, uptr size); }; } // namespace __asan // Use this macro if you want to print stack trace with the caller // of the current function in the top frame. #define GET_CALLER_PC_BP_SP \ uptr bp = GET_CURRENT_FRAME(); \ uptr pc = GET_CALLER_PC(); \ uptr local_stack; \ uptr sp = (uptr)&local_stack // Use this macro if you want to print stack trace with the current // function in the top frame. #define GET_CURRENT_PC_BP_SP \ uptr bp = GET_CURRENT_FRAME(); \ uptr pc = AsanStackTrace::GetCurrentPc(); \ uptr local_stack; \ uptr sp = (uptr)&local_stack // Get the stack trace with the given pc and bp. // The pc will be in the position 0 of the resulting stack trace. // The bp may refer to the current frame or to the caller's frame. // fast_unwind is currently unused. #define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, pc, bp) \ AsanStackTrace stack; \ stack.GetStackTrace(max_s, pc, bp) // NOTE: A Rule of thumb is to retrieve stack trace in the interceptors // as early as possible (in functions exposed to the user), as we generally // don't want stack trace to contain functions from ASan internals. #define GET_STACK_TRACE_HERE(max_size) \ GET_STACK_TRACE_WITH_PC_AND_BP(max_size, \ AsanStackTrace::GetCurrentPc(), GET_CURRENT_FRAME()) #define GET_STACK_TRACE_HERE_FOR_MALLOC \ GET_STACK_TRACE_HERE(FLAG_malloc_context_size) #define GET_STACK_TRACE_HERE_FOR_FREE(ptr) \ GET_STACK_TRACE_HERE(FLAG_malloc_context_size) #define PRINT_CURRENT_STACK() \ { \ GET_STACK_TRACE_HERE(kStackTraceMax); \ stack.PrintStack(); \ } #endif // ASAN_STACK_H