利用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扩展库进入高阶.NET6程序的调试

我们还可以运行其他 SOS 命令(如clrThreads) 来找出所有管理线程,为此我们输入:

sos clrThreads

利用SOS扩展库进入高阶.NET6程序的调试

如果您想自己尝试其他 SOS 命令,它们会列在 . NET 框架文档

希望这对你有用!

3.4 Windows上调试的支持

还可以通过将 SOS 调试扩展加载到 WinDbg/dbg 调试程序中并在 Windows 调试程序中执行命令来使用此扩展。可对实时进程或转储使用 SOS 命令。

欢迎尝试Windbg 预览版【微软商店】,千年不变的界面终于焕然一新。

利用SOS扩展库进入高阶.NET6程序的调试
安装sos依然是这些命令:

dotnet tool install --global dotnet-sos 
dotnet-sos install

安装后,可以在windbg内加载它

. Load %userprofile%\.Dotnet\SOS\sos.dll

然后在任务管理器中找到这个进程,保存dump文件到临时目录,利用windbg打开,并加载sos.dll.

!clrstack -a

利用SOS扩展库进入高阶.NET6程序的调试

当然你可以根据需要键入不同的调试命令进行跟踪分析。

!runaway
!threadpool
!continue
!syncblk

4. 小结

高阶调试是不是把你学fei了?