分析Windows中的崩溃:错误消息告诉我们什么?

GRB*_*GRB 26 c++ windows crash debugging assembly

我个人使用的一个小实用程序(用C++编写)昨天随机崩溃(我已经使用它大约100多个小时,到目前为止没有问题)虽然我通常不这样做,但我感觉有点喜欢冒险,想尝试更多地了解这个问题.我决定进入事件查看器,看看Windows记录的崩溃事件:

Faulting application StraightToM.exe, version 0.0.0.0, time stamp 0x4a873d19 
Faulting module name : StraightToM.exe, version 0.0.0.0, time stamp 0x4a873d19
Exception code : 0xc0000005
Fault offset : 0x0002d160,
Faulting process id: 0x17b4
Faulting application start time: time 0x01ca238d9e6b48b9.
Run Code Online (Sandbox Code Playgroud)

我的问题是,这些东西意味着什么,我将如何使用它们来调试我的程序?这是我目前所知的:异常代码描述了错误,而0xc0000005是内存访问冲突(试图访问它不拥有的内存).我特别想知道更多有关以下内容的信息:

  1. 故障偏移是什么意思?这是表示文件中发生错误的位置,还是表示发生错误的程序集"line"?知道了故障偏移,我如何使用像OllyDbg这样的程序来查找导致错误的相应汇编代码?或者 - 甚至更好 - 是否可以(轻松)确定C++源代码中的哪一行代码导致此错误?
  2. 很明显,时间戳对应于崩溃时的32位UNIX时间,但64位应用程序的启动时间意味着什么?如果时间戳为32,为什么它是64位?

请注意,我主要是一名C++程序员,所以虽然我对汇编有所了解,但我对它的了解非常有限.此外,这确实不是一个需要修复的严重问题(并且鉴于程序的性质也不容易复制),我只是以此为借口来了解这些错误消息的含义.我在网上找到的关于这些崩溃日志的大部分信息通常都是针对最终用户的,所以他们并没有帮助我(作为程序员).

提前致谢

ava*_*kar 17

64位时间戳是自1601年1月1日(UTC)以100纳秒间隔创建时间应用程序的主要线程(这被称为FILETIME).32位时间戳确实是time_t格式化的(它告诉模块创建的时间并存储在模块的标题中).

我会说0x0002d160是模块加载地址的偏移量(绝对地址似乎太低了).启动Visual Studio,启动调试器,查看"模块"调试窗口.你的exe文件应该列在那里.找到加载模块的地址,将0x0002d160添加到该地址,然后查看结果地址处的反汇编.Visual Studio显示与程序集混合的源代码,您应该没有问题找出导致问题的源代码行.


i_a*_*orf 7

您可以使用此信息进行事后调查.

有用的信息是异常代码0xc0000005,在这种情况下只是意味着访问冲突.因此,您取消引用null或您没有的其他内存.

我怀疑,故障偏移是你的DLL加载到内存的偏移量,所以理论上你可以将它添加到你的基地址并找到有问题的代码,但我不确定.

调试它的最佳选择是在下次发生这种情况时在调试器中捕获它.您可以使用图像文件执行选项调试器中自动运行您的应用程序.确保您已准备好符号(如果您当前正在使用RELEASE,请考虑构建DEBUG).


Kim*_*man 6

调试上帝John Robbins构建了一个名为CrashFinder的小工具来帮助解决这样的情况:https://www.wintellect.com/crashfinder-2-8-yes-native-code-still-lives/

为您向公众发布的每个版本保存PDB总是一个好主意(这听起来像是一个私有使用的工具,但最好保留PDB符号以获得最新版本).