Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

[3.1 port] Fix debugger crash during unload of assemblies in ALC #28023

Merged
merged 1 commit into from Mar 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/debug/ee/debugger.cpp
Expand Up @@ -5392,6 +5392,7 @@ DebuggerModule* Debugger::LookupOrCreateModule(Module* pModule, AppDomain *pAppD
// If it doesn't exist, create it.
if (dmod == NULL)
{
LOG((LF_CORDB, LL_INFO1000, "D::LOCM dmod for m=0x%x ad=0x%x not found, creating.\n", pModule, pAppDomain));
HRESULT hr = S_OK;
EX_TRY
{
Expand All @@ -5406,7 +5407,8 @@ DebuggerModule* Debugger::LookupOrCreateModule(Module* pModule, AppDomain *pAppD
// The module must be in the AppDomain that was requested
_ASSERTE( (dmod == NULL) || (dmod->GetAppDomain() == pAppDomain) );

LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=0x%x ad=0x%x -> dm=0x%x\n", pModule, pAppDomain, dmod));
LOG((LF_CORDB, LL_INFO1000, "D::LOCM m=0x%x ad=0x%x -> dm=0x%x(Mod=0x%x, DomFile=0x%x, AD=0x%x)\n",
pModule, pAppDomain, dmod, dmod->GetRuntimeModule(), dmod->GetDomainFile(), dmod->GetAppDomain()));
return dmod;
}

Expand Down Expand Up @@ -10014,8 +10016,10 @@ void Debugger::UnloadModule(Module* pRuntimeModule,
}
_ASSERTE(module != NULL);

STRESS_LOG3(LF_CORDB, LL_INFO10000, "D::UM: Unloading Mod:%#08x, %#08x, %#08x\n",
pRuntimeModule, pAppDomain, pRuntimeModule->IsIStream());
STRESS_LOG6(LF_CORDB, LL_INFO10000,
"D::UM: Unloading RTMod:%#08x (DomFile: %#08x, IsISStream:%#08x); DMod:%#08x(RTMod:%#08x DomFile: %#08x)\n",
pRuntimeModule, pRuntimeModule->GetDomainFile(), pRuntimeModule->IsIStream(),
module, module->GetRuntimeModule(), module->GetDomainFile());

// Note: the appdomain the module was loaded in must match the appdomain we're unloading it from. If it doesn't,
// then we've either found the wrong DebuggerModule in LookupModule or we were passed bad data.
Expand Down
42 changes: 30 additions & 12 deletions src/debug/ee/debuggermodule.cpp
Expand Up @@ -226,11 +226,10 @@ void DebuggerModuleTable::AddModule(DebuggerModule *pModule)
}

//-----------------------------------------------------------------------------
// Remove a DebuggerModule from the module table.
// This occurs in response to AppDomain unload.
// Note that this doesn't necessarily mean the EE Module is being unloaded (it may be shared)
// Remove a DebuggerModule from the module table when it gets notified.
// This occurs in response to the finalization of an unloaded AssemblyLoadContext.
//-----------------------------------------------------------------------------
void DebuggerModuleTable::RemoveModule(Module* module, AppDomain *pAppDomain)
void DebuggerModuleTable::RemoveModule(Module* pModule, AppDomain *pAppDomain)
{
CONTRACTL
{
Expand All @@ -239,12 +238,33 @@ void DebuggerModuleTable::RemoveModule(Module* module, AppDomain *pAppDomain)
}
CONTRACTL_END;

// If this is a domain neutral module, then scan the complete list of DebuggerModules looking
// for the one with a matching appdomain id.
// Note: we have to make sure to lookup the module with the app domain parameter if the module lives in a shared
// assembly or the system assembly. <BUGNUM>Bugs 65943 & 81728.</BUGNUM>
_ASSERTE( FALSE );

LOG((LF_CORDB, LL_INFO1000, "DMT::RM Attempting to remove Module:0x%x AD:0x%x\n", pModule, pAppDomain));

_ASSERTE(ThreadHoldsLock());
_ASSERTE(pModule != NULL);

HASHFIND hf;

for (DebuggerModuleEntry *pDME = (DebuggerModuleEntry *) FindFirstEntry(&hf);
pDME != NULL;
pDME = (DebuggerModuleEntry*) FindNextEntry(&hf))
{
DebuggerModule *pDM = pDME->module;
Module* pRuntimeModule = pDM->GetRuntimeModule();

if ((pRuntimeModule == pModule) && (pDM->GetAppDomain() == pAppDomain))
{
LOG((LF_CORDB, LL_INFO1000, "DMT::RM Removing DebuggerMod:0x%x - Module:0x%x DF:0x%x AD:0x%x\n",
pDM, pModule, pDM->GetDomainFile(), pAppDomain));
TRACE_FREE(pDM);
DeleteInteropSafe(pDM);
Delete(HASH(pRuntimeModule), (HASHENTRY *) pDME);
_ASSERTE(GetModule(pModule, pAppDomain) == NULL);
return;
}
}

LOG((LF_CORDB, LL_INFO1000, "DMT::RM No debugger module found for Module:0x%x AD:0x%x\n", pModule, pAppDomain));
}


Expand Down Expand Up @@ -337,5 +357,3 @@ DebuggerModule *DebuggerModuleTable::GetNextModule(HASHFIND *info)
else
return entry->module;
}