利用SOS扩展库进入高阶.NET6程序的调试
有時候我們可能想深入到程序的運行核心,去觀察下內存分配情況以及堆棧內保存的東東,那么作為編程新貴的底層框架.NET6,又為我們提供了什么可用的觀測工具呢?
1.SOS 擴展是什么?
SOS擴展庫是Windows 附帶的調試擴展庫,它允許開發人員在 WinDbg、CDB 或 NTSD 中調試托管代碼,請記住,當您執行托管二進制文件時,運行時會生成特定于平臺的本機代碼,而SOS 擴展允許您以“托管方式”調試本機代碼。
最最主要的是,SOS 調試擴展允許您查看有關在** .NET Core 運行時**運行的代碼的信息,包括實時進程和轉儲文件。
2. SOS支持跨平臺嗎?
是的,sos已經有mac、liunx和windows上的各個版本,它們支持不同的內核核心,可以用到不同的平臺上進行擴展調試。
3.如何開始使用SOS?
sos擴展必須附加到別的調試工具上,因此其并不能獨立運行。
為了調試.net 6程序,我們分別在不同的平臺使用不同的工具進行演示。
3.1 Linux平臺上使用LLDB工具
第一步是安裝調試器LLDB。LLDB 與 WinDbg 非常相似,也是 SOS 團隊一直在使用的調試器,因此我采用它作為 Linux 的默認調試器。
您可以從以下鏈接安裝 LLDB:
https://lldb.llvm.org/download.html
或者您也可以通過運行以下命令來安裝它:
yum install lldb
在 Linux 機器上安裝 lldb 后,打開終端 并通過在提示符下鍵入以下命令來啟動調試器:
lldb
如果 lldb 已正確啟動,您將獲得如下所示的 lldb 提示。
3.2 Linux 平臺安裝sos
沒有sos擴展的加持,你是無法調試.NET程序的,因此還需要安裝sos擴展。目前dotnet提供了簡易安裝方式,我們只需要錄入下列命令即可。
dotnet tool install --global dotnet-sos dotnet-sos install默認安裝的sos是和你cpu架構一致的版本,如果你需要其他版本,可以指定參數進行安裝。
參數有下列值可用。
Arm
Arm64
X86
X64
例如:
dotnet-sos install --architecture Arm在Linux系統中安裝完sos后,再次啟動LLDB,會默認加載sos擴展的。
3.3 利用LLDB調試程序
先啟動.net 程序,然后利用ps查找進程號。
ps -ef | grep dotnet然后啟動lldb
lldb在lldb命令界面內鍵入附加進程命令:
process attach -p 31339附加dotnet程序進程到分析空間。
Process 31339 stopped
Executable module set to “/tmp/dotnet/bin/Debug/net5.0/dotnet”.
Architecture set to: x86_64–linux-gnu.
一旦附加到 lldb后,就可以顯示線程列表。
您可以運行使用bt命令來檢索當前線程的調用堆棧,但是很難調試它,因為您無法以“托管方式”查看堆棧.
為了測試,讓我們運行clrstack命令,現在我們可以更好地了解正在發生的事情。
我們還可以運行其他 SOS 命令(如clrThreads)?來找出所有管理線程,為此我們輸入:
sos clrThreads
如果您想自己嘗試其他 SOS 命令,它們會列在 .?NET 框架文檔
希望這對你有用!
3.4 Windows上調試的支持
還可以通過將 SOS 調試擴展加載到 WinDbg/dbg 調試程序中并在 Windows 調試程序中執行命令來使用此擴展。可對實時進程或轉儲使用 SOS 命令。
歡迎嘗試Windbg 預覽版【微軟商店】,千年不變的界面終于煥然一新。
安裝sos依然是這些命令:
安裝后,可以在windbg內加載它
. Load %userprofile%\.Dotnet\SOS\sos.dll然后在任務管理器中找到這個進程,保存dump文件到臨時目錄,利用windbg打開,并加載sos.dll.
!clrstack -a當然你可以根據需要鍵入不同的調試命令進行跟蹤分析。
!runaway !threadpool !continue !syncblk4. 小結
高階調試是不是把你學fei了?恩,學這個跟下篇文章有些瓜葛,因此不得不先介紹下調試器的使用。
👓都看到這了,還在乎點個贊嗎?
👓都點贊了,還在乎一個收藏嗎?
👓都收藏了,還在乎一個評論嗎?
總結
以上是生活随笔為你收集整理的利用SOS扩展库进入高阶.NET6程序的调试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于事件驱动架构构建微服务第13部分:使
- 下一篇: 秘境探索之一个.NET 对象从内存分配到