一、背景
1. 讲故事
最新版本 1.2402.24001.0 的WinDbg真的让人很兴奋,可以将自己伪装成 GDB 来和远程的 GDBServer 打通来实现对 Linux 上 .NET程序进行调试,这样就可以继续使用熟悉的WinDbg 命令,在这个版本中我觉得 WinDbg 不再是 WinDbg,而是 XDbg 了,画个简图如下:
图片
简图有了,接下来就要付出实践了。
二、实操 Linux 上 .NET调试
1. 测试程序
本想在 CentOS7 上安装 .NET8,不大好装,这里就用一个现存的 .NETCore 3.1 吧,测试代码如下:
代码非常简单,就是1s输出一条记录,接下来编译成x64部署到 Centos7 上。
2. 安装GDBServer
在 linux 上安装 gdbserver 比较简单,使用 yum 安装即可 yum install gdb-gdbserver ,输出如下:
安装好之后,接下来用 gdbserver 来启动我们的程序,并启动调试端口为 1234,参考如下:
3. 使用 windbg 连接
打开Windbg后,选择 Connect to remote debugger 选项, 在连接字符串中填入 gdb:server=192.168.128.130,port=1234 即可,截图如下:
图片
连接好之后,会有一个初始中断,直接输入g就好了,输出如下:
有些人可能会好奇,为什么 WinDbg 能伪装成 GDB 来和 GDBServer 来通讯,这其实得益于 WinDbg 是一个宿主,它可以被很多外来的插件无线扩容自己的功能,这和 Linux 的分而治之恰恰相反。。。
接下来可以用 .chain 命令观察插件列表,其中的 GDBServerComposition 和 ELFBinComposition 让这项功能得到实现。
接下来就可以做验证了,研究 coreclr 源码,你会发现在 Linux 上 .NET 的 Sleep 函数是借助于底层的 pthread_cond_timedwait 函数,Linux并没有提供类似Windows 的SleepEx这样的系统调用,这就比较坑了,参考如下:
图片
不管怎么说,我们用 WinDbg 调试 Linux 的 .NET 程序算是大功告成了。
三、总结
现在的 WinDbg 早已今非昔比,全平台(MacOs,Linux,Windows) 通吃,这也得益于 Windbg 是一个宿主模式的架构体系,给 WinDbg 点赞!