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

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.<flavor>.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>显示具体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可以看到下面内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="Microsoft.Windows.SdkTools.windbg" processorArchitecture="x86" version="6.7.0.0" type="win32"></assemblyIdentity>

<description>Windows GUI symbolic debugger</description>

<dependency>

    <dependentAssembly>

        <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>

    </dependentAssembly>

</dependency>

</assembly>

 

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

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="Microsoft.Windows.SdkTools.windbg" processorArchitecture="x86" version="6.7.0.0" type="win32"></assemblyIdentity>

<description>Windows GUI symbolic debugger</description>

<dependency>

    <dependentAssembly>

           <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>

    </dependentAssembly>

</dependency>

<dependency>

    <dependentAssembly>

           <assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>

    </dependentAssembly>

</dependency>

 

</assembly>

 

其中深红色的为添加的内容,意思是该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的基本运行机制和原理,敬请关注。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
http://blog.csdn.net/atfield/article/details/1471465 Introduction Shared Source CLI 2.0 (开发代号Rotor) 是微软.NET Framework 2.0的Shared Source实现版本。Shared Source是微软推出的源代码共享计划,可以在一定限制的情况下获得/使用源代码,详情可以参考Microsoft Shared Source Initiative主页:http://www.microsoft.com/resources/sharedsource/。Rotor代码可以在非商业行为的前提下可以自由修改和发布,只需保留License声明即可。Rotor包含了下面的内容: 1. CLI的运行时(CLR)的符合ECMA标准的实现 2. C# & Jscript编译器 3. .NET Framework中的部分工具,如ilasm, ildasm, cordbg, gacutil, sn等 4. Build工具,如Build, Binplace, NMake等 5. PAL (Platform Adaptation Layer),支持其他平台 6. 自动化回归测试 7. Samples 由此可见,Rotor研究.NET Framework实现的最佳材料。 Rotor的全部源代码可以在微软的MSDN网站上下载:http://msdn.microsoft.com/net/sscli/ 下载后解压缩,可以看到如下的目录结构: 目录 内容 Binaries.x86*.rotor Build出来的可执行文件和Symbols。这个目录在Build之后才会出现 clr CLI和BCL(Base Class Library)的实现 csharp C#编译器的实现就在这里了 Docs 文档 Env Build时所需的一些文件 Fx 类库的实现 Jscript Jscript编译器的实现 Pal Platform Adaptation Layer的实现。PAL是Rotor对Windows和Unix的一些基本API的封装 Palrt Platform Adaptive Layer Runtime的实现。PAL中的和操作系统平台无关可重用的部分 prebuilt 存放着build所需的一些事先用工具生成好的文件 Samples Samples Tests Regression Test Suite Tools Build工具,包括binplace, build, cppmunge等 Vscommon 公共头文件,主要是微软内部使用的一些产品有关的公用的宏定义 总共大概有150MB左右。 本人先发在CSDN上做个备份。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值