最近在做了半年WinDbg的研究,买了两本《软件调试》(一本是新加坡的Director要我帮买的),从头看了一遍,从中受益不少。最近在做Windbg自动化的项目,碰到一些问题,来这里请教一些高人。现对各位关注的朋友致谢。
问题描述如下:
我们知道Visual Studio对程序的编译有2种模式:Debug&Release,发现Debug模式下WinDbg对局部变量的支持很好,但是Release模式下WinDbg好像对一些局部变量的地址解析有误,所以变量的值自然就不对了。测试过Visual Studio的debugger即使在Release模式下对局部变量的支持依然很好。
局部变量的地址是根据当前线程的EBP+偏移来确定的。Release模式下编译器可能作了一些优化,对一些函数的调用省略了EBP的更新,而直接用ESP+偏移来引用局部变量的地址。
了解到WinDbg对PDB地分析是基于dbghelp.dll,而Visual Studio是基于另外的一个DIA SDK.
想请问局部变量在PDB中存储的信息包括什么?以及是否可以自己写Windbg的扩展命令,使用DiA SDK来解析局部变量,这样来解决WinDbg对release模式局部变量的检查错误。
另外,感觉很奇怪的事情是,不知道MS windbg的研发小组为什么会放着这样的错误不解决呢?
简单来说,这个问题主要是编译器和调试符号的问题,不是WinDBG的问题。以VC8(VS2005)为例,使用默认选项构建出的发布版本,在IDE下和WinDBG都可以正确的显示局部变量(参见下图)。
对于VC6,默认的发布版本配置,不会产生符号文件,手工配置后,可以产生,也可以使用,但是在某些函数位置显示局部变量时,的确有错误,但是这样的错误,无论是用VC6自己调试,还是使用WinDBG都会出现。
注意上面的显示中,参数和变量显示完全错位了,0x2510c2应该是hWnd的值。但VC6自己也有这样的问题:
其实,其中的原理和导致问题的原因也很简单,使用SymView工具看一下,便很清楚。
VC6编译时,使用了FPO,而FPO一向是阻碍调试功能的“绊脚石”。
而,VC8没有使用FPO,符号中的偏移位置也很是规范,EBP+8为为第一个参数:
screenshot: