Instead of calling dladdr inside the dl_iterate_phdr callback, do it outside to avoid deadlocks with other loader code

This commit is contained in:
trodrigues 2024-05-03 16:05:59 -05:00
parent cc3cbfe6f2
commit 4bf9a8cecc

View File

@ -135,7 +135,8 @@ public:
private:
tracy::FastVector<ImageEntry> m_images;
bool m_updated;
bool m_updated = false;
bool m_haveMainImageName = false;
static int Callback( struct dl_phdr_info* info, size_t size, void* data )
{
@ -153,26 +154,13 @@ private:
image->m_startAddress = startAddress;
image->m_endAddress = endAddress;
const char* imageName = nullptr;
// the base executable name isn't provided when iterating with dl_iterate_phdr, get it with dladdr()
// the base executable name isn't provided when iterating with dl_iterate_phdr,
// we will have to patch the executable image name outside this callback
if( info->dlpi_name && info->dlpi_name[0] != '\0' )
{
imageName = info->dlpi_name;
}
else
{
Dl_info dlInfo;
if( dladdr( (void *)info->dlpi_addr, &dlInfo ) )
{
imageName = dlInfo.dli_fname;
}
}
if( imageName )
{
size_t sz = strlen( imageName ) + 1;
size_t sz = strlen( info->dlpi_name ) + 1;
image->m_name = (char*)tracy_malloc( sz );
memcpy( image->m_name, imageName, sz );
memcpy( image->m_name, info->dlpi_name, sz );
}
else
{
@ -198,9 +186,42 @@ private:
{
std::sort( m_images.begin(), m_images.end(),
[]( const ImageEntry& lhs, const ImageEntry& rhs ) { return lhs.m_startAddress > rhs.m_startAddress; } );
// patch the main executable image name here, as calling dl_* functions inside the dl_iterate_phdr callback might cause deadlocks
UpdateMainImageName();
}
}
void UpdateMainImageName()
{
if( m_haveMainImageName )
{
return;
}
for( ImageEntry& entry : m_images )
{
if( entry.m_name == nullptr )
{
Dl_info dlInfo;
if( dladdr( (void *)entry.m_startAddress, &dlInfo ) )
{
if( dlInfo.dli_fname )
{
size_t sz = strlen( dlInfo.dli_fname ) + 1;
entry.m_name = (char*)tracy_malloc( sz );
memcpy( entry.m_name, dlInfo.dli_fname, sz );
}
}
// we only expect one entry to be null for the main executable entry
break;
}
}
m_haveMainImageName = true;
}
const ImageEntry* GetImageForAddressImpl( void* address ) const
{
auto it = std::lower_bound( m_images.begin(), m_images.end(), address,
@ -221,6 +242,7 @@ private:
}
m_images.clear();
m_haveMainImageName = false;
}
};
#endif //#ifdef TRACY_USE_IMAGE_CACHE