我没有正确的符号文件(Pdbs)所以我使用.reload /f /i
加载我重新生成的内容而忽略了时间戳。我的项目有很多模块,这确实加载了其中一些而不是其他模块,我不知道为什么不是全部。
但是,我想知道如果有任何问题,我可以信任多少不匹配符号文件。这是来自故障转储文件的异常信息
0:000> .exr -1
ExceptionAddress: 020b1143 (Db!CDbaAdoRecordset::CDbaAdoRecordset+0x00000073) [abc.cpp @80]
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 00000004
Attempt to read from address 00000004
我是否应该合理地确定至少崩溃是在Db模块中?我是否还可以相信崩溃与它所说的相同的fil ename(abc.cpp)?当它显示我可以在代码[包括函数名称]中实际看到的实际函数时,调用堆栈更可能是正确的吗?
我知道符号和行号来自pdb文件,所以它可能有问题,但崩溃转储文件在所有这些连接中有什么作用,我可以用它来缩小问题范围?
我正在尝试从不匹配的符号文件中提取任何潜在客户或有用的信息。
更新
我正在调试产生转储崩溃的相同版本的代码。由于我们不这样做,因此可以完全排除诸如模块,类名或文件名之类的事情。从理论上讲,我调试的版本与崩溃版本完全匹配,因为它的版本受控制。
答案 0 :(得分:3)
对于没有pdb文件的版本,我必须多次执行相同的操作。
您的构建环境越接近用于构建二进制文件的环境,您就会拥有更好的运气。确保您拥有用于构建二进制文件的确切源代码,编译器版本和编译器/链接器标志将使您的生活更轻松。有时你会很幸运,符号会如此接近,你甚至不会发现任何奇怪的事情。
我是否应该合理地确定至少崩溃是在Db模块中?
这是你唯一能确定的事情。实际上你没有符号就有这些信息。
(没有符号,它往往会显示一个带有大偏移的导出符号,如Db!DllMain+0x123456
。在这种情况下,您仍然可以相信该模块是正确的。)
我是否还可以相信崩溃与它所说的文件名(abc.cpp)相同?
不。您现在的工作是验证您看到的所有。
要验证的事项:
在查看callstack时,源代码是否显示在该函数体中某处调用下一帧的函数?如果是这样,那么它很有可能是正确的。如果没有,如果内联函数调用,它仍然可能是正确的。
在顶部框架,ExceptionAddress
处的反汇编看起来像是编译器应该为符号指向的源代码生成的内容吗? (例如:我希望CDbaAdoRecordset
的构造函数调用与RecordSets
相关的方法,如CoCreateInstance(/*...*/, __uuidof(Recordset), /*...*/);
。
事实上,您知道符号文件中的内容(函数名称,行号等)应该让您了解您正在查看的内容以及可能出现的问题。
您最好的选择是从正常开始调试开始,即使您有匹配的符号...... Attempt to read from address 00000004
它可能试图访问一个空的对象上的偏移量4。那个对象是什么?一帆风顺!
答案 1 :(得分:3)
异常记录中的大多数内容与PDB无关,只会尝试将异常地址解析为调用堆栈。
我不确定WinDbg是否会为模块名称不匹配的DLL加载PDB。此外,我不太可能重命名DLL,我会说。
因此,您可以从具有不匹配的PDB的异常记录中信任的事项是:
ExceptionAddress: 020b1143 (Db!
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 00000004
Attempt to read from address 00000004
你不能信任的事情:
!CDbaAdoRecordset::CDbaAdoRecordset+0x00000073) [abc.cpp @80]
当它显示我在代码[包括函数名称]中实际可以看到的实际函数时,调用堆栈更有可能是正确的吗?
没有。这可能是偶然的。
崩溃转储文件在所有这些连接中的作用是什么,我可以用它来缩小问题的范围?
无。您只能从开发人员的知识中得出结论:不匹配的PDB和DLL的时差是多少,以及您在哪些文件中进行了多少更改。使用版本控制差异来找出它。
这种匹配可能会出错,因为
这种匹配仍然可能出错,因为