diff --git a/client/TracyCallstack.cpp b/client/TracyCallstack.cpp index 99d4c571..d35b9fbd 100644 --- a/client/TracyCallstack.cpp +++ b/client/TracyCallstack.cpp @@ -146,6 +146,95 @@ CallstackEntryData DecodeCallstackPtr( uint64_t ptr ) return { cb_data, uint8_t( cb_num ) }; } +#elif TRACY_HAS_CALLSTACK == 4 + +void InitCallstack() +{ +} + +CallstackEntryData DecodeCallstackPtr( uint64_t ptr ) +{ + static CallstackEntry cb; + cb.line = 0; + + char* demangled; + const char* symname = nullptr; + const char* symloc = nullptr; + auto vptr = (void*)ptr; + char** sym = nullptr; + ptrdiff_t symoff = 0; + + Dl_info dlinfo; + if( dladdr( vptr, &dlinfo ) ) + { + symloc = dlinfo.dli_fname; + symname = dlinfo.dli_sname; + symoff = (char*)ptr - (char*)dlinfo.dli_saddr; + + if( symname && symname[0] == '_' ) + { + size_t len = 0; + int status; + demangled = abi::__cxa_demangle( symname, nullptr, &len, &status ); + if( status == 0 ) + { + symname = demangled; + } + } + } + + if( !symname ) + { + sym = backtrace_symbols( &vptr, 1 ); + if( !sym ) + { + symname = "[unknown]"; + } + else + { + symname = *sym; + } + } + if( !symloc ) + { + symloc = "[unknown]"; + } + + if( symoff == 0 ) + { + const auto namelen = strlen( symname ); + auto name = (char*)tracy_malloc( namelen + 1 ); + memcpy( name, symname, namelen ); + name[namelen] = '\0'; + cb.name = name; + } + else + { + char buf[32]; + const auto offlen = sprintf( buf, " + %td", symoff ); + const auto namelen = strlen( symname ); + auto name = (char*)tracy_malloc( namelen + offlen + 1 ); + memcpy( name, symname, namelen ); + memcpy( name + namelen, buf, offlen ); + name[namelen + offlen] = '\0'; + cb.name = name; + } + + char buf[32]; + const auto addrlen = sprintf( buf, " [%p]", (void*)ptr ); + const auto loclen = strlen( symloc ); + auto loc = (char*)tracy_malloc( loclen + addrlen + 1 ); + memcpy( loc, symloc, loclen ); + memcpy( loc + loclen, buf, addrlen ); + loc[loclen + addrlen] = '\0'; + cb.file = loc; + + if( sym ) free( sym ); + if( demangled ) free( demangled ); + + return { &cb, 1 }; +} + #elif TRACY_HAS_CALLSTACK >= 2 enum { MaxCbTrace = 16 }; diff --git a/client/TracyCallstack.h b/client/TracyCallstack.h index 8b84e7f3..5516ddd9 100644 --- a/client/TracyCallstack.h +++ b/client/TracyCallstack.h @@ -11,6 +11,8 @@ # else # define TRACY_HAS_CALLSTACK 2 # endif +#elif defined __APPLE__ +# define TRACY_HAS_CALLSTACK 4 #endif #endif diff --git a/client/TracyCallstack.hpp b/client/TracyCallstack.hpp index b4b2c017..8e52c827 100644 --- a/client/TracyCallstack.hpp +++ b/client/TracyCallstack.hpp @@ -11,7 +11,7 @@ extern "C" } #elif TRACY_HAS_CALLSTACK == 2 # include -#elif TRACY_HAS_CALLSTACK == 3 +#elif TRACY_HAS_CALLSTACK >= 3 # include #endif @@ -90,7 +90,7 @@ static tracy_force_inline void* Callstack( int depth ) return trace; } -#elif TRACY_HAS_CALLSTACK == 3 +#elif TRACY_HAS_CALLSTACK >= 3 static tracy_force_inline void* Callstack( int depth ) {