gpt4 book ai didi

c++ - 如何调试无痕崩溃

转载 作者:可可西里 更新时间:2023-11-01 13:51:03 25 4
gpt4 key购买 nike

在开发应用程序的过程中,我们特别遇到了一个非常讨厌的错误。症状很简单,就是进程消失了。日志突然结束,找不到故障转储或任何东西,不存在僵尸进程。 Dr.Watson 还没有注意到任何让我们无影无踪的东西。

该错误重现并不简单,重现此错误平均需要3-4小时,重复执行相同的操作。所以某处存在某种竞争条件。我们有处理 SEH 异常和正常异常的特殊函数,所以这些都不应被忽视。

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

我们在该软件中使用了多种技术:

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

因此,如您所知,我在这里没有太多工作要做。我现在正在做的是,我试图通过在代码中的不同位置登录来缩小它的范围,以查找代码中是否有某些特定点会发生错误。我还试图删除我正在执行的操作的许多方面,以使案例尽可能简单。但这是一个非常复杂的操作,这个过程会花费很多时间,而时间(和往常一样)是一种稀缺资源。

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

最佳答案

当 Windows 下的 native 代码遇到堆栈溢出(通常是由于无限递归)时,进程有时会完全按照您的描述消失。标准错误对话框和异常处理需要一些堆栈空间,如果没有,它们将无法运行。 (更高版本的 Windows 可以更好地处理这个问题,应该总是引发异常 - Windows XP 在这个定义下不是“更高版本”。)

最简单的强力调试方法是在每个函数的入口(也可能是导出)写入日志消息。这些消息必须直接进入文件,如果您有缓冲输出(例如cout 或类似的),您应该每次都立即刷新它。当您设法导致崩溃时,您将获得至少可以定位问题的堆栈跟踪。


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

如果您在调试器下运行并中断/记录保护页异常,您将在堆栈扩展时收到通知 - 让异常得到处理,因为它被用于提交更多内存并且实际上可能与问题。


进程消失的最终非堆栈溢出原因是对 exit()ExitProcess() 的误调用。全文搜索应该能够在很大程度上排除这种情况 - 调试器中 ExitProcess 函数的断点将完全排除这种情况。

关于c++ - 如何调试无痕崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5152143/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com