1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Improved ability to locate source files from moved PDB

This commit is contained in:
Brian Fiete 2023-02-20 14:45:29 -05:00
parent 0aedc37d42
commit d405104757
11 changed files with 162 additions and 8 deletions

View file

@ -340,6 +340,9 @@ namespace IDE.Debugger
[CallingConvention(.Stdcall),CLink] [CallingConvention(.Stdcall),CLink]
static extern void Debugger_SetSymSrvOptions(char8* symCacheDir, char8* symSrvStr, int32 flags); static extern void Debugger_SetSymSrvOptions(char8* symCacheDir, char8* symSrvStr, int32 flags);
[CallingConvention(.Stdcall),CLink]
static extern void Debugger_SetSourcePathRemap(char8* remapStr);
[CallingConvention(.Stdcall),CLink] [CallingConvention(.Stdcall),CLink]
static extern void Debugger_CancelSymSrv(); static extern void Debugger_CancelSymSrv();
@ -469,6 +472,11 @@ namespace IDE.Debugger
Debugger_SetSymSrvOptions(symCacheDir, symSrvStr, (int32)symSrvFlags); Debugger_SetSymSrvOptions(symCacheDir, symSrvStr, (int32)symSrvFlags);
} }
public void SetSourcePathRemap(String remapStr)
{
Debugger_SetSourcePathRemap(remapStr);
}
public bool OpenMiniDump(String file) public bool OpenMiniDump(String file)
{ {
mIsComptimeDebug = false; mIsComptimeDebug = false;

View file

@ -250,6 +250,19 @@ namespace IDE
} }
gApp.mDebugger.SetSymSrvOptions(mSymCachePath, symbolServerPath, .None); gApp.mDebugger.SetSymSrvOptions(mSymCachePath, symbolServerPath, .None);
String remapStr = scope .();
for (var entry in mAutoFindPaths)
{
if (entry.Contains('@'))
{
if (!remapStr.IsEmpty)
remapStr.Append("\n");
remapStr.Append(entry);
}
}
remapStr.Replace('@', '=');
gApp.mDebugger.SetSourcePathRemap(remapStr);
mProfileSampleRate = Math.Clamp(mProfileSampleRate, 10, 10000); mProfileSampleRate = Math.Clamp(mProfileSampleRate, 10, 10000);
} }

View file

@ -320,6 +320,7 @@ namespace IDE.ui
{ {
for (let searchPath in gApp.mSettings.mDebuggerSettings.mAutoFindPaths) for (let searchPath in gApp.mSettings.mDebuggerSettings.mAutoFindPaths)
{ {
if (!searchPath.Contains('@'))
SearchPath(searchPath); SearchPath(searchPath);
} }
} }

View file

@ -48,6 +48,22 @@ static const char* DataGetString(uint8*& data)
return prevVal; return prevVal;
} }
static const char* SafeDataGetString(uint8*& data, uint8* dataEnd)
{
if (data >= dataEnd)
return NULL;
const char* prevVal = (const char*)data;
while (*data != 0)
{
data++;
if (data >= dataEnd)
return NULL;
}
data++;
return prevVal;
}
#define CREATE_PRIMITIVE(pdbTypeCode, dwTypeCode, typeName, type) \ #define CREATE_PRIMITIVE(pdbTypeCode, dwTypeCode, typeName, type) \
BP_ALLOC_T(DbgType); \ BP_ALLOC_T(DbgType); \
dbgType = mAlloc.Alloc<DbgType>(); \ dbgType = mAlloc.Alloc<DbgType>(); \
@ -5230,7 +5246,9 @@ bool COFF::CvParseDBI(int wantAge)
while (data < dataEnd) while (data < dataEnd)
{ {
int offset = (int)(data - dataStart); int offset = (int)(data - dataStart);
const char* fileName = DataGetString(data); const char* fileName = SafeDataGetString(data, dataEnd);
if (fileName == NULL)
break;
//DbgSrcFile* srcFile = AddSrcFile(mMasterCompileUnit, fileName); //DbgSrcFile* srcFile = AddSrcFile(mMasterCompileUnit, fileName);
//fileTable.insert(std::make_pair(offset, srcFile)); //fileTable.insert(std::make_pair(offset, srcFile));
}*/ }*/
@ -5249,6 +5267,15 @@ bool COFF::CvParseDBI(int wantAge)
uint8* strTabData = data; uint8* strTabData = data;
data += strTabSize; data += strTabSize;
int pdbNameIdx = -1;
for (auto moduleInfo : mCvModuleInfo)
{
if (moduleInfo->mCompilerNameCount > 0)
pdbNameIdx = moduleInfo->mCompilerNameCount;
}
if ((pdbNameIdx > 0) && (pdbNameIdx < strTabSize))
mOrigPDBPath = (const char*)strTabData + pdbNameIdx;
GET_INTO(int32, strTabEntryCount); GET_INTO(int32, strTabEntryCount);
for (int entryIdx = 0; entryIdx < strTabEntryCount; entryIdx++) for (int entryIdx = 0; entryIdx < strTabEntryCount; entryIdx++)
{ {

View file

@ -249,6 +249,7 @@ public:
CvStreamReader mCvSymbolRecordReader; CvStreamReader mCvSymbolRecordReader;
StringT<128> mPDBPath; StringT<128> mPDBPath;
StringT<128> mOrigPDBPath;
SafeMemStream* mCvDataStream; SafeMemStream* mCvDataStream;
CvStringTable mStringTable; CvStringTable mStringTable;

View file

@ -879,7 +879,6 @@ void DbgSrcFile::RemoveLines(DbgModule* debugModule)
{ {
// Fast-out case // Fast-out case
mLineDataRefs.Clear(); mLineDataRefs.Clear();
mFirstLineDataDbgModule = NULL;
return; return;
} }
@ -927,8 +926,63 @@ void DbgSrcFile::RehupLineData()
} }
} }
void DbgSrcFile::VerifyPath()
{
if (mVerifiedPath)
return;
if (mLineDataRefs.IsEmpty())
return;
if (!::FileExists(mFilePath))
{
bool didReplace = false;
for (auto& kv : gDebugManager->mSourcePathRemap)
{
if (mFilePath.StartsWith(kv.mKey, StringImpl::CompareKind_OrdinalIgnoreCase))
{
mFilePath.Remove(0, kv.mKey.mLength);
mFilePath.Insert(0, kv.mValue);
didReplace = true;
}
}
if (!didReplace)
{
HashSet<DbgModule*> checkedModules;
for (auto& lineDataRef : mLineDataRefs)
{
auto dbgModule = lineDataRef->mCompileUnit->mDbgModule;
if (checkedModules.Add(dbgModule))
{
if (dbgModule->mDbgFlavor == DbgFlavor_MS)
{
COFF* coff = (COFF*)dbgModule;
if ((!coff->mOrigPDBPath.IsEmpty()) && (!coff->mOrigPDBPath.Equals(coff->mPDBPath, StringImpl::CompareKind_OrdinalIgnoreCase)))
{
String relFilePath = GetRelativePath(mFilePath, coff->mOrigPDBPath);
String checkActualFilePath = GetAbsPath(relFilePath, coff->mPDBPath);
if (FileExists(checkActualFilePath))
{
mFilePath = checkActualFilePath;
break;
}
}
}
}
}
}
}
mVerifiedPath = true;
}
const String& DbgSrcFile::GetLocalPath() const String& DbgSrcFile::GetLocalPath()
{ {
if (!mVerifiedPath)
VerifyPath();
return (!mLocalPath.IsEmpty()) ? mLocalPath : mFilePath; return (!mLocalPath.IsEmpty()) ? mLocalPath : mFilePath;
} }
@ -4931,6 +4985,7 @@ addr_target DbgModule::GetHotTargetAddress(DbgHotTargetSection* hotTargetSection
if (hotTargetSection->mNoTargetAlloc) if (hotTargetSection->mNoTargetAlloc)
return 0; return 0;
BfLogDbg("DbgModule::GetHotTargetAddress %p %p\n", this, hotTargetSection);
hotTargetSection->mTargetSectionAddr = mDebugger->AllocHotTargetMemory(hotTargetSection->mDataSize, hotTargetSection->mCanExecute, hotTargetSection->mCanWrite, &hotTargetSection->mTargetSectionSize); hotTargetSection->mTargetSectionAddr = mDebugger->AllocHotTargetMemory(hotTargetSection->mDataSize, hotTargetSection->mCanExecute, hotTargetSection->mCanWrite, &hotTargetSection->mTargetSectionSize);
hotTargetSection->mImageOffset = (int)mImageSize; hotTargetSection->mImageOffset = (int)mImageSize;
@ -5207,6 +5262,8 @@ void DbgModule::ParseHotTargetSections(DataStream* stream, addr_target* resolved
void DbgModule::CommitHotTargetSections() void DbgModule::CommitHotTargetSections()
{ {
BfLogDbg("DbgModule::CommitHotTargetSections %p\n", this);
for (int sectNum = 0; sectNum < (int)mHotTargetSections.size(); sectNum++) for (int sectNum = 0; sectNum < (int)mHotTargetSections.size(); sectNum++)
{ {
if (mHotTargetSections[sectNum] != NULL) if (mHotTargetSections[sectNum] != NULL)
@ -5580,7 +5637,7 @@ bool DbgModule::ReadCOFF(DataStream* stream, DbgModuleKind moduleKind)
//if (this == mDebugTarget->mTargetBinary) //if (this == mDebugTarget->mTargetBinary)
//mMemReporter = new MemReporter(); //mMemReporter = new MemReporter();
BfLogDbg("DbgModule::ReadCOFF %s\n", mFilePath.c_str()); BfLogDbg("DbgModule::ReadCOFF %p %s\n", this, mFilePath.c_str());
if (mMemReporter != NULL) if (mMemReporter != NULL)
{ {

View file

@ -729,11 +729,11 @@ public:
String mLocalPath; String mLocalPath;
bool mHadLineData; bool mHadLineData;
bool mHasLineDataFromMultipleModules; bool mHasLineDataFromMultipleModules;
bool mVerifiedPath;
DbgFileExistKind mFileExistKind; DbgFileExistKind mFileExistKind;
int mStepFilterVersion; int mStepFilterVersion;
DbgHashKind mHashKind; DbgHashKind mHashKind;
uint8 mHash[32]; uint8 mHash[32];
DbgModule* mFirstLineDataDbgModule; // Just used to detect mHasLineDataFromMultipleModules
Array<DbgDeferredSrcFileReference> mDeferredRefs; Array<DbgDeferredSrcFileReference> mDeferredRefs;
Array<DbgSubprogram*> mLineDataRefs; Array<DbgSubprogram*> mLineDataRefs;
Array<HotReplacedLineInfo*> mHotReplacedDbgLineInfo; // Indexing starts at -1 Array<HotReplacedLineInfo*> mHotReplacedDbgLineInfo; // Indexing starts at -1
@ -742,8 +742,8 @@ public:
DbgSrcFile() DbgSrcFile()
{ {
mHasLineDataFromMultipleModules = false; mHasLineDataFromMultipleModules = false;
mFirstLineDataDbgModule = NULL;
mHadLineData = false; mHadLineData = false;
mVerifiedPath = false;
mHashKind = DbgHashKind_None; mHashKind = DbgHashKind_None;
mFileExistKind = DbgFileExistKind_NotChecked; mFileExistKind = DbgFileExistKind_NotChecked;
mStepFilterVersion = 0; mStepFilterVersion = 0;
@ -759,6 +759,7 @@ public:
void RemoveLines(DbgModule* debugModule); void RemoveLines(DbgModule* debugModule);
void RemoveLines(DbgModule* debugModule, DbgSubprogram* dbgSubprogram, bool isHotReplaced); void RemoveLines(DbgModule* debugModule, DbgSubprogram* dbgSubprogram, bool isHotReplaced);
void RehupLineData(); void RehupLineData();
void VerifyPath();
const String& GetLocalPath(); const String& GetLocalPath();
void GetHash(String& hashStr); void GetHash(String& hashStr);
}; };

View file

@ -132,11 +132,11 @@ void DbgSymRequest::SearchLocal()
return; return;
} }
uint8 outGuid[16];
int32 outAge;
if (mPDBRequested.IndexOf('\\') != -1) // Do we have an absolute path at all? System dlls won't. if (mPDBRequested.IndexOf('\\') != -1) // Do we have an absolute path at all? System dlls won't.
{ {
// Check actual path // Check actual path
uint8 outGuid[16];
int32 outAge;
if (CheckPDBData(mPDBRequested, outGuid, outAge)) if (CheckPDBData(mPDBRequested, outGuid, outAge))
{ {
mFinalPDBPath = mPDBRequested; mFinalPDBPath = mPDBRequested;
@ -156,6 +156,18 @@ void DbgSymRequest::SearchLocal()
} }
} }
} }
else
{
String checkPath = ::GetFileDir(mModulePath);
checkPath += "\\";
checkPath += mPDBRequested;
if (CheckPDBData(checkPath, outGuid, outAge))
{
mFinalPDBPath = checkPath;
return;
}
}
mMayBeOld = true; mMayBeOld = true;
} }

View file

@ -826,6 +826,38 @@ BF_EXPORT void BF_CALLTYPE Debugger_SetSymSrvOptions(const char* symCacheDir, co
gDebugManager->SetSourceServerCacheDir(); gDebugManager->SetSourceServerCacheDir();
} }
BF_EXPORT void BF_CALLTYPE Debugger_SetSourcePathRemap(const char* remapStr)
{
AutoCrit autoCrit(gDebugManager->mCritSect);
gDebugManager->mSourcePathRemap.Clear();
const char* startStr = remapStr;
for (const char* cPtr = remapStr; true; cPtr++)
{
if ((*cPtr == '\n') || (*cPtr == 0))
{
String remapStr = String(startStr, cPtr - startStr);
remapStr.Trim();
int eqPos = (int)remapStr.IndexOf('=');
if (eqPos != -1)
{
auto keyStr = remapStr.Substring(0, eqPos);
keyStr.Trim();
auto valueStr = remapStr.Substring(eqPos + 1);
valueStr.Trim();
gDebugManager->mSourcePathRemap[keyStr] = valueStr;
}
startStr = cPtr;
}
if (*cPtr == 0)
break;
}
}
BF_EXPORT bool BF_CALLTYPE Debugger_OpenMiniDump(const char* fileName) BF_EXPORT bool BF_CALLTYPE Debugger_OpenMiniDump(const char* fileName)
{ {
#ifdef BF_PLATFORM_WINDOWS #ifdef BF_PLATFORM_WINDOWS

View file

@ -75,6 +75,7 @@ public:
DebugVisualizers* mDebugVisualizers; DebugVisualizers* mDebugVisualizers;
DwDisplayInfo mDefaultDisplayInfo; DwDisplayInfo mDefaultDisplayInfo;
Dictionary<String, DwDisplayInfo> mDisplayInfos; Dictionary<String, DwDisplayInfo> mDisplayInfos;
Dictionary<String, String> mSourcePathRemap;
bool mStepOverExternalFiles; bool mStepOverExternalFiles;
NetManager* mNetManager; NetManager* mNetManager;

View file

@ -345,6 +345,7 @@ DbgSrcFile* DebugTarget::GetSrcFile(const String& srcFilePath)
mSrcFiles.TryGetValue(*origSrcPath, &srcFile); mSrcFiles.TryGetValue(*origSrcPath, &srcFile);
} }
} }
return srcFile; return srcFile;
} }