asan_stack.h revision 2b939c3abc8b7713ef28000bd768ca6d77445f45
1//===-- asan_stack.h --------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of AddressSanitizer, an address sanity checker. 11// 12// ASan-private header for asan_stack.cc. 13//===----------------------------------------------------------------------===// 14#ifndef ASAN_STACK_H 15#define ASAN_STACK_H 16 17#include "asan_internal.h" 18 19namespace __asan { 20 21static const uptr kStackTraceMax = 64; 22 23struct StackTrace { 24 uptr size; 25 uptr max_size; 26 uptr trace[kStackTraceMax]; 27 static void PrintStack(uptr *addr, uptr size); 28 void PrintStack() { 29 PrintStack(this->trace, this->size); 30 } 31 void CopyTo(uptr *dst, uptr dst_size) { 32 for (uptr i = 0; i < size && i < dst_size; i++) 33 dst[i] = trace[i]; 34 for (uptr i = size; i < dst_size; i++) 35 dst[i] = 0; 36 } 37 38 void CopyFrom(uptr *src, uptr src_size) { 39 size = src_size; 40 if (size > kStackTraceMax) size = kStackTraceMax; 41 for (uptr i = 0; i < size; i++) { 42 trace[i] = src[i]; 43 } 44 } 45 46 void FastUnwindStack(uptr pc, uptr bp, uptr stack_top, uptr stack_bottom); 47 48 static uptr GetCurrentPc(); 49 50 static uptr CompressStack(StackTrace *stack, 51 u32 *compressed, uptr size); 52 static void UncompressStack(StackTrace *stack, 53 u32 *compressed, uptr size); 54}; 55 56void GetStackTrace(StackTrace *trace, uptr max_s, uptr pc, uptr bp); 57 58 59 60} // namespace __asan 61 62// Use this macro if you want to print stack trace with the caller 63// of the current function in the top frame. 64#define GET_CALLER_PC_BP_SP \ 65 uptr bp = GET_CURRENT_FRAME(); \ 66 uptr pc = GET_CALLER_PC(); \ 67 uptr local_stack; \ 68 uptr sp = (uptr)&local_stack 69 70// Use this macro if you want to print stack trace with the current 71// function in the top frame. 72#define GET_CURRENT_PC_BP_SP \ 73 uptr bp = GET_CURRENT_FRAME(); \ 74 uptr pc = StackTrace::GetCurrentPc(); \ 75 uptr local_stack; \ 76 uptr sp = (uptr)&local_stack 77 78// Get the stack trace with the given pc and bp. 79// The pc will be in the position 0 of the resulting stack trace. 80// The bp may refer to the current frame or to the caller's frame. 81// fast_unwind is currently unused. 82#define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, pc, bp) \ 83 StackTrace stack; \ 84 GetStackTrace(&stack, max_s, pc, bp) 85 86// NOTE: A Rule of thumb is to retrieve stack trace in the interceptors 87// as early as possible (in functions exposed to the user), as we generally 88// don't want stack trace to contain functions from ASan internals. 89 90#define GET_STACK_TRACE_HERE(max_size) \ 91 GET_STACK_TRACE_WITH_PC_AND_BP(max_size, \ 92 StackTrace::GetCurrentPc(), GET_CURRENT_FRAME()) 93 94#define GET_STACK_TRACE_HERE_FOR_MALLOC \ 95 GET_STACK_TRACE_HERE(flags()->malloc_context_size) 96 97#define GET_STACK_TRACE_HERE_FOR_FREE(ptr) \ 98 GET_STACK_TRACE_HERE(flags()->malloc_context_size) 99 100#define PRINT_CURRENT_STACK() \ 101 { \ 102 GET_STACK_TRACE_HERE(kStackTraceMax); \ 103 stack.PrintStack(); \ 104 } 105 106#endif // ASAN_STACK_H 107