今天软件突然挂了,只有event log可以参考,研究了半天,在网上也找了很多资料。有很多很好的资料,不过貌似没有win7版本的,都是xp的。因为win7的event log和xp的貌似有点不同,研究了半天,总结出一点,写下来,供大家参考下:
配置:WIN7 + VS2010
配置 VS2010:
- 打开map:linker --> Debugging --> Generate Map File
- 打开COD: C/C++ --> Output Files --> Assembler Output
- 编写了一段空指针的代码:
- 运行程序,程序crash。查看event viewer:发现其错误偏移地址是:Fault offset: 0x00002752
- 打开对应程序的map文件:这时候就有问题,这个错误偏移地址Fault offset: 0x00002752,如何计算出对应的代码呢?一些文章中给出的公式如下:
崩溃行偏移 = 崩溃地址 - 崩溃函数绝对地址 + 函数相对偏移
但是我算了半天,貌似算不出来。想了半天,终于明白了,首先计算崩溃绝对地址:
崩溃绝对地址 = Fault offset + 0x0040 0000
带入event viewer给出值Fault offset: 0x00002752,得到崩溃绝对地址:0x0040 2752
- 根据得到的崩溃绝对地址,查找map文件,相应的函数的地址是:
崩溃函数绝对地址 < 崩溃绝对地址 < 下一个函数绝对地址
查找相应的map文件,发现:OnTimer 的绝对地址 < 崩溃绝对地址 < OnSize的绝对地址
因此能够判断crash发生在OnTimer的函数之内。
- 查出崩溃所在的函数之后,需要查找具体crash行的代码。首先,计算crash行的代码相对于函数的偏移:
崩溃行偏移 = 崩溃绝对地址 - 崩溃函数绝对地址
带入相应的值:
崩溃行偏移 = 0x0040 2752 - 0x0040 2700 --> 得到崩溃行偏移0x52.
- 在找出崩溃函数和崩溃行偏移之后,如果需要定位代码,就需要cod文件了:
我想这个时候就能基本上确定出问题的代码了,当然也许有时候需要依据上下文作出判断。。。。
....
如上图,先找出OnTimer这个函数,然后在这个函数内部根据偏移地址 0x52确定出问题的代码是:(2) move DWORD PTR[eax], eax,空指针异常。
此外上图中红圈(1)所标示的数字343代表的意思是: 代码行
有人会觉得奇怪,为什么没有test_crash01和test_crash这两个函数,因为它们被编译器优化掉了。。。。