From b2b0db0c470eba512d358dcf3d359488083e82a8 Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Fri, 26 Jul 2024 15:17:41 -0700 Subject: [PATCH] Fix SOS !dumpmt -md command (#105575) * Fix SOS !dumpmt -md command The new virtual method slot enumerator failed if any of the Precode slot values were not in the dump. There are usually 2 or so that are invalid/not in dump but that should not stop/fail the new enumeration DAC API. Part of this is to make MethodTable::GetMethodDescForSlot_NoThrow not throw a read exception and return a null MD. * Code review feedback - move CATCH to request.cpp --- src/coreclr/debug/daccess/request.cpp | 33 ++++++++++++++++++--------- src/coreclr/vm/method.cpp | 5 ++-- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index b4de3332da23f7..33a8ad66354359 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -490,20 +490,31 @@ ClrDataAccess::GetMethodTableSlotEnumerator(CLRDATA_ADDRESS mt, ISOSMethodEnum * HRESULT DacMethodTableSlotEnumerator::Init(PTR_MethodTable mTable) { - unsigned int slot = 0; - WORD numVtableSlots = mTable->GetNumVtableSlots(); - while (slot < numVtableSlots) + for (WORD slot = 0; slot < numVtableSlots; slot++) { - MethodDesc* pMD = mTable->GetMethodDescForSlot_NoThrow(slot); - SOSMethodData methodData = {0}; - methodData.MethodDesc = HOST_CDADDR(pMD); - methodData.Entrypoint = mTable->GetSlot(slot); - methodData.DefininingMethodTable = PTR_CDADDR(pMD->GetMethodTable()); - methodData.DefiningModule = HOST_CDADDR(pMD->GetModule()); - methodData.Token = pMD->GetMemberDef(); + SOSMethodData methodData = {0, 0, 0, 0, 0, 0}; + MethodDesc* pMD = nullptr; + + EX_TRY + { + pMD = mTable->GetMethodDescForSlot_NoThrow(slot); + } + EX_CATCH + { + } + EX_END_CATCH(SwallowAllExceptions) - methodData.Slot = slot++; + if (pMD != nullptr) + { + methodData.MethodDesc = HOST_CDADDR(pMD); + methodData.DefininingMethodTable = PTR_CDADDR(pMD->GetMethodTable()); + methodData.DefiningModule = HOST_CDADDR(pMD->GetModule()); + methodData.Token = pMD->GetMemberDef(); + } + + methodData.Entrypoint = mTable->GetSlot(slot); + methodData.Slot = slot; if (!mMethods.Add(methodData)) return E_OUTOFMEMORY; diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 4f7e9d1cc825a9..d8313fdc965162 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -2624,7 +2624,7 @@ MethodDesc* MethodDesc::GetMethodDescFromStubAddr(PCODE addr, BOOL fSpeculative } CONTRACT_END; - MethodDesc * pMD = NULL; + MethodDesc* pMD = NULL; // Otherwise this must be some kind of precode // @@ -2633,10 +2633,9 @@ MethodDesc* MethodDesc::GetMethodDescFromStubAddr(PCODE addr, BOOL fSpeculative if (pPrecode != NULL) { pMD = pPrecode->GetMethodDesc(fSpeculative); - RETURN(pMD); } - RETURN(NULL); // Not found + RETURN(pMD); } //*******************************************************************************