1
0
mirror of https://github.com/wolfpld/tracy synced 2025-04-29 12:23:53 +00:00

Batch addr2line calls per 1024 addresses and escape paths

addr2line starts failing when given too many addresses to resolve.
Batching per 1024 addresses allows not only to see progress but also fixes resolution for images with high number of addresses to resolve.
Escaping is also required when image paths have spaces for example.
This commit is contained in:
Clément Grégoire 2025-04-14 15:36:18 +02:00
parent 9074461ffb
commit f02c6fe4d5

View File

@ -44,21 +44,65 @@ public:
} }
} }
static void escapeShellParam(std::string const& s, std::string& out)
{
out.reserve( s.size() + 2 );
out.push_back( '"' );
for( unsigned char c : s )
{
if( ' ' <= c and c <= '~' and c != '\\' and c != '"' )
{
out.push_back( c );
}
else
{
out.push_back( '\\' );
switch( c )
{
case '"': out.push_back( '"' ); break;
case '\\': out.push_back( '\\' ); break;
case '\t': out.push_back( 't' ); break;
case '\r': out.push_back( 'r' ); break;
case '\n': out.push_back( 'n' ); break;
default:
char const* const hexdig = "0123456789ABCDEF";
out.push_back( 'x' );
out.push_back( hexdig[c >> 4] );
out.push_back( hexdig[c & 0xF] );
}
}
}
out.push_back( '"' );
}
bool ResolveSymbols( const std::string& imagePath, const FrameEntryList& inputEntryList, bool ResolveSymbols( const std::string& imagePath, const FrameEntryList& inputEntryList,
SymbolEntryList& resolvedEntries ) SymbolEntryList& resolvedEntries )
{ {
if (!m_addr2LinePath.length()) return false; if( !m_addr2LinePath.length() ) return false;
std:: string escapedPath;
escapeShellParam( imagePath, escapedPath );
size_t entryIdx = 0;
while( entryIdx < inputEntryList.size() )
{
const size_t startIdx = entryIdx;
const size_t batchEndIdx = std::min( inputEntryList.size(), startIdx + (size_t)1024 );
printf( "Resolving symbols [%zu-%zu[\n", startIdx, batchEndIdx );
// generate a single addr2line cmd line for all addresses in one invocation // generate a single addr2line cmd line for all addresses in one invocation
std::stringstream ss; std::stringstream ss;
ss << m_addr2LinePath << " -C -f -e " << imagePath << " -a "; ss << m_addr2LinePath << " -C -f -e " << escapedPath << " -a ";
for ( const FrameEntry& entry : inputEntryList ) for( ; entryIdx < batchEndIdx; entryIdx++ )
{ {
const FrameEntry& entry = inputEntryList[entryIdx];
ss << " 0x" << std::hex << entry.symbolOffset; ss << " 0x" << std::hex << entry.symbolOffset;
} }
std::string resultStr = ExecShellCommand( ss.str().c_str() ); std::string resultStr = ExecShellCommand( ss.str().c_str() );
std::stringstream result(resultStr); std::stringstream result( resultStr );
//printf("executing: '%s' got '%s'\n", ss.str().c_str(), result.str().c_str()); //printf("executing: '%s' got '%s'\n", ss.str().c_str(), result.str().c_str());
// The output is 2 lines per entry with the following contents: // The output is 2 lines per entry with the following contents:
@ -66,7 +110,7 @@ public:
// symbol_name // symbol_name
// file:line // file:line
for( size_t i = 0; i < inputEntryList.size(); ++i ) for( size_t i = startIdx ;i < batchEndIdx; i++ )
{ {
const FrameEntry& inputEntry = inputEntryList[i]; const FrameEntry& inputEntry = inputEntryList[i];
@ -75,17 +119,17 @@ public:
std::string addr; std::string addr;
std::getline( result, addr ); std::getline( result, addr );
std::getline( result, newEntry.name ); std::getline( result, newEntry.name );
if (newEntry.name == "??") if( newEntry.name == "??" )
{ {
newEntry.name = "[unknown] + " + std::to_string(inputEntry.symbolOffset); newEntry.name = "[unknown] + " + std::to_string( inputEntry.symbolOffset );
} }
std::string fileLine; std::string fileLine;
std::getline(result, fileLine); std::getline( result, fileLine );
if ( fileLine != "??:?" ) if( fileLine != "??:?" )
{ {
size_t pos = fileLine.find_last_of(':'); size_t pos = fileLine.find_last_of( ':' );
if ( pos != std::string::npos ) if( pos != std::string::npos )
{ {
newEntry.file = fileLine.substr( 0, pos ); newEntry.file = fileLine.substr( 0, pos );
std::string lineStr = fileLine.substr( pos + 1 ); std::string lineStr = fileLine.substr( pos + 1 );
@ -94,7 +138,8 @@ public:
} }
} }
resolvedEntries.push_back( std::move(newEntry) ); resolvedEntries.push_back( std::move( newEntry ) );
}
} }
return true; return true;