教你配置windows上的windbg,linux上的lldb,打入clr内部这一篇就够了
一:背景
1. 講故事
前幾天公眾號(hào)里有位兄弟看了幾篇文章之后,也準(zhǔn)備用windbg試試看,結(jié)果這一配就花了好幾天,(づ╥﹏╥)づ,我想也有很多躍躍欲試的朋友在配置的時(shí)候肯定會(huì)遇到這樣和那樣的問(wèn)題,所以我覺(jué)得有必要整理一下,讓大家少走彎路。
二:一些基礎(chǔ)概念
1. 在哪下載
現(xiàn)在安裝windbg越來(lái)越麻煩,還要安裝Windows 10 SDK,很多人就栽在這里,其實(shí)大家可以直接在網(wǎng)上找一鍵打包的windbg 6.0版本即可,才30多M,調(diào)生產(chǎn)調(diào)本地都很方便,順帶還可以練練SOS命令。
云盤(pán):https://pan.baidu.com/s/1VqXVIGVHxAZVPNds1525Jg?提取碼:mahg
外網(wǎng):http://www.33lc.com/soft/96743.html
2. 版本問(wèn)題
解壓打開(kāi)會(huì)有一個(gè)x64和x86文件夾,很顯然,32位的程序用x86下的windbg調(diào)試,64位的程序用x64的windbg調(diào)試,如下圖:
3. 其他的問(wèn)題
我比較喜歡用64bit程序,所以這里使用64位的windbg。
<1> 配置微軟公有符號(hào)
符號(hào)其實(shí)就是pdb文件,我們?cè)赿ebug模式下編譯項(xiàng)目都會(huì)看到這個(gè),它的作用會(huì)對(duì)dll進(jìn)行打標(biāo),這樣在調(diào)試時(shí)通過(guò)pdb就能看到局部變量,全局變量,行號(hào)等等其他信息,在FCL類(lèi)庫(kù)中的pdb文件就放在微軟的公有服務(wù)器上,SRV*C:\mysymbols*http://msdl.microsoft.com/download/symbols。
<2> 理解sos.dll和clr.dll
很多時(shí)候大家都是事后調(diào)試,所以需要在生產(chǎn)上抓一個(gè)dump文件,為了將dump文件逆向到clr上的運(yùn)行時(shí)狀態(tài),你必須要尋找到當(dāng)時(shí)運(yùn)行程序clr版本,同時(shí)也要找到對(duì)應(yīng)clr版本的sos.dll,他們通常是在一起的,sos 就是 你 和 clr交互的渠道,很多人都卡在尋找正確版本的sos和clr版本上。。。如果不清楚,我可以畫(huà)張圖。
有了這個(gè)前置基礎(chǔ),接下來(lái)就可以在windows和centos上進(jìn)行配置實(shí)踐了。。。????????????
三. windows上的 netcore 3.1 配置
為了演示,我先上一段簡(jiǎn)單的代碼:
static void Main(string[] args){var info = "hello world!";Console.WriteLine(info);Console.ReadLine();}1. 尋找clr.dll
在netcore中,clr的名字變成了 coreclr.dll,路徑:C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.3
2. 尋找sos.dll
netcore3.0開(kāi)始,sos就沒(méi)有放在版本號(hào)文件下了,詳見(jiàn)?SOS_README.md?內(nèi)容。
SOS and other diagnostic tools now ship of band and work with any version of the .NET Core runtime. SOS has moved to the diagnostics repo here: https://github.com/dotnet/diagnostics.git. Instructions to install SOS: https://github.com/dotnet/diagnostics#installing-sos.看了上面文檔,大概意思就是說(shuō)老版本的windbg,需要通過(guò)小工具dotnet-sos 自己生成一個(gè)sos.dll,那就按照文檔來(lái)吧
PS C:\WINDOWS\system32> dotnet tool install -g dotnet-sos You can invoke the tool using the following command: dotnet-sos Tool 'dotnet-sos' (version '3.1.122203') was successfully installed. PS C:\WINDOWS\system32> dotnet-sos install Installing SOS to C:\Users\hxc\.dotnet\sos from C:\Users\hxc\.dotnet\tools\.store\dotnet-sos\3.1.122203\dotnet-sos\3.1.122203\tools\netcoreapp2.1\any\win-x64 Installing over existing installation... Creating installation directory... Copying files... Execute '.load C:\Users\hxc\.dotnet\sos\sos.dll' to load SOS in your Windows debugger. Cleaning up... SOS install succeeded PS C:\WINDOWS\system32>仔細(xì)看輸出,sos.dll 已經(jīng)生成好了,接下來(lái)在任務(wù)管理器中生成一個(gè)dump文件,然后使用 .load 命令把 coreclr 和 sos 加載進(jìn)去即可。
.load C:\Users\hxc\.dotnet\sos\sos.dll .load C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.3\coreclr.dll最后我們抓一下?info?變量在堆上的分布。
0:000> ~0s ntdll!ZwReadFile+0x14: 00007ff8`3228aa64 c3 ret0:000> !clrstack -l OS Thread Id: 0x41d4 (0)000000246097EA40 00007FFF89C50F97 Error: Fail to initialize CoreCLR 80131022 ConsoleApp5.Program.Main(System.String[])LOCALS:0x000000246097EA68 = 0x0000021d8141aba80:000> !do 0x0000021d8141aba8 Name: System.String MethodTable: 00007fff89cd1e18 EEClass: 00007fff89cc2128 Size: 46(0x2e) bytes File: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.3\System.Private.CoreLib.dll String: hello world! Fields:MT Field Offset Type VT Attr Value Name 00007fff89c1b1e8 4000242 8 System.Int32 1 instance 12 _stringLength 00007fff89c18000 4000243 c System.Char 1 instance 68 _firstChar 00007fff89cd1e18 4000244 110 System.String 0 static 0000021d81411360 Empty好了,windows上的netcore調(diào)試就這么簡(jiǎn)單,希望這些配置能節(jié)省您的時(shí)間。
四. windows 上的 netframework 配置
framework程序比netcore配置要方便的多,不需要自己去生成sos了,如下代碼所示:
64位程序加載路徑.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll32位程序加載路徑.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll.load C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll五. centos 上的 netcore 3.1 配置
首先要明白,對(duì)于linux內(nèi)核windbg就失效了,那怎么調(diào)試呢?有兩種方式。
1. 使用netcore內(nèi)置的dotnet-dump 小工具
這個(gè)工具????????的地方在于,sos和clr都不需要你配置,直接使用它生成dump,然后直接調(diào)試,方便至極,下面看看怎么安裝,開(kāi)兩個(gè)terminal,如下代碼:
terminal 1:[root@10-25-198-96 data]# dotnet build [root@10-25-198-96 netcoreapp3.1]# dotnet data.dll hello worldterminal 2:[root@10-25-198-96 cs2]# ps -ef | grep dotnet root 31555 31247 0 22:28 pts/0 00:00:00 dotnet cs2.dll root 32112 31995 0 22:29 pts/2 00:00:00 grep --color=auto dotnet[root@10-25-198-96 cs2]# dotnet tool install -g dotnet-dump You can invoke the tool using the following command: dotnet-dump Tool 'dotnet-dump' (version '3.1.122203') was successfully installed. [root@10-25-198-96 cs2]# export PATH=$PATH:$HOME/.dotnet/tools [root@10-25-198-96 cs2]# dotnet-dump collect --process-id 31555 Writing full to /cs2/core_20200508_223204 Complete可以看到dump文件已經(jīng)好了?/cs2/core_20200508_223204?,接下來(lái)用 dotnet-dump 對(duì)dump文件調(diào)試。
[root@10-25-198-96 cs2]# dotnet-dump analyze /cs2/core_20200508_223204 Loading core dump: /cs2/core_20200508_223204 ... Ready to process analysis commands. Type 'help' to list available commands or 'help [command]' to get detailed help on a command. Type 'quit' or 'exit' to exit the session. > clrstack -l OS Thread Id: 0x7b43 (0)Child SP IP Call Site 00007FFDFCABF2D0 00007fb0397af7fd [InlinedCallFrame: 00007ffdfcabf2d0] Interop+Sys.ReadStdin(Byte*, Int32) 00007FFDFCABF2D0 00007fafbebbb4db [InlinedCallFrame: 00007ffdfcabf2d0] Interop+Sys.ReadStdin(Byte*, Int32) 00007FFDFCABF2C0 00007FAFBEBBB4DB ILStubClass.IL_STUB_PInvoke(Byte*, Int32)00007FFDFCABF9D0 00007FAFBECF844D System.Console.ReadLine()00007FFDFCABF9E0 00007FAFBEBB037D cs2.Program.Main(System.String[]) [/cs2/Program.cs @ 13]LOCALS:0x00007FFDFCABF9F0 = 0x00007faf980081d800007FFDFCABFD08 00007fb037fc0f7f [GCFrame: 00007ffdfcabfd08] 00007FFDFCAC01F0 00007fb037fc0f7f [GCFrame: 00007ffdfcac01f0] > dumpobj 0x00007faf980081d8 Name: System.String MethodTable: 00007fafbec30f90 EEClass: 00007fafbeb9e1b0 Size: 44(0x2c) bytes File: /usr/share/dotnet/shared/Microsoft.NETCore.App/3.1.3/System.Private.CoreLib.dll String: hello world Fields:MT Field Offset Type VT Attr Value Name 00007fafbec2a0e8 400022a 8 System.Int32 1 instance 11 _stringLength 00007fafbec26f00 400022b c System.Char 1 instance 68 _firstChar 00007fafbec30f90 400022c 108 System.String 0 static 00007faf97fff360 Empty >就這么簡(jiǎn)單,不過(guò)這個(gè)工具雖好,但是不能調(diào)試非托管堆,而且命令也不是太多,當(dāng)然夠我們平時(shí)用了。
2. 使用linux專(zhuān)屬的lldb調(diào)試器
要想實(shí)現(xiàn)windbg級(jí)別的調(diào)試,可以使用lldb調(diào)試器,這個(gè)非常強(qiáng)大,這里我也來(lái)介紹一下吧。
<1> 安裝lldb
lldb是使用C++寫(xiě)的,也可以在?https://github.com/dotnet/diagnostics/blob/master/documentation/building/linux-instructions.md?尋找安裝辦法。
sudo yum install centos-release-SCL epel-release sudo yum install cmake cmake3 gcc gcc-c++ gdb git libicu libunwind make python27 tar wget which zip cd $HOME git clone https://github.com/dotnet/diagnostics.git $HOME/diagnostics/documentation/lldb/centos7/build-install-lldb.sh一陣抽搐后就安裝好了,從下面可以看到目前版本是3.9.1。
[root@10-25-198-96 cs2]# lldb -v lldb version 3.9.1 ( revision )<2> 尋找sos.dll
跟windbg一樣,你需要生成一個(gè)sos.dll 。。。同樣也是使用 dotnet-sos 生成。
[root@10-25-198-96 cs2]# dotnet tool install -g dotnet-sos You can invoke the tool using the following command: dotnet-sos Tool 'dotnet-sos' (version '3.1.122203') was successfully installed. [root@10-25-198-96 cs2]# dotnet-sos install Installing SOS to /root/.dotnet/sos from /root/.dotnet/tools/.store/dotnet-sos/3.1.122203/dotnet-sos/3.1.122203/tools/netcoreapp2.1/any/linux-x64 Installing over existing installation... Creating installation directory... Copying files... Updating existing /root/.lldbinit file - LLDB will load SOS automatically at startup Cleaning up... SOS install succeeded從上面信息看,sos 是安裝在?/root/.dotnet/sos?目錄下,同時(shí)也看到在lldb啟動(dòng)的時(shí)候會(huì)自動(dòng)加載sos.dll 。。。
<3> 使用createdump 生成dump文件
每個(gè)dotnet版本下都有一個(gè)createdump程序,可以用它生成dump文件,具體配置文檔可以參見(jiàn):
https://github.com/dotnet/diagnostics/blob/master/documentation/debugging-coredump.md
https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/xplat-minidump-generation.md#configurationpolicy
[root@10-25-198-96 cs2]# ps -ef | grep dotnet root 31555 31247 0 22:28 pts/0 00:00:00 dotnet cs2.dll root 32112 31995 0 22:29 pts/2 00:00:00 grep --color=auto dotnet[root@10-25-198-96 cs2]# find / -name createdump /usr/share/dotnet/shared/Microsoft.NETCore.App/3.1.3/createdump[root@10-25-198-96 3.1.3]# ./createdump 31555 -f /lldb/test.dump Writing minidump with heap to file /lldb/test.dump Written 84692992 bytes (20677 pages) to core file[root@10-25-198-96 3.1.3]# lldb --core /lldb/test.dump (lldb) target create --core "/lldb/test.dump" Core file '/lldb/test.dump' (x86_64) was loaded. (lldb) clrstack -l OS Thread Id: 0x7b43 (1) 00007FFDFCABF9E0 00007FAFBEBB037D cs2.Program.Main(System.String[]) [/cs2/Program.cs @ 13]LOCALS:0x00007FFDFCABF9F0 = 0x00007faf980081d800007FFDFCABFD08 00007fb037fc0f7f [GCFrame: 00007ffdfcabfd08] 00007FFDFCAC01F0 00007fb037fc0f7f [GCFrame: 00007ffdfcac01f0] (lldb) dumpobj 0x00007faf980081d8 Name: System.String MethodTable: 00007fafbec30f90 EEClass: 00007fafbeb9e1b0 Size: 44(0x2c) bytes File: /usr/share/dotnet/shared/Microsoft.NETCore.App/3.1.3/System.Private.CoreLib.dll String: hello world Fields:MT Field Offset Type VT Attr Value Name 00007fafbec2a0e8 400022a 8 System.Int32 1 instance 11 _stringLength 00007fafbec26f00 400022b c System.Char 1 instance 68 _firstChar 00007fafbec30f90 400022c 108 System.String 0 static 00007faf97fff360 Empty (lldb)可以看到,通過(guò)lldb也可以直接打入clr內(nèi)部啦。。。
六:總結(jié)
我覺(jué)得這篇文章肯定能給很多朋友節(jié)省不少的時(shí)間,想起朱一旦的那句話(huà):有錢(qián)人的快樂(lè),就是這么樸實(shí)無(wú)華且枯燥, 哈哈~~~
總結(jié)
以上是生活随笔為你收集整理的教你配置windows上的windbg,linux上的lldb,打入clr内部这一篇就够了的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 陌陌的 Service Mesh 探索与
- 下一篇: Autofac在.NET Core 中的