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

我个人使用的一个小实用工具(用C ++编写)昨天随机地崩溃了(我用了大约100多个小时,目前为止没有问题),虽然我通常不这样做,但我感觉有点冒险的,并想尝试和了解更多的问题。 我决定进入事件查看器,看看Windows已经logging了有关崩溃的信息:

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. 

我的问题是,这些事情都意味着什么,我将如何使用这些来debugging我的程序? 以下是我迄今为止所了解的内容:exception代码描述错误,而0xc0000005是内存访问冲突(试图访问它不拥有的内存)。 我特别想知道更多关于以下内容:

  1. 错误抵消是什么意思? 这是否代表文件中发生错误的位置,还是代表发生错误的程序集“行”? 知道错误偏移量,我将如何使用像OllyDbg这样的程序来查找导致错误的相应汇编代码? 或者 – 甚至更好 – 是否可以(容易地)确定C ++源代码中的哪一行导致了这个错误?
  2. 很明显,时间戳对应于崩溃时的32位UNIX时间,但64位应用程序的启动时间意味着什么? 如果时间标记是32,为什么它是64位呢?

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

提前致谢

Solutions Collecting From Web of "在Windows中分析崩溃:错误消息告诉我们什么?"

从1601年1月1日(UTC)(这被称为FILETIME )开始,64位时间戳是时间应用程序的主线程以100纳秒间隔创建的。 32位时间戳实际上是time_t格式(它告诉模块创建的时间并存储在模块的头文件中)。

我会说0x0002d160是从模块的加载地址偏移量(它似乎太低,绝对地址)。 启动Visual Studio,启动调试器,看看“模块”调试窗口。 你的exe文件应该在那里列出。 查找模块加载的地址,将0x0002d160添加到该地址,并查看结果地址的反汇编。 Visual Studio显示与程序集混合的源代码,你应该没有什么问题找出源代码行造成的问题。

没有太多的事情可以用这个信息来做事后分析。

信息的有用位是异常代码0xc0000005,在这种情况下,这意味着访问冲突。 所以你解除引用null或其他一些你并不拥有的内存。

错误偏移,我怀疑,是从你的DLL加载到内存的偏移量,所以你可以在理论上将其添加到您的基地址,并找到有问题的代码,但我不知道。

调试这个最好的办法就是在下次发生这种情况时在调试器中捕获它。 您可以使用图像文件执行选项在调试器中自动运行您的应用程序。 确保你有符号准备好(如果你正在使用RELEASE,考虑建立DEBUG)。

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

保存每个构建版本的PDB对于公众来说都是一个好主意(这听起来像是一个你只能用于私有的工具,但最好保留最新版本的PDB符号)。

看起来像这里仍然没有好的答案,如果崩溃发生在开发环境之外。 我认为off set是汇编代码崩溃的地址。 但是你需要知道该dll的汇编代码的起始位置。 或者也许你不需要知道起始地址,因为你可以使用汇编工具来打开DLL,并通过添加偏移量来找到汇编代码的起始地址