八、 诊断实例
在这一节主要讲述如何在具体的场景中运用Windbg,主要讲述一些我平常工作中用的比较多的使用场景,比如怎么查看某个线程具体执行到哪一行代码,调用方法时怎么传值,怎么分析查找线程栈中的变量,堆中的内存对象等。
1. 分析线程栈回溯(call stack)中某个方法(托管方法)执行到了哪一步。
通常在工作中会碰到这么一个场景,需要分析一个Freezing的dump是在哪个方法里面的哪一行源代码Freeze掉了,这时候就需要找到我们自己写的代码是在哪一行陷入了Freeze了。
要找到具体的栈帧(Stack Frame)对应哪一行具体的源代码,其实挺容易的,但前提是需要懂一点汇编,但是编译器优化过后的代码生成的汇编非常难读,跟源代码相距甚远,非常难通过对应的汇编找到对应的源代码,尤其是碰到方法特别长的代码,这加剧了分析难度,所以说方法或函数写的短小精悍还是很有好处的。
在这里我通过release的编译方式AnyCpu,Prefer 32-bit的编译方式编译代码,而且禁掉了pdb文件的生成: 通过Project的Properties找到Build一栏,然后在output里面选择Advanced…(中文版的VS请自行脑补翻译):
然后再弹出的Dialog里面中DebugInfo选择None:
点击OK。在这里我之所以去掉pdb文件是因为在实际工作中,在客户的机器上碰到的问题打出来的dump都是优化过的代码,而且这个时候也找不到pdb文件(除非在build branch的时候你留了一手,将pdb文件build出来了,另外补一句,在托管代码中pdb的用处也没特别大)。
好了,先看代码: