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 19 namespace __asan { 20 21 static const size_t kStackTraceMax = 64; 22 23 struct AsanStackTrace { 24 size_t size; 25 size_t max_size; 26 uintptr_t trace[kStackTraceMax]; 27 static void PrintStack(uintptr_t *addr, size_t size); PrintStackAsanStackTrace28 void PrintStack() { 29 PrintStack(this->trace, this->size); 30 } CopyToAsanStackTrace31 void CopyTo(uintptr_t *dst, size_t dst_size) { 32 for (size_t i = 0; i < size && i < dst_size; i++) 33 dst[i] = trace[i]; 34 for (size_t i = size; i < dst_size; i++) 35 dst[i] = 0; 36 } 37 CopyFromAsanStackTrace38 void CopyFrom(uintptr_t *src, size_t src_size) { 39 size = src_size; 40 if (size > kStackTraceMax) size = kStackTraceMax; 41 for (size_t i = 0; i < size; i++) { 42 trace[i] = src[i]; 43 } 44 } 45 46 void GetStackTrace(size_t max_s, uintptr_t pc, uintptr_t bp); 47 48 void FastUnwindStack(uintptr_t pc, uintptr_t bp); 49 50 static uintptr_t GetCurrentPc(); 51 52 static size_t CompressStack(AsanStackTrace *stack, 53 uint32_t *compressed, size_t size); 54 static void UncompressStack(AsanStackTrace *stack, 55 uint32_t *compressed, size_t size); 56 }; 57 58 } // namespace __asan 59 60 // Use this macro if you want to print stack trace with the caller 61 // of the current function in the top frame. 62 #define GET_CALLER_PC_BP_SP \ 63 uintptr_t bp = GET_CURRENT_FRAME(); \ 64 uintptr_t pc = GET_CALLER_PC(); \ 65 uintptr_t local_stack; \ 66 uintptr_t sp = (uintptr_t)&local_stack; 67 68 // Use this macro if you want to print stack trace with the current 69 // function in the top frame. 70 #define GET_CURRENT_PC_BP_SP \ 71 uintptr_t bp = GET_CURRENT_FRAME(); \ 72 uintptr_t pc = AsanStackTrace::GetCurrentPc(); \ 73 uintptr_t local_stack; \ 74 uintptr_t sp = (uintptr_t)&local_stack; 75 76 // Get the stack trace with the given pc and bp. 77 // The pc will be in the position 0 of the resulting stack trace. 78 // The bp may refer to the current frame or to the caller's frame. 79 // fast_unwind is currently unused. 80 #define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, pc, bp) \ 81 AsanStackTrace stack; \ 82 stack.GetStackTrace(max_s, pc, bp); \ 83 84 // NOTE: A Rule of thumb is to retrieve stack trace in the interceptors 85 // as early as possible (in functions exposed to the user), as we generally 86 // don't want stack trace to contain functions from ASan internals. 87 88 #define GET_STACK_TRACE_HERE(max_size) \ 89 GET_STACK_TRACE_WITH_PC_AND_BP(max_size, \ 90 AsanStackTrace::GetCurrentPc(), GET_CURRENT_FRAME()) \ 91 92 #define GET_STACK_TRACE_HERE_FOR_MALLOC \ 93 GET_STACK_TRACE_HERE(FLAG_malloc_context_size) 94 95 #define GET_STACK_TRACE_HERE_FOR_FREE(ptr) \ 96 GET_STACK_TRACE_HERE(FLAG_malloc_context_size) 97 98 #define PRINT_CURRENT_STACK() \ 99 { \ 100 GET_STACK_TRACE_HERE(kStackTraceMax); \ 101 stack.PrintStack(); \ 102 } \ 103 104 #endif // ASAN_STACK_H 105