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

Merge pull request #1024 from siliceum/update-batch-addr2line

tracy-update: Batch addr2line calls per 1024 addresses and escape paths
This commit is contained in:
Bartosz Taudul 2025-04-14 17:04:02 +02:00 committed by GitHub
commit 1fc7c9f160
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -44,57 +44,102 @@ 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 );
// generate a single addr2line cmd line for all addresses in one invocation size_t entryIdx = 0;
std::stringstream ss; while( entryIdx < inputEntryList.size() )
ss << m_addr2LinePath << " -C -f -e " << imagePath << " -a ";
for ( const FrameEntry& entry : inputEntryList )
{ {
ss << " 0x" << std::hex << entry.symbolOffset; const size_t startIdx = entryIdx;
} const size_t batchEndIdx = std::min( inputEntryList.size(), startIdx + (size_t)1024 );
std::string resultStr = ExecShellCommand( ss.str().c_str() ); printf( "Resolving symbols [%zu-%zu[\n", startIdx, batchEndIdx );
std::stringstream result(resultStr);
//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: // generate a single addr2line cmd line for all addresses in one invocation
// hex_address_of_symbol std::stringstream ss;
// symbol_name ss << m_addr2LinePath << " -C -f -e " << escapedPath << " -a ";
// file:line for( ; entryIdx < batchEndIdx; entryIdx++ )
for( size_t i = 0; i < inputEntryList.size(); ++i )
{
const FrameEntry& inputEntry = inputEntryList[i];
SymbolEntry newEntry;
std::string addr;
std::getline( result, addr );
std::getline( result, newEntry.name );
if (newEntry.name == "??")
{ {
newEntry.name = "[unknown] + " + std::to_string(inputEntry.symbolOffset); const FrameEntry& entry = inputEntryList[entryIdx];
ss << " 0x" << std::hex << entry.symbolOffset;
} }
std::string fileLine; std::string resultStr = ExecShellCommand( ss.str().c_str() );
std::getline(result, fileLine); std::stringstream result( resultStr );
if ( fileLine != "??:?" )
//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:
// hex_address_of_symbol
// symbol_name
// file:line
for( size_t i = startIdx ;i < batchEndIdx; i++ )
{ {
size_t pos = fileLine.find_last_of(':'); const FrameEntry& inputEntry = inputEntryList[i];
if ( pos != std::string::npos )
SymbolEntry newEntry;
std::string addr;
std::getline( result, addr );
std::getline( result, newEntry.name );
if( newEntry.name == "??" )
{ {
newEntry.file = fileLine.substr( 0, pos ); newEntry.name = "[unknown] + " + std::to_string( inputEntry.symbolOffset );
std::string lineStr = fileLine.substr( pos + 1 );
char* after = nullptr;
newEntry.line = strtol( lineStr.c_str(), &after, 10 );
} }
}
resolvedEntries.push_back( std::move(newEntry) ); std::string fileLine;
std::getline( result, fileLine );
if( fileLine != "??:?" )
{
size_t pos = fileLine.find_last_of( ':' );
if( pos != std::string::npos )
{
newEntry.file = fileLine.substr( 0, pos );
std::string lineStr = fileLine.substr( pos + 1 );
char* after = nullptr;
newEntry.line = strtol( lineStr.c_str(), &after, 10 );
}
}
resolvedEntries.push_back( std::move( newEntry ) );
}
} }
return true; return true;