天天看點

教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了

一:背景

1. 講故事

前幾天公衆号裡有位兄弟看了幾篇文章之後,也準備用windbg試試看,結果這一配就花了好幾天,(づ╥﹏╥)づ,我想也有很多躍躍欲試的朋友在配置的時候肯定會遇到這樣和那樣的問題,是以我覺得有必要整理一下,讓大家少走彎路。

二:一些基礎概念

1. 在哪下載下傳

現在安裝windbg越來越麻煩,還要安裝Windows 10 SDK,很多人就栽在這裡,其實大家可以直接在網上找一鍵打包的windbg 6.0版本即可,才30多M,調生産調本地都很友善,順帶還可以練練SOS指令。

雲盤:https://pan.baidu.com/s/1VqXVIGVHxAZVPNds1525Jg 提取碼:mahg

外網:http://www.33lc.com/soft/96743.html

2. 版本問題

解壓打開會有一個x64和x86檔案夾,很顯然,32位的程式用x86下的windbg調試,64位的程式用x64的windbg調試,如下圖:

教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了

3. 其他的問題

我比較喜歡用64bit程式,是以這裡使用64位的windbg。

<1> 配置微軟公有符号

符号其實就是pdb檔案,我們在debug模式下編譯項目都會看到這個,它的作用會對dll進行打标,這樣在調試時通過pdb就能看到局部變量,全局變量,行号等等其他資訊,在FCL類庫中的pdb檔案就放在微軟的公有伺服器上,

SRV*C:\mysymbols*http://msdl.microsoft.com/download/symbols

教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了

<2> 了解sos.dll和clr.dll

很多時候大家都是事後調試,是以需要在生産上抓一個dump檔案,為了将dump檔案逆向到clr上的運作時狀态,你必須要尋找到當時運作程式clr版本,同時也要找到對應clr版本的sos.dll,他們通常是在一起的,sos 就是 你 和 clr互動的管道,很多人都卡在尋找正确版本的sos和clr版本上。。。如果不清楚,我可以畫張圖。

教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了

有了這個前置基礎,接下來就可以在windows和centos上進行配置實踐了。。。😄😄😄

三. windows上的 netcore 3.1 配置

為了示範,我先上一段簡單的代碼:

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

教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了

2. 尋找sos.dll

netcore3.0開始,sos就沒有放在版本号檔案下了,詳見

SOS_README.md

内容。

教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了
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.

           

看了上面文檔,大概意思就是說老版本的windbg,需要通過小工具dotnet-sos 自己生成一個sos.dll,那就按照文檔來吧

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>

           

仔細看輸出,sos.dll 已經生成好了,接下來在任務管理器中生成一個dump檔案,然後使用 .load 指令把 coreclr 和 sos 加載進去即可。

教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了
.load C:\Users\hxc\.dotnet\sos\sos.dll
.load C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.3\coreclr.dll

           
教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了

最後我們抓一下

info

變量在堆上的分布。

0:000> ~0s
ntdll!ZwReadFile+0x14:
00007ff8`3228aa64 c3              ret

0:000> !clrstack -l
OS Thread Id: 0x41d4 (0)

000000246097EA40 00007FFF89C50F97 Error: Fail to initialize CoreCLR 80131022
ConsoleApp5.Program.Main(System.String[])
    LOCALS:
        0x000000246097EA68 = 0x0000021d8141aba8

0: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調試就這麼簡單,希望這些配置能節省您的時間。

四. 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.dll

32位程式加載路徑

 .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 配置

首先要明白,對于linux核心windbg就失效了,那怎麼調試呢? 有兩種方式。

1. 使用netcore内置的dotnet-dump 小工具

這個工具🐮👃的地方在于,sos和clr都不需要你配置,直接使用它生成dump,然後直接調試,友善至極,下面看看怎麼安裝,開兩個terminal,如下代碼:

terminal 1:

[root@10-25-198-96 data]# dotnet build
[root@10-25-198-96 netcoreapp3.1]# dotnet data.dll
hello world


terminal 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檔案已經好了

/cs2/core_20200508_223204

,接下來用 dotnet-dump 對dump檔案調試。

[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 = 0x00007faf980081d8

00007FFDFCABFD08 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
>    

           

就這麼簡單,不過這個工具雖好,但是不能調試非托管堆,而且指令也不是太多,當然夠我們平時用了。

2. 使用linux專屬的lldb調試器

要想實作windbg級别的調試,可以使用lldb調試器,這個非常強大,這裡我也來介紹一下吧。

<1> 安裝lldb

lldb是使用C++寫的,也可以在

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一樣,你需要生成一個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

目錄下,同時也看到在lldb啟動的時候會自動加載sos.dll 。。。

<3> 使用createdump 生成dump檔案

每個dotnet版本下都有一個createdump程式,可以用它生成dump檔案,具體配置文檔可以參見:

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 = 0x00007faf980081d8

00007FFDFCABFD08 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) 

           

可以看到,通過lldb也可以直接打入clr内部啦。。。

六: 總結

我覺得這篇文章肯定能給很多朋友節省不少的時間,想起朱一旦的那句話:有錢人的快樂,就是這麼樸實無華且枯燥, 哈哈~~~

感謝

龍式坦克

的提醒:

現在大家基本上都是64bit的機器,你的預設任務管理器也是64位,如果你要抓上面32位程式的dump檔案,需要啟用32位程式管理器。

路徑:

C:\Windows\SysWOW64\taskmgr.exe

都說 虎牙直播 是使用 netcore 寫的,可以用windbg去玩玩它。

教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了

不過有點奇怪的是,在我的機器上預設跑的是netframework4.5版本。

0:000> !dumpdomain 007b6bb8
--------------------------------------
Domain 1:           007b6bb8
LowFrequencyHeap:   007b7024
HighFrequencyHeap:  007b7070
StubHeap:           007b70bc
Stage:              OPEN
SecurityDescriptor: 007b7df8
Name:               HuyaClient.exe
Assembly:           007eb870 [C:\Program Files (x86)\HuyaLive\HuyaClient\Net45\HuyaClient.exe]
ClassLoader:        007eb928
SecurityDescriptor: 007ecaa0
  Module Name
008a403c    C:\Program Files (x86)\HuyaLive\HuyaClient\Net45\HuyaClient.exe

Assembly:           007ea848 [C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.dll]
ClassLoader:        007f0eb8
SecurityDescriptor: 007ec990
  Module Name
5d8b1000    C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.dll


           
教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了

這裡面更多的秘密,期待您的挖掘。。。。

如您有更多問題與我互動,掃描下方進來吧~

教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了
教你配置windows上的windbg,linux上的lldb,打入clr内部這一篇就夠了