2018-06-18 23:17:19 +00:00
|
|
|
#ifndef __TRACYCALLSTACK_HPP__
|
|
|
|
#define __TRACYCALLSTACK_HPP__
|
|
|
|
|
2020-01-25 15:49:29 +00:00
|
|
|
#include "../common/TracyApi.h"
|
2019-01-27 12:41:32 +00:00
|
|
|
#include "TracyCallstack.h"
|
|
|
|
|
2020-01-25 15:49:29 +00:00
|
|
|
#if TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5
|
2018-06-21 15:07:21 +00:00
|
|
|
# include <unwind.h>
|
2019-02-20 15:01:41 +00:00
|
|
|
#elif TRACY_HAS_CALLSTACK >= 3
|
2019-01-27 12:41:32 +00:00
|
|
|
# include <execinfo.h>
|
2018-06-18 23:17:19 +00:00
|
|
|
#endif
|
|
|
|
|
2018-06-20 19:45:27 +00:00
|
|
|
|
2018-06-18 23:17:19 +00:00
|
|
|
#ifdef TRACY_HAS_CALLSTACK
|
|
|
|
|
2022-05-01 13:26:26 +00:00
|
|
|
#ifdef TRACY_DEBUGINFOD
|
|
|
|
# include <elfutils/debuginfod.h>
|
|
|
|
#endif
|
|
|
|
|
2018-06-19 16:49:13 +00:00
|
|
|
#include <assert.h>
|
2018-06-18 23:17:19 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include "../common/TracyAlloc.hpp"
|
|
|
|
#include "../common/TracyForceInline.hpp"
|
|
|
|
|
|
|
|
namespace tracy
|
|
|
|
{
|
|
|
|
|
2020-08-20 15:38:29 +00:00
|
|
|
struct CallstackSymbolData
|
2018-06-18 23:17:19 +00:00
|
|
|
{
|
|
|
|
const char* file;
|
|
|
|
uint32_t line;
|
2020-02-27 12:17:26 +00:00
|
|
|
bool needFree;
|
2021-06-19 17:02:08 +00:00
|
|
|
uint64_t symAddr;
|
2020-02-26 21:32:42 +00:00
|
|
|
};
|
|
|
|
|
2020-02-27 11:58:01 +00:00
|
|
|
struct CallstackEntry
|
2020-02-26 21:32:42 +00:00
|
|
|
{
|
2020-02-27 11:58:01 +00:00
|
|
|
const char* name;
|
|
|
|
const char* file;
|
|
|
|
uint32_t line;
|
2020-03-25 17:05:00 +00:00
|
|
|
uint32_t symLen;
|
2020-02-25 22:03:40 +00:00
|
|
|
uint64_t symAddr;
|
2018-06-18 23:17:19 +00:00
|
|
|
};
|
|
|
|
|
2019-01-20 18:11:48 +00:00
|
|
|
struct CallstackEntryData
|
|
|
|
{
|
|
|
|
const CallstackEntry* data;
|
|
|
|
uint8_t size;
|
2020-02-25 23:32:47 +00:00
|
|
|
const char* imageName;
|
2019-01-20 18:11:48 +00:00
|
|
|
};
|
|
|
|
|
2020-08-20 15:38:29 +00:00
|
|
|
CallstackSymbolData DecodeSymbolAddress( uint64_t ptr );
|
2019-03-05 01:34:35 +00:00
|
|
|
const char* DecodeCallstackPtrFast( uint64_t ptr );
|
2019-01-20 18:11:48 +00:00
|
|
|
CallstackEntryData DecodeCallstackPtr( uint64_t ptr );
|
2019-01-20 15:55:59 +00:00
|
|
|
void InitCallstack();
|
2022-08-16 11:55:46 +00:00
|
|
|
void InitCallstackCritical();
|
2022-04-27 15:49:28 +00:00
|
|
|
void EndCallstack();
|
2021-11-25 22:27:20 +00:00
|
|
|
const char* GetKernelModulePath( uint64_t addr );
|
2018-06-20 19:45:27 +00:00
|
|
|
|
2022-05-01 12:50:50 +00:00
|
|
|
#ifdef TRACY_DEBUGINFOD
|
|
|
|
const uint8_t* GetBuildIdForImage( const char* image, size_t& size );
|
2022-05-01 13:05:23 +00:00
|
|
|
debuginfod_client* GetDebuginfodClient();
|
2022-05-01 12:50:50 +00:00
|
|
|
#endif
|
|
|
|
|
2018-07-14 09:08:17 +00:00
|
|
|
#if TRACY_HAS_CALLSTACK == 1
|
2018-06-18 23:17:19 +00:00
|
|
|
|
2022-01-01 16:33:39 +00:00
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
typedef unsigned long (__stdcall *___tracy_t_RtlWalkFrameChain)( void**, unsigned long, unsigned long );
|
|
|
|
TRACY_API extern ___tracy_t_RtlWalkFrameChain ___tracy_RtlWalkFrameChain;
|
|
|
|
}
|
2020-01-25 15:49:29 +00:00
|
|
|
|
2018-06-19 16:49:13 +00:00
|
|
|
static tracy_force_inline void* Callstack( int depth )
|
2018-06-18 23:17:19 +00:00
|
|
|
{
|
2018-06-20 15:02:05 +00:00
|
|
|
assert( depth >= 1 && depth < 63 );
|
2022-01-01 16:33:39 +00:00
|
|
|
auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) );
|
|
|
|
const auto num = ___tracy_RtlWalkFrameChain( (void**)( trace + 1 ), depth, 0 );
|
|
|
|
*trace = num;
|
|
|
|
return trace;
|
2018-06-18 23:17:19 +00:00
|
|
|
}
|
|
|
|
|
2019-05-22 12:14:30 +00:00
|
|
|
#elif TRACY_HAS_CALLSTACK == 2 || TRACY_HAS_CALLSTACK == 5
|
2018-06-21 15:07:21 +00:00
|
|
|
|
|
|
|
struct BacktraceState
|
|
|
|
{
|
|
|
|
void** current;
|
|
|
|
void** end;
|
|
|
|
};
|
|
|
|
|
|
|
|
static _Unwind_Reason_Code tracy_unwind_callback( struct _Unwind_Context* ctx, void* arg )
|
|
|
|
{
|
|
|
|
auto state = (BacktraceState*)arg;
|
|
|
|
uintptr_t pc = _Unwind_GetIP( ctx );
|
|
|
|
if( pc )
|
|
|
|
{
|
|
|
|
if( state->current == state->end ) return _URC_END_OF_STACK;
|
|
|
|
*state->current++ = (void*)pc;
|
|
|
|
}
|
|
|
|
return _URC_NO_REASON;
|
|
|
|
}
|
|
|
|
|
|
|
|
static tracy_force_inline void* Callstack( int depth )
|
|
|
|
{
|
|
|
|
assert( depth >= 1 && depth < 63 );
|
|
|
|
|
|
|
|
auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) );
|
|
|
|
BacktraceState state = { (void**)(trace+1), (void**)(trace+1+depth) };
|
|
|
|
_Unwind_Backtrace( tracy_unwind_callback, &state );
|
|
|
|
|
|
|
|
*trace = (uintptr_t*)state.current - trace + 1;
|
|
|
|
|
|
|
|
return trace;
|
|
|
|
}
|
|
|
|
|
2019-11-21 18:50:46 +00:00
|
|
|
#elif TRACY_HAS_CALLSTACK == 3 || TRACY_HAS_CALLSTACK == 4 || TRACY_HAS_CALLSTACK == 6
|
2018-06-20 19:45:27 +00:00
|
|
|
|
|
|
|
static tracy_force_inline void* Callstack( int depth )
|
|
|
|
{
|
|
|
|
assert( depth >= 1 );
|
|
|
|
|
2020-11-19 15:36:01 +00:00
|
|
|
auto trace = (uintptr_t*)tracy_malloc( ( 1 + (size_t)depth ) * sizeof( uintptr_t ) );
|
|
|
|
const auto num = (size_t)backtrace( (void**)(trace+1), depth );
|
2018-06-20 19:45:27 +00:00
|
|
|
*trace = num;
|
|
|
|
|
|
|
|
return trace;
|
|
|
|
}
|
|
|
|
|
2018-06-18 23:17:19 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|