TracyCallstack.hpp (2452B)
1 #ifndef __TRACYCALLSTACK_HPP__ 2 #define __TRACYCALLSTACK_HPP__ 3 4 #include "TracyCallstack.h" 5 6 #if TRACY_HAS_CALLSTACK == 1 7 extern "C" 8 { 9 typedef unsigned long (__stdcall *t_RtlWalkFrameChain)( void**, unsigned long, unsigned long ); 10 extern t_RtlWalkFrameChain RtlWalkFrameChain; 11 } 12 #elif TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5 13 # include <unwind.h> 14 #elif TRACY_HAS_CALLSTACK >= 3 15 # include <execinfo.h> 16 #endif 17 18 19 #ifdef TRACY_HAS_CALLSTACK 20 21 #include <assert.h> 22 #include <stdint.h> 23 24 #include "../common/TracyAlloc.hpp" 25 #include "../common/TracyForceInline.hpp" 26 27 namespace tracy 28 { 29 30 struct CallstackEntry 31 { 32 const char* name; 33 const char* file; 34 uint32_t line; 35 }; 36 37 struct CallstackEntryData 38 { 39 const CallstackEntry* data; 40 uint8_t size; 41 }; 42 43 const char* DecodeCallstackPtrFast( uint64_t ptr ); 44 CallstackEntryData DecodeCallstackPtr( uint64_t ptr ); 45 void InitCallstack(); 46 47 #if TRACY_HAS_CALLSTACK == 1 48 49 static tracy_force_inline void* Callstack( int depth ) 50 { 51 assert( depth >= 1 && depth < 63 ); 52 53 auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) ); 54 const auto num = RtlWalkFrameChain( (void**)( trace + 1 ), depth, 0 ); 55 *trace = num; 56 57 return trace; 58 } 59 60 #elif TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5 61 62 struct BacktraceState 63 { 64 void** current; 65 void** end; 66 }; 67 68 static _Unwind_Reason_Code tracy_unwind_callback( struct _Unwind_Context* ctx, void* arg ) 69 { 70 auto state = (BacktraceState*)arg; 71 uintptr_t pc = _Unwind_GetIP( ctx ); 72 if( pc ) 73 { 74 if( state->current == state->end ) return _URC_END_OF_STACK; 75 *state->current++ = (void*)pc; 76 } 77 return _URC_NO_REASON; 78 } 79 80 static tracy_force_inline void* Callstack( int depth ) 81 { 82 assert( depth >= 1 && depth < 63 ); 83 84 auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) ); 85 BacktraceState state = { (void**)(trace+1), (void**)(trace+1+depth) }; 86 _Unwind_Backtrace( tracy_unwind_callback, &state ); 87 88 *trace = (uintptr_t*)state.current - trace + 1; 89 90 return trace; 91 } 92 93 #elif TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6 94 95 static tracy_force_inline void* Callstack( int depth ) 96 { 97 assert( depth >= 1 ); 98 99 auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) ); 100 const auto num = backtrace( (void**)(trace+1), depth ); 101 *trace = num; 102 103 return trace; 104 } 105 106 #endif 107 108 } 109 110 #endif 111 112 #endif