.NET / Rotor源码研究3 – 调试Rotor托管代码的利器:WinDbg和SOS

news/2025/1/25 20:53:24

WinDbg+SOS简介

在动手进一步研究Rotor之前,我们需要首先解决一个问题:用什么调试工具最好? 很有可能你会说,这还不简单,直接用Visual Studio不就好了?一般情况下是的,只不过,在这个情况下,Visual Studio并非是最好的选择:

1.     CLR对代码的编译是动态进行的(其实还有可能是静态的,称之为Prejit或者NGEN,不过可惜Rotor对此不支持),也就是说常规的设置断点的方法并不适用,因为可能这个时候对应的本地代码还没有生成呢

2.     CLR是一个复杂的运行时环境/虚拟机。有些时候我们需要获得CLR的一些相关信息,而这个时候Visual Studio就显得功能不够强大

你可能会说,那为什么VS可以调试托管代码呢?确实,VS是可以调试托管代码,但是注意我们是调试CLR本身,这个时候VS本身的对托管代码的调试功能会造成不少麻烦,得到一些你所不希望的结果。此外,由于我们是在调试Rotor,这个时候不能直接运行托管代码,而是要在CLIX的支持下运行,这也使得VS的托管代码调试功能无效。

这个时候,相对而言较好的工具是WinDbg+SOS的组合。

WinDbg是微软提供的Windows下面的免费调试器,具有下面特点:

1.     支持用户模式和内核模式下的调试

2.     支持GUI(虽然看起来是废话,不过WinDbg也有所谓命令行版本NTSD/CDB/KD,相对于这几个调试器而言WinDbg算是很友好的了)

3.     支持远程调试

4.     支持符号服务器和源代码服务器

5.     支持源代码级别的调试(不支持也不用出来混了,呵呵)

6.     非常轻量级,完整地版本仅数十兆(相对于VS而言),如果只需要调试器本身,还可以更小

7.     支持对Dump文件的调试

8.     可扩展

WinDbg可以在下面的地址下载:

32位版本:http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx

64位版本:http://www.microsoft.com/whdc/devtools/debugging/install64bit.mspx

SOS全称是Son of Strike(别问我为什么,我也不知道,这个要问Larry了),是一个WinDbgExtension,加载之后可以给WinDbg提供一些对托管代码调试的命令。值得一提的是,WinDbg也有有限的对托管代码的支持,只不过功能非常有限,需要SOS的帮助。

SOS.NET Framework中和Rotor中均有提供,所以本文中对于WinDbgSOS的描述基本上适用于Rotor和发行版的.NET Framework(而且有可能也将适用于Silverlight)。比如.NET Framework 2.0中的SOSC:/Windows/Microsoft .NET/v2.0.50727下面,而RotorSOS.dll则是在binaries..rotor目录下面(flavorBuild的配置,如CPUDebug/Release,等等)。

SOS可以做到:

1.     输出对象的内容

2.     察看CLR的数据结构

3.     察看代码和堆栈

4.     显示各种历史信息

5.     提供各种诊断信息

SOS有如下限制:

1.     不可以在mscorwks加载之前被使用

2.     无法察看局部对象的名称

3.     以及很多其他的功能

SOS使用方法如下:

1.     使用.loadby / .load 命令加载。但是Rotor下面SOS由于对VC Runtime的依赖会发生Side By Side相关的问题导致无法找到MSVCR80.dll或者MSVCR80D.dll。解决方法在文章最后会提到

2.     !help命令可以提供所有命令的列表

3.     !help faq显示SOS使用的方法

4.     !help 显示具体Command的帮助

WinDbg+SOS的优势在于:

1.     WinDbg的本地代码(非托管代码)调试功能非常强,甚至比VS还强大,只是需要一些时间习惯

2.     SOS是调试托管代码必须的,提供一些基本功能如设置对托管代码的断点,显示变量和Stack,等等

3.     SOS可以用来查询对CLR内部的状态,如GCHeapMethodTableMethodDescModuleAssembly等等各种信息,对于除错和诊断非常有用

如何解决Rotor中的SOS.dll命令无法加载的问题

由于SOS是在WinDbg进程中加载,而WinDbgManifest中并没有VC Runtime调试版的DLLSide By Side信息,所以加载会失败。解决方法有下面的两种:

1.     Copy相应的的DLLWinDbg目录或者到Rotor的目录下面。我的VS2005编译出来的SOS.dll依赖于8.0.50727.762版本的MSVCR80D.dll,因此可以在C:/windows/WinSxS/x86_microsoft.vc80.debugcrt_1fc8b3b9a1e18e3b_8.0 .50727.762_none_24c8a196583ff03b目录下面找到。

2.     也可以从WinDbgManifest入手解决这个问题。既然WinDbgManifest没有MSVCR80D的相关信息,我们可以手动替WinDbg加上一个,步骤如下:

首先使用mt.exeWinDbgManifest提取出来,这个Manifest是在WinDbg.exe中作为资源存在的,其ID1。先打开VS 2005的命令提示符(否则找不到mt),进入WinDbg所在目录,输入:

mt.exe -inputresource:windbg.exe;#1 -out:extracted.manifest

获得了WinDbgManifest之后,打开extracted.manifest可以看到下面内容:

Windows GUI symbolic debugger

   

       

   

可以看到里面并没有对于MSVCR80D.dll的信息,我们可以自己动手加上去:

Windows GUI symbolic debugger

   

          

   

   

          

   

其中深红色的为添加的内容,意思是该EXE依赖于Microsoft.VC80.DebugCRT这个DLLversion 8.0.50727.762architecturex86public key token1fc8b3b9a1e8e3bWindows会自动根据这个信息找到对应的MSVCR80D.dll

下面我们可以动手修改WinDbg了,建议动手之前WinDbg之前请先备份WinDbg。准备好了之后键入:

mt.exe -manifest extracted.manifest -outputresource:windbg.exe;#1

这个命令会将Manifest作为资源重新添加到WinDbg.exe,覆盖原来的Manifest,至此WinDbg已经被我们修改了。验证一下,用WinDbg打开CLIX.exe进行调试,然后键入如下命令:

.loadby sos sscoree

没有看到任何输出,说明加载成功。再输入

!help

SOS会输出所有命令的列表。

后记

经过修改之后,SOS可以被正常加载了。很遗憾的是,在我后续的对Rotor的实验中,发现Rotor的代码中对SOSBPMD命令和CLR notification支持存在问题,而BPMD命令正好是SOS的最重要功能之一:设置断点。在我的下一篇文章中,会讲到问题的具体情况以及如何修改Rotor代码来支持CLR NotificationSOSBPMD命令。在修改了Rotor代码使SOS正常工作之后,再下一篇文章则会以跟踪一个简单的HelloWorld的托管代码程序来揭示Rotor的基本运行机制和原理,敬请关注。

 



https://dhexx.cn/news/show-3785810.html

相关文章

java架构-Java 判断字符串中是否包含中文

Java判断一个字符串是否有中文是利用Unicode编码来判断,因为中文的编码区间为:0x4e00--0x9fbb, 不过通用区间来判断中文也不非常精确,因为有些中文的标点符号利用区间判断会得到错误的结果。而且利用区间判断中文效率也并不高&…

铁路民警拍摄记录农村30年 农村淘宝承包其全家全年口粮

“天哪!这么多,这真的一年估计都吃不完” 尽管早有心理准备,但当王宏旻面对农村淘宝送的整整1200斤大米时,仍不禁感叹。 农村淘宝推出共享丰收喜悦“随手拍丰收”活动。一周时间内全国32个省市区上万名网友参与,随手拍…

手动生成C#的COM包装类的常见问题和解决办法

看一下如下代码:[Guid("25088995-7924-4B15-B01A-EA7C422ADC68")]public class CHelloClass : IHello{[DispId(1)][MethodImplAttribute(MethodImplOptions.InternalCall, MethodCodeTypeMethodCodeType.Runtime)]public extern void HelloWorld();}class…

丰收节拍丰收中奖 农村淘宝给一家全年管饭

“天哪!这么多,这真的一年估计都吃不完” 尽管早有心理准备,但当王宏旻面对农村淘宝送的整整1200斤大米时,仍不禁感叹。 农村淘宝推出共享丰收喜悦“随手拍丰收”活动。一周时间内全国32个省市区上万名网友参与,随手拍…

阿里CEO张勇:不存在阿里巴巴模式,我们一直在高速演进

双节期间,马云在联合国"加班",阿里CEO张勇也没闲着。 昨天,即将于明年接任阿里巴巴集团董事局主席的张勇,参加了2018安永全球新晋合伙人大会,并发表了精彩的演说,"不存在阿里巴巴模式&…

Visual Studio 2005的JIT Debugger在Vista上面无法正常工作

Visual Studio 2005的Jit Debugger在Vista上不工作,即使你打了SP1和Update for Windows Vista也不行。修改Jit Debugger使其工作在Vista上需要大量的修改,因此这个工作被移到Visual Studio Code Name Orcas,也就是2007中去了。不过不排除微软…

抛砖引玉 【镜像控件】 WPF实现毛玻璃控件不要太简单

原文:抛砖引玉 【镜像控件】 WPF实现毛玻璃控件不要太简单版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Vblegend_2013/article/details/83447420 源码已封装成 MirrorGrid类 可以直接在XAML里添加 根据需要可以把Grid 改…

黄金周未来景区游客涨6倍 阿里巴巴数字经济体引领体验式消费升级

免排队、秒刷脸、轻松反复入园……国庆假期前两日,西溪湿地未来景区游客数量达到平日的6倍,每天有上千位游客享受"无需取票、不刷身份证"的"纯刷脸"极致入园体验。 这就是阿里巴巴旗下旅行品牌飞猪通过技术创新和大数据赋能景区的一…

ACM UVa算法题209 Triangular Vertices的解法

有一段时间没有做ACM算法题目了,今天正好有空便随便挑了209题来做做:ACM UVa算法题#209题这道题有几个要点:1. 给定坐标系坐标系很容易定,我采用的是第一个点为(0, 0)点,X方向差别为2个单位,Y方向差别为1…

Java复习笔记(三)

程序控制语句if条件语句只要满足条件就处理,不完全是顺序结构,可以跳着执行。(1)if (条件语句){执行语句;}else{执行语句;}(2)if ....else if....elseif (条件1){执行语句}else if …