调试、调试、调试...

A. 如何在Visual Studio 2005中对托管代码及非托管的CLR环境同时进行调试?

步骤远比你想象的简单,而且更重要的是比windbg方便。举例:

1. 开启一个C#的项目,打开该项目的属性窗口
2. 将Debug页面中的Enable Unmanaged Code Debugging选中
3. 在某语句处设置好断点,F5重新编译,运行,命中断点
4. 打开Immediate窗口,输入!Load sos.dll加载CLR调试扩展(这个sos.dll是.NET Framework 2.0 SDK自带的)
5. 然后在Immediate窗口里开始愉快的!DumpStackObjects、!DumpClass、!DumpMT,一窥CLR内部堂奥吧。!Help是帮助
6. 使用这种方式,对于托管代码的调试跟平时并没有啥区别


B. 可以使用Visual Studio 2005来调试Rotor 2.0编译的托管代码吗?

不行。Rotor对托管代码调试支持不全,只能使用其自带的cordbg来进行调试(无意中发现Rotor自带的cordbg版本号居然比SDK 2.0的还要高,一个是2.0.50826,一个是2.0.50727 RTM....-_-b)


C. 可以使用Visual Studio 2005来跟踪和调试非托管的Rotor代码吗?

虽然不能直接用vs2005来调试Rotor编译的托管代码,但是,调试Rotor本身却是可以的!步骤也不是很复杂:

1. 用记事本编辑Rotor编译所得的sos.dll.manifest文件(例如d:\Rotor2\binaries.x86chk.Rotor\sos.dll.manifest)
2.
 
copy其中<dependency>...</dependency>部分内容,将其paste进C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.exe.manifest文件的<assembly>一节当中,保存之
3. 假设某Rotor2下编译的托管测试文件的全路径名为d:\Rotor2\samples\hello.exe
4. Rotor控制台下输入"devenv /debugexe clix d:\Rotor2\samples\hello.exe",启动vs2005,加载clix
5. F5启动,稍等几秒钟,确信Rotor的运行时环境已启动,然后按Ctrl-Alt-Break抢占中断clix执行
6. 打开Immediate窗口,输入!Load d:\Rotor2\binaries.x86chk.Rotor\sos.dll,加载Rotor自己编译生成的CLR调试扩展
7. 好戏开始了!快单步跟踪、输入>cmd / !threads / !dumpstack试试看吧!


D. "稍等几秒钟,确信Rotor的运行时环境已启动,再按Ctrl-Alt-Break抢占中断其执行"是啥意思?

意思就是说,在调试Rotor时,如何合理、适时地设置断点是关键。为了简单起见,可以在上述那个简单示例中使用一条Console.ReadLine语句暂时锁死流程的执行,启动后稍等一会儿再按Ctrl-Alt-Break返回调试器,这样我们便能保证中断时Rotor的运行时环境已经完成加载了。

或者更专业一点,还可以通过设置环境变量来启动Rotor的辅助调试机制,如COMPlus_BreakOnEELoad、COMPlus_JitBreak等,这比“猜测式断点”更准确、更方便,这里就不多说了,请进一步参考Rotor自带的调试文档,里面说得很详细。


参考文献:
[1] Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects, MSDN Magazine, May 2005
[2] SOS: It's Not Just an ABBA Song Anymore, MSDN Magazine, MSDN Magazine, Jun. 2003
[3] SOS Debugging with the CLR, Jason Zander's Blog, Oct. 2003  

posted @ 2006-04-08 00:46  neoragex2002  阅读(867)  评论(0编辑  收藏  举报