From e2f45167f99016838951ab45d463db2c0f1e237b Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 25 Jul 2023 07:42:37 -0700 Subject: [PATCH] Fixed hot-swap mFindDbgModuleCache where addrs are not 64k-aligned --- IDEHelper/DebugTarget.cpp | 45 +++++++++++++++++++++++++++++++++------ IDEHelper/DebugTarget.h | 15 ++++++++++++- IDEHelper/Debugger.cpp | 3 ++- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/IDEHelper/DebugTarget.cpp b/IDEHelper/DebugTarget.cpp index 978aa87e..fa106df5 100644 --- a/IDEHelper/DebugTarget.cpp +++ b/IDEHelper/DebugTarget.cpp @@ -46,6 +46,8 @@ DebugTarget::DebugTarget(WinDebugger* debugger) DebugTarget::~DebugTarget() { + ClearFindDbgModuleCache(); + for (auto dwarf : mDbgModules) delete dwarf; @@ -273,7 +275,7 @@ String DebugTarget::UnloadDyn(addr_target imageBase) } } - mFindDbgModuleCache.Clear(); + ClearFindDbgModuleCache(); mDbgModules.RemoveAt(i); bool success = mDbgModuleMap.Remove(dwarf->mId); BF_ASSERT_REL(success); @@ -317,7 +319,7 @@ void DebugTarget::CleanupHotHeap() DbgModule* dbgModule = mDbgModules[dwarfIdx]; if (dbgModule->mDeleting) { - mFindDbgModuleCache.Clear(); + ClearFindDbgModuleCache(); mDbgModules.RemoveAt(dwarfIdx); bool success = mDbgModuleMap.Remove(dbgModule->mId); BF_ASSERT_REL(success); @@ -931,10 +933,19 @@ void DebugTarget::GetCompilerSettings() } } +void DebugTarget::ClearFindDbgModuleCache() +{ + for (auto& entry : mFindDbgModuleCache) + { + delete entry.mValue.mCollisions; + } + mFindDbgModuleCache.Clear(); +} + void DebugTarget::AddDbgModule(DbgModule* dbgModule) { dbgModule->mId = ++mCurModuleId; - mFindDbgModuleCache.Clear(); + ClearFindDbgModuleCache(); mDbgModules.Add(dbgModule); bool success = mDbgModuleMap.TryAdd(dbgModule->mId, dbgModule); BF_ASSERT_REL(success); @@ -2481,17 +2492,39 @@ DbgBreakKind DebugTarget::GetDbgBreakKind(addr_target address, CPURegisters* reg DbgModule* DebugTarget::FindDbgModuleForAddress(addr_target address) { addr_target checkAddr = address & ~0xFFFF; - DbgModule** valuePtr = NULL; + FindDbgModuleCacheEntry* valuePtr = NULL; if (mFindDbgModuleCache.TryAdd(checkAddr, NULL, &valuePtr)) { for (auto dwarf : mDbgModules) { if ((address >= dwarf->mImageBase) && (address < dwarf->mImageBase + dwarf->mImageSize)) - *valuePtr = dwarf; + { + if (valuePtr->mFirst == NULL) + { + valuePtr->mFirst = dwarf; + } + else + { + if (valuePtr->mCollisions == NULL) + valuePtr->mCollisions = new Array(); + valuePtr->mCollisions->Add(dwarf); + } + } } } - return *valuePtr; + auto dwarf = valuePtr->mFirst; + if ((address >= dwarf->mImageBase) && (address < dwarf->mImageBase + dwarf->mImageSize)) + return dwarf; + + if (valuePtr->mCollisions != NULL) + { + for (auto dwarf : *valuePtr->mCollisions) + if ((address >= dwarf->mImageBase) && (address < dwarf->mImageBase + dwarf->mImageSize)) + return dwarf; + } + + return NULL; } DbgModule* DebugTarget::GetMainDbgModule() diff --git a/IDEHelper/DebugTarget.h b/IDEHelper/DebugTarget.h index 8716583a..1b5f060c 100644 --- a/IDEHelper/DebugTarget.h +++ b/IDEHelper/DebugTarget.h @@ -18,6 +18,18 @@ enum DbgOnDemandKind DbgOnDemandKind_AllowRemote }; +struct FindDbgModuleCacheEntry +{ + DbgModule* mFirst; + Array* mCollisions; + + FindDbgModuleCacheEntry() + { + mFirst = NULL; + mCollisions = NULL; + } +}; + class DebugTarget { public: @@ -42,7 +54,7 @@ public: DbgModule* mTargetBinary; Array mDbgModules; Dictionary mDbgModuleMap; - Dictionary mFindDbgModuleCache; // Addresses are all 64k multiples + Dictionary mFindDbgModuleCache; // Addresses are all 64k multiples HashSet mPendingSrcFileRehup; // Waiting to remove old/invalid line info BumpAllocator mAlloc; @@ -78,6 +90,7 @@ public: DebugTarget(WinDebugger* debugger); ~DebugTarget(); + void ClearFindDbgModuleCache(); void AddDbgModule(DbgModule* dbgModule); DbgModule* Init(const StringImpl& launchPath, const StringImpl& targetPath, intptr imageBase = 0); void SetupTargetBinary(); diff --git a/IDEHelper/Debugger.cpp b/IDEHelper/Debugger.cpp index d1bae9a5..07d14973 100644 --- a/IDEHelper/Debugger.cpp +++ b/IDEHelper/Debugger.cpp @@ -66,7 +66,8 @@ DbgMemoryFlags DbgModuleMemoryCache::Read(uintptr addr, uint8* data, int size) if ((addr < mAddr) || (addr > mAddr + mSize)) { - gDebugger->ReadMemory(addr, size, data); + if (data != NULL) + gDebugger->ReadMemory(addr, size, data); flags = gDebugger->GetMemoryFlags(addr); BfLogDbg("Got memory flags %p = %d\n", addr, flags); return flags;