From 72063e16410e3f3d89a1c346f50fc38f5a691093 Mon Sep 17 00:00:00 2001 From: Eugene Zemtsov Date: Fri, 5 Jun 2015 15:03:44 -0700 Subject: [PATCH] Fix bug: CoreCLR debugger couldn't make more than one EnC edit to a method. Second and all further attempts failed, moreover sometimes VS debugger would crash with AV trying to do EnC. (TFS bug #1172983) [tfs-changeset: 1483755] --- src/debug/di/helpers.h | 6 +++++- src/debug/di/module.cpp | 13 +++++++++++-- src/md/enc/metamodelenc.cpp | 6 +++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/debug/di/helpers.h b/src/debug/di/helpers.h index c76d5db..11a26dd 100644 --- a/src/debug/di/helpers.h +++ b/src/debug/di/helpers.h @@ -122,7 +122,11 @@ public: FORCEINLINE TYPE** operator & () { - // We allow getting the address so we can pass it in as an outparam. + // We allow getting the address so we can pass it in as an outparam. + // BTW/@TODO: this is a subtle and dangerous thing to do, since it easily leads to situations + // when pointer gets assigned without the ref counter being incremented. + // This can cause premature freeing of the object after the pointer dtor was called. + // But if we have a non-null m_Ptr, then it may get silently overwritten, // and thus we'll lose the chance to call release on it. // So we'll just avoid that pattern and assert to enforce it. diff --git a/src/debug/di/module.cpp b/src/debug/di/module.cpp index f9ecf43..1edbe13 100644 --- a/src/debug/di/module.cpp +++ b/src/debug/di/module.cpp @@ -2202,8 +2202,17 @@ HRESULT CordbModule::ApplyChanges(ULONG cbMetaData, (void **)&pMDImport)); // The left-side will call this same method on its copy of the metadata. - IfFailGo(pMDImport->ApplyEditAndContinue(pbMetaData, cbMetaData, &pMDImport2)); - pMDImport2->AddRef(); // @todo - issue in ApplyEditAndContinue, doesn't addref the out parameter. + hr = pMDImport->ApplyEditAndContinue(pbMetaData, cbMetaData, &pMDImport2); + if (pMDImport2 != NULL) + { + // ApplyEditAndContinue() expects IMDInternalImport**, but we give it RSExtSmartPtr + // Silent cast of RSExtSmartPtr to IMDInternalImport* leads to assignment of a raw pointer + // without calling AddRef(), thus we need to do it manually. + + // @todo - ApplyEditAndContinue should probably AddRef the out parameter. + pMDImport2->AddRef(); + } + IfFailGo(hr); // We're about to get a new importer object, so release the old one. diff --git a/src/md/enc/metamodelenc.cpp b/src/md/enc/metamodelenc.cpp index 1b3c733..e19cf7a 100644 --- a/src/md/enc/metamodelenc.cpp +++ b/src/md/enc/metamodelenc.cpp @@ -264,14 +264,18 @@ CMiniMdRW::ApplyDelta( return E_INVALIDARG; } +#ifndef FEATURE_CORECLR // Verify that the delta is based on the base. IfFailGo(mdDelta.getEncBaseIdOfModule(pModDelta, &GuidDelta)); IfFailGo(getEncBaseIdOfModule(pModBase,&GuidBase)); - if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_DeltaCheck) && (GuidDelta != GuidBase)) + if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_DeltaCheck) && + CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas) && + (GuidDelta != GuidBase)) { _ASSERTE(!"The Delta MetaData is based on a different generation than the current MetaData."); return E_INVALIDARG; } +#endif //!FEATURE_CORECLR // Let the other md prepare for sparse records. IfFailGo(mdDelta.StartENCMap()); -- 2.7.4