您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何為WinDbg編寫ClrMD插件,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
當遷移到Linux時,由于LLDB是Linux上.NET網絡核心的通用調試器,因此我決定編寫一個兼容層,以便能夠在新環境中加載擴展。
如何創建一個適用于WinDbg和LLDB的擴展?第一步仍然是創建一個新的類庫項目。無論是.NET Framework和.NET Standard都可以,但有些事情需要注意:
1.如果選擇.NET Framework,請確保不要使用與.NET Core不兼容的任何功能(例如AppDomain),否則您將無法在LLDB中運行擴展;
2.如果選擇.NET Standard,請記住發布項目以將所有依賴項包含在一個文件夾中,因為在編譯時默認情況下不會這樣做
創建項目后,添加對ClrMDExports nuget包的引用。它會自動將ClrMD和UnmanagedExports.Repack作為依賴項。UnmanagedExports.Repack是UnmanagedExports的一個分支,它增加了與.NET Framework 4.7+和.NET Standard的兼容性,并支持PackageReference。
請注意,新的Init.cs文件將添加到您的項目中(如果您使用包引用,則不應該看到它)。不要對此文件進行任何更改。每次更新nuget包時都會被覆蓋。
Init文件負責導出WinDbg所需的DebugExtensionInitialize方法,并設置所有內容,只要依賴項與擴展位于相同的文件夾中,就可以正確加載它們。
下一步是添加自定義命令。您需要為每個命令創建一個靜態方法,并使用以下簽名:
public static void HelloWorld(IntPtr client, [MarshalAs(UnmanagedType.LPStr)] string args) { }
然后使用UnmanagedExports附帶的DllExport屬性裝飾它。您可以使用ExportName
屬性的參數來定義WinDbg / LLDB可見的命令名稱。請記住,名稱區分大小寫!
[DllExport("helloworld")] public static void HelloWorld(IntPtr client, [MarshalAs(UnmanagedType.LPStr)] string args) { }
在該方法中,您應該只調用DebuggingContext.Execute
由ClrMDExports提供的方法。它接受client
和args
作為參數的值,以及帶有(ClrRuntime runtime, string args)
簽名的另一個靜態方法的委托。在靜態回調方法中,實現命令。
[DllExport("helloworld")] public static void HelloWorld(IntPtr client, [MarshalAs(UnmanagedType.LPStr)] string args) { DebuggingContext.Execute(client, args, HelloWorld); } private static void HelloWorld(ClrRuntime runtime, string args) { Console.WriteLine("The first 10 types on the heap are: "); foreach (var type in runtime.Heap.EnumerateTypes().Take(10)) { Console.WriteLine(type); } }
為方便起見,控制臺輸出會自動重定向到調試器。
您可以直接在WinDbg中加載和使用您的擴展:
由于擴展是為WinDbg API編寫的,因此無法直接加載到LLDB中。相反, 我編寫了一個進行翻譯的插件。
首先,下載最新版本的LLDB-LoadManaged元插件并將其解壓縮到一個文件夾中。
然后啟動LLDB并附加到目標:
./lldb -c dump.dmp
接下來,加載元插件:
plugin load ./loadmanaged/libloadmanaged.so
確保Mono.Cecil.dll和PluginInterop.dll文件與libloadmanaged.so位于同一文件夾中。
加載后,LLDB-LoadManaged將嘗試通過瀏覽調試目標中加載的模塊來定位CoreCLR。如果失敗(例如,因為您在與目標不同的機器上運行lldb),您可以通過調用SetClrPath
以下命令手動設置路徑:
SetClrPath /usr/local/share/dotnet/shared/Microsoft.NETCore.App/2.2.0/
最后,使用以下LoadManaged
命令加載WinDbg擴展:
LoadManaged /home/k.gosse/TestExtension.dll
(該LoadManaged
命令尚不支持相對路徑)
就是這樣!現在,您可以像在WinDbg中一樣調用擴展程序。
注意:libloadmanaged.so和libsosplugin.so都會根據自己的需要托管CLR。但是,.NET Core CLR不支持并排方案。這意味著我們不能同時使用LoadManaged和SOS插件。這可以講是一個限制,它不太可能在.NET Core端修復。我們這里有一種解決方法,可以通過LoadManaged加載并替換libsosplugin.so的SOS托管版本。
關于如何為WinDbg編寫ClrMD插件就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。