asan_stack.h revision 276851
133965Sjdp//===-- asan_stack.h --------------------------------------------*- C++ -*-===// 278828Sobrien// 3218822Sdim// The LLVM Compiler Infrastructure 433965Sjdp// 533965Sjdp// This file is distributed under the University of Illinois Open Source 633965Sjdp// License. See LICENSE.TXT for details. 733965Sjdp// 833965Sjdp//===----------------------------------------------------------------------===// 933965Sjdp// 1033965Sjdp// This file is a part of AddressSanitizer, an address sanity checker. 1133965Sjdp// 1233965Sjdp// ASan-private header for asan_stack.cc. 1333965Sjdp//===----------------------------------------------------------------------===// 1433965Sjdp#ifndef ASAN_STACK_H 1533965Sjdp#define ASAN_STACK_H 1633965Sjdp 1733965Sjdp#include "asan_flags.h" 1833965Sjdp#include "asan_thread.h" 1933965Sjdp#include "sanitizer_common/sanitizer_flags.h" 20218822Sdim#include "sanitizer_common/sanitizer_stacktrace.h" 21218822Sdim 2233965Sjdpnamespace __asan { 2333965Sjdp 2433965Sjdp// Get the stack trace with the given pc and bp. 2533965Sjdp// The pc will be in the position 0 of the resulting stack trace. 2633965Sjdp// The bp may refer to the current frame or to the caller's frame. 2733965SjdpALWAYS_INLINE 2833965Sjdpvoid GetStackTraceWithPcBpAndContext(BufferedStackTrace *stack, uptr max_depth, 29218822Sdim uptr pc, uptr bp, void *context, 30218822Sdim bool fast) { 31218822Sdim#if SANITIZER_WINDOWS 32218822Sdim stack->Unwind(max_depth, pc, bp, context, 0, 0, fast); 33218822Sdim#else 34218822Sdim AsanThread *t; 35218822Sdim stack->size = 0; 3633965Sjdp if (LIKELY(asan_inited)) { 3733965Sjdp if ((t = GetCurrentThread()) && !t->isUnwinding()) { 3833965Sjdp // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace() 3933965Sjdp // yields the call stack of the signal's handler and not of the code 4033965Sjdp // that raised the signal (as it does on Linux). 41218822Sdim if (SANITIZER_FREEBSD && t->isInDeadlySignal()) fast = true; 42218822Sdim uptr stack_top = t->stack_top(); 43218822Sdim uptr stack_bottom = t->stack_bottom(); 4477298Sobrien ScopedUnwinding unwind_scope(t); 4577298Sobrien stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast); 4677298Sobrien } else if (t == 0 && !fast) { 4777298Sobrien /* If GetCurrentThread() has failed, try to do slow unwind anyways. */ 4889857Sobrien stack->Unwind(max_depth, pc, bp, context, 0, 0, false); 4989857Sobrien } 5089857Sobrien } 51218822Sdim#endif // SANITIZER_WINDOWS 52218822Sdim} 53218822Sdim 54218822Sdim} // namespace __asan 5589857Sobrien 5689857Sobrien// NOTE: A Rule of thumb is to retrieve stack trace in the interceptors 5789857Sobrien// as early as possible (in functions exposed to the user), as we generally 5889857Sobrien// don't want stack trace to contain functions from ASan internals. 5989857Sobrien 6089857Sobrien#define GET_STACK_TRACE(max_size, fast) \ 6189857Sobrien BufferedStackTrace stack; \ 6289857Sobrien if (max_size <= 2) { \ 6389857Sobrien stack.size = max_size; \ 6489857Sobrien if (max_size > 0) { \ 6589857Sobrien stack.top_frame_bp = GET_CURRENT_FRAME(); \ 6633965Sjdp stack.trace_buffer[0] = StackTrace::GetCurrentPc(); \ 67218822Sdim if (max_size > 1) \ 6833965Sjdp stack.trace_buffer[1] = GET_CALLER_PC(); \ 6933965Sjdp } \ 70218822Sdim } else { \ 71218822Sdim GetStackTraceWithPcBpAndContext(&stack, max_size, \ 7233965Sjdp StackTrace::GetCurrentPc(), \ 7333965Sjdp GET_CURRENT_FRAME(), 0, fast); \ 7433965Sjdp } 75218822Sdim 7633965Sjdp#define GET_STACK_TRACE_FATAL(pc, bp) \ 77218822Sdim BufferedStackTrace stack; \ 7833965Sjdp GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, 0, \ 7933965Sjdp common_flags()->fast_unwind_on_fatal) 8033965Sjdp 8133965Sjdp#define GET_STACK_TRACE_SIGNAL(sig) \ 82218822Sdim BufferedStackTrace stack; \ 8333965Sjdp GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, \ 8433965Sjdp (sig).pc, (sig).bp, (sig).context, \ 8533965Sjdp common_flags()->fast_unwind_on_fatal) 8633965Sjdp 8733965Sjdp#define GET_STACK_TRACE_FATAL_HERE \ 8833965Sjdp GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal) 8933965Sjdp 9033965Sjdp#define GET_STACK_TRACE_CHECK_HERE \ 9133965Sjdp GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_check) 92218822Sdim 9333965Sjdp#define GET_STACK_TRACE_THREAD \ 9433965Sjdp GET_STACK_TRACE(kStackTraceMax, true) 9533965Sjdp 9633965Sjdp#define GET_STACK_TRACE_MALLOC \ 97218822Sdim GET_STACK_TRACE(common_flags()->malloc_context_size, \ 98218822Sdim common_flags()->fast_unwind_on_malloc) 9933965Sjdp 10033965Sjdp#define GET_STACK_TRACE_FREE GET_STACK_TRACE_MALLOC 10133965Sjdp 10233965Sjdp#define PRINT_CURRENT_STACK() \ 10333965Sjdp { \ 10433965Sjdp GET_STACK_TRACE_FATAL_HERE; \ 10533965Sjdp stack.Print(); \ 106218822Sdim } 10733965Sjdp 10833965Sjdp#define PRINT_CURRENT_STACK_CHECK() \ 10933965Sjdp { \ 11033965Sjdp GET_STACK_TRACE_CHECK_HERE; \ 111218822Sdim stack.Print(); \ 11233965Sjdp } 11333965Sjdp 11433965Sjdp#endif // ASAN_STACK_H 11533965Sjdp