官方的 dnSpy 在 2021 時,由于某些吃瓜的原因 wtfsck 將 dnSpy 給 Archived 掉,在大佬被哄好之前,預計是不再更新。最新官方版本對 dotnet 6 的支持較弱,對于很多 dotnet 6 應用都無法成功調試,附加調試上去將會讓應用卡住。好在 dnSpy 是開源的,也剛好 lsj 大佬改得動,于是改了一個支持 dotnet 6 的版本
什么是 dnSpy 神器?請看?神器如 dnSpy,無需源碼也能修改 .NET 程序 - walterlv
我現在使用最多的調試工具,除了 VisualStudio 之外,就是 dnSpy 工具了。使用 dnSpy 可以讓我方便調試用戶端的應用。在完成了將團隊里面最大的項目升級到 dotnet 6 時,就在升級過程遇到了一些問題,想要調試,卻發現沒有合適的工具,詳細請看 dotnet 6 在 Win7 系統證書鏈錯誤導致 HttpWebRequest 內存泄露
為了讓我減少加班,我請了?lsj?幫忙改改 dnSpy 神器,讓 dnSpy 可以調試 dotnet 6 的應用
這是支持 dotnet 6 版本的 dnSpy 神器下載地址,也是修改之后開源的地址:https://github.com/kkwpsv/dnSpy/releases/tag/6.1.9
如果大家下載不了,可以發郵件讓我用其他方式發給你
那改好了是不是就完成了?還有一個問題是為什么 dnSpy 對 dotnet 6 的支持較弱呢?有以下幾個原因,對應的修復方法還請看 lsj 的改動 https://github.com/kkwpsv/dnSpy/commit/a217b257453147c5d9db45070f7555f6395329bf
如?[DAC][DBI] ICorDebugModule::GetMetaDataInterface fails in net6.0 for "Anonymously Hosted DynamicMethods Assembly" in unit test project. · Issue #62977 · dotnet/runtime?所說的原因,由于?"Anonymously Hosted DynamicMethods Assembly"
?沒有定義 IMetaDataImport2 接口,因此在?https://github.com/dnSpy/dnSpy/blob/2b6dcfaf602fb8ca6462b8b6237fdfc0c74ad994/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet.CorDebug/Impl/ModuleCreator.cs#L94-L96?將拿到空,如以下代碼,將拋出 InvalidOperationException 錯誤
var comMetadata = dnModule.CorModule.GetMetaDataInterface<IMetaDataImport2>();if (comMetadata is null)throw new InvalidOperationException();
修復的方式就是不拋出異常,而是自己定義一個 繼承 DmdLazyMetadataBytes 類型的 DmdLazyMetadataBytesNull 類型,進行返回,如以下代碼
if (comMetadata is null)// "Anonymously Hosted DynamicMethods Assembly" not implement IMetaDataImport2, we just return DmdLazyMetadataBytesNullreturn () => new DmdLazyMetadataBytesNull();
同時在 DmdAppDomainImpl.cs 里面,返回 DmdNullMetadataReader 即可,如此也許會影響讀取程序集的信息,但好過無法調試
這個?"Anonymously Hosted DynamicMethods Assembly"
?沒有定義 IMetaDataImport2 接口,也影響 https://github.com/dnSpy/dnSpy/blob/2b6dcfaf602fb8ca6462b8b6237fdfc0c74ad994/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet.CorDebug/dndbg/Engine/CorAssembly.cs#L56-L60?的代碼,如以下代碼,拿到的 ManifestModule 是空值。好在這里只是在 dnSpy 應用的 Debug 模式才會炸掉
var module = ManifestModule;Debug2.Assert(module is not null);
修復的方法只是將 Assert 的代碼干掉即可
經過以上更改,就可以讓 dnSpy 支持 dotnet 6 的調試
嗯,現在我覺得 dnSpy 作者做的還是太對了,我似乎越來越覺得開源也是一個不對的事情,那就是 SB 太多了。本來今天是想著將 dnSpy 在堆棧網上廣告一下,造福一下國外的小伙伴。可惜遇到了傻比,最后我將問題和回答都刪除了。這個事讓我更加理解了很多開源作者最后選擇了閉源的做法,以及讓我更加佩服維護社區的大佬們。有人問,原作者關閉了 dnSpy 的瓜是什么?其中一個瓜就是被傻子給氣的,開源了不收錢了,反而被當成理所當然,還要這要那,不滿足了還被罵。具體的瓜還請自己去找了
我認為所有的參與開源和分享知識的行為都理應受到表揚稱贊,共同維護一個良好的開發者生態
十分感謝?wtfsck?大佬提供的 dnSpy 神器,和?lsj?讓 dnSpy 支持 dotnet 6 調試