Skip to content

Commit 1d9df16

Browse files
committed
DBG: fix missing module name in symbol log and implement source mapping
1 parent d13b2ee commit 1d9df16

File tree

7 files changed

+123
-1
lines changed

7 files changed

+123
-1
lines changed

src/dbg/symbolinfo.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "dbghelp_safe.h"
1313
#include "exception.h"
1414
#include "WinInet-Downloader/downslib.h"
15+
#include <shlwapi.h>
1516

1617
struct SYMBOLCBDATA
1718
{
@@ -377,8 +378,39 @@ bool SymGetSourceLine(duint Cip, char* FileName, int* Line, DWORD* disp)
377378
*Line = lineInfo.lineNumber;
378379

379380
if(FileName)
381+
{
380382
strncpy_s(FileName, MAX_STRING_SIZE, lineInfo.sourceFile.c_str(), _TRUNCATE);
381383

384+
// Check if it was a full path
385+
if(!PathIsRelativeW(StringUtils::Utf8ToUtf16(lineInfo.sourceFile).c_str()))
386+
return true;
387+
388+
// Construct full path from pdb path
389+
{
390+
SHARED_ACQUIRE(LockModules);
391+
MODINFO* info = ModInfoFromAddr(Cip);
392+
if(!info)
393+
return true;
394+
395+
String sourceFilePath = info->symbols->loadedSymbolPath();
396+
397+
// Strip the name, leaving only the file directory
398+
size_t bslash = sourceFilePath.rfind('\\');
399+
if(bslash != String::npos)
400+
sourceFilePath.resize(bslash + 1);
401+
sourceFilePath += lineInfo.sourceFile;
402+
403+
// Attempt to remap the source file if it exists (more heuristics could be added in the future)
404+
if(FileExists(sourceFilePath.c_str()))
405+
{
406+
if(info->symbols->mapSourceFilePdbToDisk(lineInfo.sourceFile, sourceFilePath))
407+
{
408+
strncpy_s(FileName, MAX_STRING_SIZE, sourceFilePath.c_str(), _TRUNCATE);
409+
}
410+
}
411+
}
412+
}
413+
382414
return true;
383415
}
384416

src/dbg/symbolsourcebase.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "symbolsourcebase.h"
2+
#include <algorithm>
3+
4+
bool SymbolSourceBase::mapSourceFilePdbToDisk(const std::string & pdb, const std::string & disk)
5+
{
6+
std::string pdblower = pdb, disklower = disk;
7+
std::transform(pdblower.begin(), pdblower.end(), pdblower.begin(), tolower);
8+
std::transform(disklower.begin(), disklower.end(), disklower.begin(), tolower);
9+
10+
// Abort if the disk file doesn't exist
11+
if(!FileExists(disklower.c_str()))
12+
return false;
13+
14+
// Remove existing mapping if found
15+
auto found = _sourceFileMapPdbToDisk.find(pdblower);
16+
if(found != _sourceFileMapPdbToDisk.end())
17+
{
18+
// Abort if there is already an existing mapping for the destination (we want 1 to 1 mapping)
19+
// Done here because we can avoid corrupting the state
20+
if(disklower != found->second && _sourceFileMapDiskToPdb.count(disklower))
21+
return false;
22+
23+
// Remove existing mapping
24+
_sourceFileMapDiskToPdb.erase(found->second);
25+
_sourceFileMapPdbToDisk.erase(found);
26+
}
27+
// Abort if there is already an existing mapping for the destination (we want 1 to 1 mapping)
28+
else if(_sourceFileMapDiskToPdb.count(disklower))
29+
{
30+
return false;
31+
}
32+
33+
// Insert destinations
34+
_sourceFileMapPdbToDisk.insert({ pdblower, disk });
35+
_sourceFileMapDiskToPdb.insert({ disklower, pdb });
36+
return true;
37+
}
38+
39+
bool SymbolSourceBase::getSourceFileDiskToPdb(const std::string & disk, std::string & pdb) const
40+
{
41+
std::string disklower = disk;
42+
std::transform(disklower.begin(), disklower.end(), disklower.begin(), tolower);
43+
auto found = _sourceFileMapDiskToPdb.find(disklower);
44+
if(found == _sourceFileMapDiskToPdb.end())
45+
return false;
46+
pdb = found->second;
47+
return true;
48+
}
49+
50+
bool SymbolSourceBase::getSourceFilePdbToDisk(const std::string & pdb, std::string & disk) const
51+
{
52+
std::string pdblower = pdb;
53+
std::transform(pdblower.begin(), pdblower.end(), pdblower.begin(), tolower);
54+
auto found = _sourceFileMapPdbToDisk.find(pdblower);
55+
if(found == _sourceFileMapPdbToDisk.end())
56+
return false;
57+
disk = found->second;
58+
return true;
59+
}

src/dbg/symbolsourcebase.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <stdint.h>
77
#include <vector>
88
#include <functional>
9+
#include <map>
910

1011
struct SymbolInfoGui
1112
{
@@ -47,6 +48,8 @@ class SymbolSourceBase
4748
{
4849
private:
4950
std::vector<uint8_t> _symbolBitmap; // TODO: what is the maximum size for this?
51+
std::map<std::string, std::string> _sourceFileMapPdbToDisk; // pdb source path -> disk source path
52+
std::map<std::string, std::string> _sourceFileMapDiskToPdb; // disk source path -> pdb source path
5053

5154
public:
5255
virtual ~SymbolSourceBase() = default;
@@ -129,6 +132,15 @@ class SymbolSourceBase
129132
{
130133
return false; // Stub
131134
}
135+
136+
virtual std::string loadedSymbolPath() const
137+
{
138+
return ""; // Stub
139+
}
140+
141+
bool mapSourceFilePdbToDisk(const std::string & pdb, const std::string & disk);
142+
bool getSourceFilePdbToDisk(const std::string & pdb, std::string & disk) const;
143+
bool getSourceFileDiskToPdb(const std::string & disk, std::string & pdb) const;
132144
};
133145

134146
static SymbolSourceBase EmptySymbolSource;

src/dbg/symbolsourcedia.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ bool SymbolSourceDIA::loadPDB(const std::string & path, const std::string & modn
5151
{
5252
_path = path;
5353
_imageSize = imageSize;
54+
_modname = modname;
5455
_imageBase = imageBase;
5556
_requiresShutdown = false;
5657
_symbolsLoaded = false;
@@ -339,12 +340,17 @@ bool SymbolSourceDIA::loadSourceLinesAsync()
339340

340341
uint32_t SymbolSourceDIA::findSourceFile(const std::string & fileName) const
341342
{
343+
// Map the disk file name back to PDB file name
344+
std::string mappedFileName;
345+
if(!getSourceFileDiskToPdb(fileName, mappedFileName))
346+
mappedFileName = fileName;
347+
342348
//TODO: make this fast
343349
uint32_t idx = -1;
344350
for(uint32_t n = 0; n < _sourceFiles.size(); n++)
345351
{
346352
const String & str = _sourceFiles[n];
347-
if(_stricmp(str.c_str(), fileName.c_str()) == 0)
353+
if(_stricmp(str.c_str(), mappedFileName.c_str()) == 0)
348354
{
349355
idx = n;
350356
break;
@@ -436,6 +442,7 @@ bool SymbolSourceDIA::findSourceLineInfo(duint rva, LineInfo & lineInfo)
436442
lineInfo.disp = 0;
437443
lineInfo.size = 0;
438444
lineInfo.sourceFile = _sourceFiles[cached.sourceFileIdx];
445+
getSourceFilePdbToDisk(lineInfo.sourceFile, lineInfo.sourceFile);
439446
return true;
440447
}
441448

@@ -458,6 +465,7 @@ bool SymbolSourceDIA::findSourceLineInfo(const std::string & file, int line, Lin
458465
lineInfo.disp = 0;
459466
lineInfo.size = 0;
460467
lineInfo.sourceFile = _sourceFiles[cached.sourceFileIdx];
468+
getSourceFilePdbToDisk(lineInfo.sourceFile, lineInfo.sourceFile);
461469
return true;
462470
}
463471

@@ -541,3 +549,8 @@ bool SymbolSourceDIA::findSymbolsByPrefix(const std::string & prefix, const std:
541549

542550
return result;
543551
}
552+
553+
std::string SymbolSourceDIA::loadedSymbolPath() const
554+
{
555+
return _path;
556+
}

src/dbg/symbolsourcedia.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ class SymbolSourceDIA : public SymbolSourceBase
158158

159159
virtual bool findSymbolsByPrefix(const std::string & prefix, const std::function<bool(const SymbolInfo &)> & cbSymbol, bool caseSensitive) override;
160160

161+
virtual std::string loadedSymbolPath() const override;
162+
161163
public:
162164
bool loadPDB(const std::string & path, const std::string & modname, duint imageBase, duint imageSize, DiaValidationData_t* validationData);
163165

src/dbg/x64dbg_dbg.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
<ClCompile Include="stringformat.cpp" />
101101
<ClCompile Include="stringutils.cpp" />
102102
<ClCompile Include="symbolinfo.cpp" />
103+
<ClCompile Include="symbolsourcebase.cpp" />
103104
<ClCompile Include="symbolsourcedia.cpp" />
104105
<ClCompile Include="symcache.cpp" />
105106
<ClCompile Include="tcpconnections.cpp" />

src/dbg/x64dbg_dbg.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,9 @@
455455
<ClCompile Include="WinInet-Downloader\downslib.cpp">
456456
<Filter>Source Files\Third Party\WinInet-Downloader</Filter>
457457
</ClCompile>
458+
<ClCompile Include="symbolsourcebase.cpp">
459+
<Filter>Source Files\Symbols</Filter>
460+
</ClCompile>
458461
</ItemGroup>
459462
<ItemGroup>
460463
<ClInclude Include="dbghelp\dbghelp.h">

0 commit comments

Comments
 (0)