mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-26 16:04:34 +00:00
Android callstack collection using _Unwind_Backtrace().
This commit is contained in:
parent
0c13fb818b
commit
bf7402e8b0
@ -69,6 +69,85 @@ CallstackEntry DecodeCallstackPtr( uint64_t ptr )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined __ANDROID__
|
||||||
|
|
||||||
|
CallstackEntry DecodeCallstackPtr( uint64_t ptr )
|
||||||
|
{
|
||||||
|
CallstackEntry ret;
|
||||||
|
ret.line = 0;
|
||||||
|
|
||||||
|
char* demangled = nullptr;
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
symname = "[unknown]";
|
||||||
|
}
|
||||||
|
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';
|
||||||
|
ret.name = name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
sprintf( buf, " + %td", symoff );
|
||||||
|
const auto offlen = strlen( buf );
|
||||||
|
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';
|
||||||
|
ret.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[32];
|
||||||
|
sprintf( buf, " [%p]", (void*)ptr );
|
||||||
|
const auto addrlen = strlen( buf );
|
||||||
|
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';
|
||||||
|
ret.file = loc;
|
||||||
|
|
||||||
|
if( sym ) free( sym );
|
||||||
|
if( demangled ) free( demangled );
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined _GNU_SOURCE
|
#elif defined _GNU_SOURCE
|
||||||
|
|
||||||
CallstackEntry DecodeCallstackPtr( uint64_t ptr )
|
CallstackEntry DecodeCallstackPtr( uint64_t ptr )
|
||||||
|
@ -10,6 +10,9 @@ extern "C" __declspec(dllimport) unsigned short __stdcall RtlCaptureStackBackTra
|
|||||||
extern "C" __declspec(dllimport) unsigned short __stdcall RtlCaptureStackBackTrace( unsigned long, unsigned long, void**, unsigned long* );
|
extern "C" __declspec(dllimport) unsigned short __stdcall RtlCaptureStackBackTrace( unsigned long, unsigned long, void**, unsigned long* );
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
#elif defined __ANDROID__
|
||||||
|
# define TRACY_HAS_CALLSTACK
|
||||||
|
# include <unwind.h>
|
||||||
#elif defined _GNU_SOURCE
|
#elif defined _GNU_SOURCE
|
||||||
# define TRACY_HAS_CALLSTACK
|
# define TRACY_HAS_CALLSTACK
|
||||||
# include <execinfo.h>
|
# include <execinfo.h>
|
||||||
@ -52,6 +55,41 @@ static tracy_force_inline void* Callstack( int depth )
|
|||||||
return trace;
|
return trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined __ANDROID__
|
||||||
|
|
||||||
|
static tracy_force_inline void InitCallstack() {}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined _GNU_SOURCE
|
#elif defined _GNU_SOURCE
|
||||||
|
|
||||||
static tracy_force_inline void InitCallstack() {}
|
static tracy_force_inline void InitCallstack() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user