mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-30 01:04:36 +00:00
131 lines
3.9 KiB
C++
131 lines
3.9 KiB
C++
#ifdef _WIN32
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
# define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
|
|
#include <windows.h>
|
|
#include <dbghelp.h>
|
|
|
|
#include <cstdio>
|
|
#include <iostream>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <windows.h>
|
|
#include <string>
|
|
|
|
#include "OfflineSymbolResolver.h"
|
|
|
|
class SymbolResolver
|
|
{
|
|
public:
|
|
SymbolResolver()
|
|
{
|
|
m_procHandle = GetCurrentProcess();
|
|
|
|
if( !SymInitialize(m_procHandle, NULL, FALSE) )
|
|
{
|
|
std::cerr << "SymInitialize() failed with: " << GetLastErrorString() << std::endl;
|
|
}
|
|
else
|
|
{
|
|
const DWORD symopts = SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES;
|
|
SymSetOptions( symopts );
|
|
m_dbgHelpInitialized = true;
|
|
}
|
|
}
|
|
|
|
~SymbolResolver()
|
|
{
|
|
SymCleanup( m_procHandle );
|
|
}
|
|
|
|
bool ResolveSymbolsForModule( const std::string& imagePath, const FrameEntryList& inputEntryList,
|
|
SymbolEntryList& resolvedEntries )
|
|
{
|
|
if( !m_dbgHelpInitialized ) return false;
|
|
|
|
ULONG64 moduleBase = SymLoadModuleEx( m_procHandle, NULL, imagePath.c_str(), NULL, 0, 0, NULL, 0 );
|
|
if( !moduleBase )
|
|
{
|
|
std::cerr << "SymLoadModuleEx() failed for module " << imagePath
|
|
<< ": " << GetLastErrorString() << std::endl;
|
|
return false;
|
|
}
|
|
|
|
for( size_t i = 0; i < inputEntryList.size(); ++i )
|
|
{
|
|
uint64_t offset = inputEntryList[i].symbolOffset;
|
|
DWORD64 address = moduleBase + offset;
|
|
|
|
SYMBOL_INFO* symbolInfo = (SYMBOL_INFO*)s_symbolResolutionBuffer;
|
|
symbolInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
|
|
symbolInfo->MaxNameLen = MAX_SYM_NAME;
|
|
|
|
SymbolEntry newEntry;
|
|
|
|
if( SymFromAddr( m_procHandle, address, NULL, symbolInfo ) )
|
|
{
|
|
newEntry.name = symbolInfo->Name;
|
|
//std::cout << "Resolved symbol to: '" << newEntry.name << "'" << std::endl;
|
|
}
|
|
else
|
|
{
|
|
newEntry.name = "[unknown] + " + std::to_string(offset);
|
|
}
|
|
|
|
IMAGEHLP_LINE lineInfo = { 0 };
|
|
lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
|
DWORD displaceMent = 0;
|
|
if ( SymGetLineFromAddr64( m_procHandle, address, &displaceMent, &lineInfo ) )
|
|
{
|
|
newEntry.file = lineInfo.FileName;
|
|
newEntry.line = int(lineInfo.LineNumber);
|
|
///std::cout << "\tline_file: " lineInfo.FileName << ":" << int(lineInfo.LineNumber) << std::endl;
|
|
}
|
|
|
|
resolvedEntries.push_back(std::move(newEntry));
|
|
}
|
|
|
|
SymUnloadModule64( m_procHandle, moduleBase );
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
static const size_t symbolResolutionBufferSize = sizeof(SYMBOL_INFO) + MAX_SYM_NAME;
|
|
static char s_symbolResolutionBuffer[symbolResolutionBufferSize];
|
|
|
|
std::string GetLastErrorString()
|
|
{
|
|
DWORD error = GetLastError();
|
|
if (error == 0)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
LPSTR messageBuffer = nullptr;
|
|
DWORD dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
|
|
size_t size = FormatMessageA( dwFlags, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPSTR)&messageBuffer, 0, NULL );
|
|
|
|
std::string message(messageBuffer, size);
|
|
LocalFree(messageBuffer);
|
|
|
|
return message;
|
|
}
|
|
|
|
bool m_dbgHelpInitialized = false;
|
|
HANDLE m_procHandle = nullptr;
|
|
};
|
|
|
|
char SymbolResolver::s_symbolResolutionBuffer[symbolResolutionBufferSize];
|
|
|
|
bool ResolveSymbols( const std::string& imagePath, const FrameEntryList& inputEntryList,
|
|
SymbolEntryList& resolvedEntries )
|
|
{
|
|
static SymbolResolver resolver;
|
|
return resolver.ResolveSymbolsForModule( imagePath, inputEntryList, resolvedEntries );
|
|
}
|
|
|
|
#endif // #ifdef _WIN32
|