如何调试无痕崩溃

时间:2011-03-01 08:43:16

标签: c++ c windows debugging c++builder

在开发应用程序期间,我们特别遇到了一个非常讨厌的错误。症状很简单,该过程消失了。日志突然结束,没有崩溃转储或任何可以找到的东西,没有僵尸进程存在。沃森博士没有注意到任何遗留下来的东西。

重现错误不容易,重现此错误平均需要3-4个小时,重复执行相同的操作。所以在某个地方存在某种竞争条件。我们有处理SEH和普通异常的特殊函数,所以这些都不会被忽视。

调试必须在特殊的计算机上完成,因为它在非常专业的硬件上运行。因此只能进行远程调试。当连接远程调试时,C ++构建器没有注意到应用程序丢失,当我们尝试对不存在的进程进行任何调试时崩溃并烧毁。

我们在这个软件上使用了各种各样的技术:

  • 的OpenGL
  • Directshow +一些COTS过滤器
  • COM / DCOM
  • 串行COM端口与专用硬件通信
  • C ++ Builder(使用与VC ++不同的堆栈帧)

所以,正如你所理解的那样,我在这里工作的时间并不多。我现在正在做的是我试图通过登录代码中的不同位置来缩小它,以查找代码中是否存在错误发生的特定点。我也试图删除我正在执行的操作的许多方面,以使案例尽可能简单。但这是一个非常复杂的操作,这个过程需要花费很多时间,而且时间(像往常一样)是一种稀缺资源。

我想知道是否有人对我有好的建议,无论是对于原因(通常是什么导致过程只是在没有任何通知的情况下停止),或者是调试这种难以捉摸的失败的技术?

4 个答案:

答案 0 :(得分:7)

当Windows下的本机代码遇到堆栈溢出(通常是由于无限递归)时,该过程有时会像您描述的那样完全消失。标准错误对话框和异常处理需要一些堆栈空间,如果没有,则无法运行。 (Windows的更高版本处理得更好,而应该总是引发异常 - Windows XP在此定义下不是“稍后”。)

调试此问题最简单的蛮力方法是在每个函数的条目(可能是出口)处写入日志消息。这些消息直接转到文件,如果你有缓冲输出(例如cout或类似的),你应该每次立即刷新它。当您设法导致崩溃时,您将接近堆栈跟踪,至少可以本地化问题。


无限递归不是堆栈溢出的唯一原因(尽管它是更常见的)。如果在堆栈上分配非常大的变量(通常是具有数千/百万元素的数组),则可能发生相同的问题。特别是,alloca()“函数”可以掩盖这种类型的堆栈溢出的原因。

如果你在调试器下运行并中断/登录防护页面异常,你会在堆栈扩展时得到通知 - 让异常被处理,因为它被用来提交更多的内存而且可能实际上并没有与问题。


消失过程的最终非堆栈溢出原因是对exit()ExitProcess()的迷路调用。全文搜索应该能够主要排除这一点 - 调试器中ExitProcess函数的断点将完全这样做。

答案 1 :(得分:2)

为什么不尝试windbg,它也可以通过命名管道或串口远程连接。


没有BSOD,没有Rootkit,没有乐趣~~ Biswanth Chowdhury - Win32 Kernel *

答案 2 :(得分:2)

尝试使用较小的堆运行它。如果问题是由于内存不足造成的,这将导致崩溃更快发生。

答案 3 :(得分:1)

如果您希望能够更频繁地调试方案,请尝试在虚拟机中运行此方法,并在发生之前每隔一段时间拍摄一次“快照”。

此处的问题可能与您通过串口连接的专用硬件的状态不一致。