我没有正确的符号文件 (Pdb),所以我使用 .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 模块中?我还可以相信崩溃与它所说的是同一个文件名(abc.cpp)吗?当调用堆栈显示我在代码中实际看到的实际函数 [包括函数名称] 时,调用堆栈是否更有可能是正确的?
我知道符号和行号来自 pdb 文件,所以它可能有问题,但故障转储文件在所有这些连接中有什么贡献,我可以使用它来缩小问题范围?
我正在尝试从不匹配的符号文件中提取任何线索或有用的信息。
更新
我正在调试产生转储崩溃的相同版本的代码。可以完全排除模块、类名或文件名等问题,因为我们不这样做。理论上,我正在调试的版本与崩溃的版本完全匹配,因为它的版本受控。
最佳答案
对于没有 pdb 文件的发行版,我不得不多次使用同样的技巧。
您的构建环境与用于构建二进制文件的环境越接近,您的运气就越好。确保您拥有用于构建二进制文件的确切源代码、编译器版本和编译器/链接器标志将使您的生活变得更加轻松。有时您会很幸运,这些符号会非常接近,您甚至不会注意到任何奇怪的事情。
Should I be reasonably sure that at least the crash is in the Db module?
这是您唯一可以确定的事情。您实际上拥有没有符号的信息。
(如果没有符号,它往往会显示具有较大偏移量的导出符号,例如 Db!DllMain+0x123456
。在这种情况下,您仍然可以相信该模块是正确的。)
Can I also trust that the crash is in the same filename (abc.cpp) that it says it is?
没有。你现在的工作是验证你看到的一切。
要验证的事情:
在查看调用堆栈时,源代码是否显示函数在该函数主体的某处调用下一帧?如果是这样,它很有可能是正确的。如果不是,如果函数调用是内联的,它仍然可能是正确的。
在顶部框架中,
ExceptionAddress
处的反汇编看起来像是编译器应该为符号指向的源代码生成的内容吗? (例如:我希望CDbaAdoRecordset
的构造函数调用与RecordSets
相关的方法,例如CoCreateInstance(/*...*/, __uuidof(Recordset ),/*...*/);
.
您知道符号文件的内容(函数名称、行号等)这一事实应该让您了解您正在查看的内容以及可能出现的问题。
你最好的选择是从你通常会开始调试的地方开始,即使你有匹配的符号...... 尝试从地址 00000004 读取
它可能试图访问空对象上的偏移量 4。那个物体是什么?祝你好运!
关于c++ - 不匹配的符号是完整的展示塞子还是我可以部分信任它们来提取线索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38362274/