【问题标题】:How can I determine why my process terminates如何确定我的进程终止的原因
【发布时间】:2011-09-27 11:34:35
【问题描述】:

我有一个问题,在调用第 3 方库例程期间我的进程终止。我完全无法在我的调试器中捕捉到这一点。这可能与这个问题有关:How can I debug a win32 process that unexpectedly terminates silently?

当我跳过对该库的调用时,正在调试的进程简单地终止。如果此终止是由于未处理的异常或内存访问冲突,调试器将捕获它。所以我最好的猜测是进程以某种方式正常终止。

我尝试过的:

  • ExitThreadExitProcess 上设置断点
  • 为未处理的异常和无效参数设置处理程序(set_terminate_set_invalid_parameter_handler
  • 更改 _set_abort_behavior_set_error_mode
  • 指示调试器停止执行所有抛出的异常。

但无济于事,没有调用任何处理程序,也没有触发断点。

我所观察到的: 当进程崩溃时,我在调试输出窗口中看到两件事:

  1. 不相关(请参阅下面的更新) 我看到EEFileLoadException 被抛出。这个异常的快速谷歌并没有给我一个明确的答案来解释这个异常的含义。

    First-chance exception at 0x7656b9bc (KernelBase.dll) in Program.exe: Microsoft C++ exception: EEFileLoadException at memory location 0x0030b5ac..
    First-chance exception at 0x7656b9bc (KernelBase.dll) in Program.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000..
    First-chance exception at 0x7656b9bc (KernelBase.dll) in Program.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000..
    First-chance exception at 0x7656b9bc (KernelBase.dll) in Program.exe: 0xE0434352: 0xe0434352.
    
  2. 终止时,所有线程都返回相同的错误代码 (STATUS_INVALID_CRUNTIME_PARAMETER)。 据我所知,此错误代码意味着其中一个 c 运行时函数收到了无效参数,并且出于安全原因终止了应用程序。

    The thread 'Win32 Thread' (0x12c0) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0xe04) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x53c) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x116c) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x16e0) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x1420) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x13c4) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x40c) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0xc78) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0xd88) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x16c8) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0xcb8) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x584) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x1164) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x1550) has exited with code -1073740777 (0xc0000417).
    The thread 'Win32 Thread' (0x474) has exited with code -1073740777 (0xc0000417).
    The program '[5140] Program.exe: Native' has exited with code -1073740777 (0xc0000417).
    

我真正想知道的是什么导致了这种情况,并且可以选择;我怎样才能在调试器中捕捉到这个?

更新 关于EEFileLoadException,实际上是在程序调用导致它终止之前抛出的,所以它与进程的终止无关。

更新 我刚刚读到set_terminate 在调试器中不起作用,所以这是不可能的。正如我在评论中指出的那样,处理程序是按线程管理的,因此我无权访问相关的处理程序。

此外,程序很可能在我无法访问的工作线程中崩溃,因此很难设置任何断点/处理程序。

有没有更好的方法来找出问题所在?

【问题讨论】:

  • 我意识到终止处理程序没有被调用,因为它们是基于每个线程安装的,我无法访问崩溃线程。
  • 我遇到了与此类似的情况,但在我的情况下,TRACE 消息也没有传递到输出窗口。当我改为附加 WinDebug 时,我发现有一个 DebugBreak() 调用被 VS 忽略,这导致进程到 terminate() 本身,导致 The program [0x2F74] 'OUTLOOK.EXE' has exited with code -1073740777 (0xc0000417). 不幸的是,我无法弄清楚为什么 Visual Studio 忽略了它应该正在调试的程序。

标签: visual-studio-2010 debugging winapi


【解决方案1】:

配置 procdump 以在进程终止时生成进程转储。不确定VS2010是否可以打开转储文件,但windbg可以。然后转储所有线程堆栈,您应该会看到导致终止的堆栈。然后,您将能够检查堆栈以找到有问题的参数。

如果您的应用程序是 foo.exe,则从命令提示符运行 procdump,如下所示: procdump -ma -t -w foo.exe

-ma 表示完全内存转储

-t 表示进程终止时写转储

-w 表示如果尚未运行则等待进程启动

然后在任何调试器之外运行您的应用程序。一旦它终止,您应该会看到 procdump 的输出,表明进程已终止并且正在写入转储文件。

这是 procdump 的链接: http://technet.microsoft.com/en-us/sysinternals/dd996900

【讨论】:

    【解决方案2】:

    运行您的应用程序裸体调试器(或附加到正在运行的进程),按Ctrl+Alt+E 并选中复选框,让调试器在出现异常时停止执行。

    每次发生异常时,调试器都会中断。您将能够检查线程状态/调用堆栈以可能识别问题。

    应用意外终止的典型原因是:

    • 某些东西确实会发布 WM_QUIT 消息,这会指示应用关闭
    • 发生异常,并且未处理(尤其是在后台线程上);异常遍历调用堆栈到操作系统,它不知道如何处理所有的东西,只是杀死进程

    由于EEFileLoadException 异常发生并且您不知道它是关于什么的,您可能希望首先了解它是否被处理,如果它对您的应用程序实际上是致命的事情。

    【讨论】:

    • 我已经尝试指示调试器在没有运气的情况下停止所有抛出的异常。
    • 另外,我认为WM_QUIT 不是问题,因为应用程序在调试主线程时终止。这将指向另一个线程是罪魁祸首。
    • 调试器是否在异常时停止?您使用的是什么类型的调试器,原生的和/或托管的?
    • 调试器不会停止执行。我正在使用纯本机调试器。 AFAIK,不涉及托管代码。 (不过,在第 3 方库的掩护下可能存在托管代码)
    • 您的帖子包含发生异常的引号。调试器只需要停止这些,或者您正在调试的异常设置指示它继续。我唯一能想到的是加载了第三方托管代码,它会导致automatic 调试器模式开始托管调试。这将忽略原生内容。
    【解决方案3】:

    我以前也遇到过同样的问题。我刚刚删除了 C# 项目中的 obj 文件。并再次重建,它的项目工作。希望这能解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      • 2011-02-05
      • 2011-06-18
      • 2013-12-14
      • 1970-01-01
      • 2012-04-24
      相关资源
      最近更新 更多