TracyCallstack.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #ifndef __TRACYCALLSTACK_HPP__
  2. #define __TRACYCALLSTACK_HPP__
  3. #include "../common/TracyApi.h"
  4. #include "TracyCallstack.h"
  5. #if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5
  6. # include <unwind.h>
  7. #elif TRACY_HAS_CALLSTACK >= 3
  8. # include <execinfo.h>
  9. #endif
  10. #ifdef TRACY_HAS_CALLSTACK
  11. #include <assert.h>
  12. #include <stdint.h>
  13. #include "../common/TracyAlloc.hpp"
  14. #include "../common/TracyForceInline.hpp"
  15. namespace tracy
  16. {
  17. struct CallstackSymbolData
  18. {
  19. const char* file;
  20. uint32_t line;
  21. bool needFree;
  22. };
  23. struct CallstackEntry
  24. {
  25. const char* name;
  26. const char* file;
  27. uint32_t line;
  28. uint32_t symLen;
  29. uint64_t symAddr;
  30. };
  31. struct CallstackEntryData
  32. {
  33. const CallstackEntry* data;
  34. uint8_t size;
  35. const char* imageName;
  36. };
  37. CallstackSymbolData DecodeSymbolAddress( uint64_t ptr );
  38. CallstackSymbolData DecodeCodeAddress( uint64_t ptr );
  39. const char* DecodeCallstackPtrFast( uint64_t ptr );
  40. CallstackEntryData DecodeCallstackPtr( uint64_t ptr );
  41. void InitCallstack();
  42. #if TRACY_HAS_CALLSTACK == 1
  43. TRACY_API uintptr_t* CallTrace( int depth );
  44. static tracy_force_inline void* Callstack( int depth )
  45. {
  46. assert( depth >= 1 && depth < 63 );
  47. return CallTrace( depth );
  48. }
  49. #elif TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5
  50. struct BacktraceState
  51. {
  52. void** current;
  53. void** end;
  54. };
  55. static _Unwind_Reason_Code tracy_unwind_callback( struct _Unwind_Context* ctx, void* arg )
  56. {
  57. auto state = (BacktraceState*)arg;
  58. uintptr_t pc = _Unwind_GetIP( ctx );
  59. if( pc )
  60. {
  61. if( state->current == state->end ) return _URC_END_OF_STACK;
  62. *state->current++ = (void*)pc;
  63. }
  64. return _URC_NO_REASON;
  65. }
  66. static tracy_force_inline void* Callstack( int depth )
  67. {
  68. assert( depth >= 1 && depth < 63 );
  69. auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) );
  70. BacktraceState state = { (void**)(trace+1), (void**)(trace+1+depth) };
  71. _Unwind_Backtrace( tracy_unwind_callback, &state );
  72. *trace = (uintptr_t*)state.current - trace + 1;
  73. return trace;
  74. }
  75. #elif TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6
  76. static tracy_force_inline void* Callstack( int depth )
  77. {
  78. assert( depth >= 1 );
  79. auto trace = (uintptr_t*)tracy_malloc( ( 1 + (size_t)depth ) * sizeof( uintptr_t ) );
  80. const auto num = (size_t)backtrace( (void**)(trace+1), depth );
  81. *trace = num;
  82. return trace;
  83. }
  84. #endif
  85. }
  86. #endif
  87. #endif