Explorar o código

Fixed hot-swap mFindDbgModuleCache where addrs are not 64k-aligned

Brian Fiete %!s(int64=2) %!d(string=hai) anos
pai
achega
e2f45167f9
Modificáronse 3 ficheiros con 55 adicións e 8 borrados
  1. 39 6
      IDEHelper/DebugTarget.cpp
  2. 14 1
      IDEHelper/DebugTarget.h
  3. 2 1
      IDEHelper/Debugger.cpp

+ 39 - 6
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<DbgModule*>();
+					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()

+ 14 - 1
IDEHelper/DebugTarget.h

@@ -18,6 +18,18 @@ enum DbgOnDemandKind
 	DbgOnDemandKind_AllowRemote
 };
 
+struct FindDbgModuleCacheEntry
+{
+	DbgModule* mFirst;
+	Array<DbgModule*>* mCollisions;
+
+	FindDbgModuleCacheEntry()
+	{
+		mFirst = NULL;
+		mCollisions = NULL;
+	}
+};
+
 class DebugTarget
 {
 public:
@@ -42,7 +54,7 @@ public:
 	DbgModule* mTargetBinary;
 	Array<DbgModule*> mDbgModules;
 	Dictionary<int, DbgModule*> mDbgModuleMap;
-	Dictionary<addr_target, DbgModule*> mFindDbgModuleCache; // Addresses are all 64k multiples
+	Dictionary<addr_target, FindDbgModuleCacheEntry> mFindDbgModuleCache; // Addresses are all 64k multiples
 	HashSet<DbgSrcFile*> 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();

+ 2 - 1
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;