如何调试意外终止的win32进程?

时间:2008-12-18 16:21:00

标签: c++ debugging winapi crash

我有一个用C ++编写的Windows应用程序偶尔会蒸发。我使用蒸发这个词,因为没有任何遗留下来:没有来自Windows的“我们很抱歉”的消息,没有来自Dr. Watson工厂的崩溃转储......

有一次,在调试器下发生崩溃,调试器没有中断 - 它显示应用程序仍在运行。当我手动暂停执行时,我发现我的进程不再有任何线程。

如何捕捉此过程终止的原因?

11 个答案:

答案 0 :(得分:5)

您可以尝试使用windows debugging tool package中的adplus实用程序。

adplus -crash -p yourprocessid

自动转储工具为异常提供小型转储,并在应用程序崩溃时提供完整转储。

答案 1 :(得分:4)

如果您使用的是Visual Studio 2003或更高版本,则应通过启用“调试菜单”下的所有“调试异常中断”选项来启用调试程序“First Chance Exception”处理程序功能。例外对话框。在调试器中启动进程的调试版本之前,请打开每个选项。

默认情况下,调试器中的大多数First Chance Exception处理程序都处于关闭状态,因此如果Windows或您的代码抛出异常,调试器会要求您的应用程序处理它。

First Chance Exception系统允许调试器拦截进程和/或系统抛出的每个可能的异常。

http://support.microsoft.com/kb/105675

答案 2 :(得分:3)

发布的所有其他想法都很好。

但听起来应用程序正在调用abort()或terminate()。

如果在调试器中运行它,请在这两个方法上设置断点并退出()以便进行测量。

以下是导致terminate to be called because of exceptions出错的情况列表。

另见: Why destructor is not called on exception?

这表明如果没有捕获异常,应用程序将终止()。因此,在main()中粘贴一个catch块,报告错误(到日志文件),然后重新抛出。

int main()
{
    try
    {
        // Do your code here.
    }
    catch(...)
    {
        // Log Error;
        throw;  // re-throw the error for the de-bugger.
    }
}

答案 3 :(得分:2)

嗯,问题是您遇到了访问冲突。您可能希望附加WinDBG并打开所有异常过滤器。它可能仍然没有帮助 - 我的猜测是你得到的内存损坏并没有引发异常。

您可能需要查看enabling full pageheap checking

您可能还想查看有关工具的一些想法的关于堆损坏的older question

答案 4 :(得分:2)

这种突然消失的最常见原因是堆栈溢出,通常是由某种无限递归引起的(当然,这可能涉及一系列相互调用的函数链)。

你的应用程序有可能吗?

答案 5 :(得分:1)

您可以在Windows上的Event Viewer中查看Windows日志。

答案 6 :(得分:1)

首先,我想说我在Windows开发方面只有一个温和的经验。 在那之后,我认为这是一个典型的情况,日志可能有所帮助。

通常调试和记录提供正交信息。如果你的调试器没用,可能日志会帮助你。

答案 7 :(得分:1)

这可能是对_exit()或某些Windows等价物的调用。尝试在_exit上设置断点...

答案 8 :(得分:0)

您是否尝试过PC Lint等并在代码上运行它? 尝试使用最大警告进行编译 如果这是一个.NET应用程序 - 请使用FX Cop。

答案 9 :(得分:0)

可能的原因浮现在脑海中。

  • 了TerminateProcess()
  • 堆栈溢出异常
  • 处理异常时的异常

最后一个特别导致应用程序立即失败 堆栈溢出 - 您可能会收到通知,但不太可能。

进入调试器,将所有异常通知更改为“始终停止”,而不是“如果未处理则停止”,然后执行操作以导致程序失败。如果您收到异常,调试器将停止,您可以决定这是否是您要查找的异常。

答案 10 :(得分:0)

我花了几个小时试图在Windows 7上运行64位应用程序的Visual Studio 2017上深入研究。我最终必须在 RtlReportSilentProcessExit 函数上设置一个断点,该函数存在于 ntdll.dll 文件。只需基本函数名称就足以让Visual Studio找到它。

也就是说,在我让Visual Studio自动下载C标准库的符号后,它也会自动停止导致问题的运行时异常。