Transfer machine code for external targets.

For an external target the symbol code query addresses are VMAs in the
target's address space, not pointers in the monitor's, so read them out
with ReadExternalTargetMemory. Kernel code (the top bit marks it) is
shared by the monitor and its target alike, so the kernel path applies
in both modes.
This commit is contained in:
Bartosz Taudul
2026-08-30 16:17:34 +02:00
parent d8a011630d
commit 81f3c71ef3

View File

@@ -4432,29 +4432,35 @@ void Profiler::HandleParameter( uint64_t payload )
void Profiler::HandleSymbolCodeQuery( uint64_t symbol, uint32_t size )
{
#if defined __linux__ && defined TRACY_HAS_CALLSTACK
// When profiling an external process, symbol addresses are ELF virtual
// addresses, not pointers in the monitor's address space. We cannot
// read code bytes directly.
if( GetExternalTargetPid() != 0 )
{
AckSymbolCodeNotAvailable();
return;
}
#endif
if( symbol >> 63 != 0 )
{
QueueKernelCode( symbol, size );
return;
}
else
{
auto&& lambda = [ this, symbol ]( const char* buf, size_t size ) {
SendLongString( symbol, buf, size, QueueType::SymbolCode );
};
// 'symbol' may have come from a module that has since unloaded, perform a safe copy before sending
if( !WithSafeCopy( (const char*)symbol, size, lambda ) ) AckSymbolCodeNotAvailable();
auto&& lambda = [ this, symbol ]( const char* buf, size_t size ) {
SendLongString( symbol, buf, size, QueueType::SymbolCode );
};
#if defined __linux__ && defined TRACY_HAS_CALLSTACK
if( GetExternalTargetPid() != 0 )
{
auto buf = (char*)tracy_malloc_fast( size );
if( ReadExternalTargetMemory( symbol, size, buf ) == size )
{
lambda( buf, size );
}
else
{
AckSymbolCodeNotAvailable();
}
tracy_free_fast( buf );
return;
}
#endif
// 'symbol' may have come from a module that has since unloaded, perform a safe copy before sending
if( !WithSafeCopy( (const char*)symbol, size, lambda ) ) AckSymbolCodeNotAvailable();
}
void Profiler::HandleSourceCodeQuery( char* data, char* image, uint32_t id )