我有一个用 C++ 编写的 Windows 应用程序,它偶尔会消失。我使用蒸发这个词是因为没有留下任何东西:没有来自 Windows 的“我们很抱歉”消息,没有来自 Dr. Watson 设施的崩溃转储......
有一次在调试器下发生了崩溃,调试器没有中断——它显示应用程序仍在运行。当我手动暂停执行时,我发现我的进程不再有任何线程。
如何捕获此过程终止的原因?
如果您使用的是 Visual Studio 2003 或更高版本,您应该启用调试器“第一次机会异常”处理程序功能,方法是打开“调试菜单 | 下的所有调试异常中断”选项。例外对话框。在调试器中启动进程的调试构建之前打开每个选项。
默认情况下,调试器中的大多数 First Chance Exception 处理程序都已关闭,因此如果 Windows 或您的代码抛出异常,调试器希望您的应用程序处理它。
First Chance Exception 系统允许调试器拦截进程和/或系统抛出的每一个可能的异常。
发布的所有其他想法都很好。
但听起来应用程序正在调用 abort() 或 terminate()。
如果你在调试器中运行它,在这两个方法和 exit() 上都设置一个断点,只是为了更好的衡量。
以下是由于异常出错而导致调用终止的情况列表。
另请参阅: 为什么在异常时不调用析构函数?
这表明如果没有捕获到异常,应用程序将终止()。因此,在 main() 中粘贴一个 catch 块,报告错误(到日志文件)然后重新抛出。
int main()
{
try
{
// Do your code here.
}
catch(...)
{
// Log Error;
throw; // re-throw the error for the de-bugger.
}
}
好吧,问题是您遇到了访问冲突。您可能希望附加 WinDBG 并打开所有异常过滤器。它可能仍然无济于事-我的猜测是您遇到了没有引发异常的内存损坏。
您可能想查看启用完整的页面堆检查
您可能还想查看有关堆损坏的旧问题,以了解有关工具的一些想法。
这种突然消失的最常见原因是堆栈溢出,通常是由某种无限递归引起的(当然,这可能涉及一系列相互调用的多个函数)。
你的应用程序有这种可能性吗?
您可以在 Windows 上的事件查看器中检查 Windows 日志。
首先我想说的是,我在 Windows 开发方面的经验并不多。在那之后,我认为这是一个典型的案例,日志可能会有所帮助。
通常调试和记录提供正交信息。如果您的调试器没用,那么日志可能会对您有所帮助。
这可能是对 _exit() 或某些 Windows 等效项的调用。尝试在 _exit 上设置断点...
您是否尝试过 PC Lint 等并在您的代码上运行它?尝试以最大警告编译如果这是一个 .NET 应用程序 - 使用 FX Cop。
可能的原因浮现在脑海。
最后一个尤其会导致应用程序立即失败。
堆栈溢出 - 您可能会收到通知,但不太可能。
进入调试器,将所有异常通知更改为“始终停止”而不是“如果未处理则停止”,然后执行导致程序失败的操作。如果您遇到异常,调试器将停止,您可以决定这是否是您正在寻找的异常。
我花了几个小时试图在 Windows 7 上运行 64 位应用程序的 Visual Studio 2017 上对此进行深入研究。我最终不得不在RtlReportSilentProcessExit函数上设置断点,该函数位于ntdll.dll文件中。只需基本函数名称就足以让 Visual Studio 找到它。
也就是说,在我让 Visual Studio 自动下载 C 标准库的符号后,它也自动停止了导致问题的运行时异常。