C++ 如何调试无跟踪崩溃

C++ 如何调试无跟踪崩溃,c++,c,windows,debugging,c++builder,C++,C,Windows,Debugging,C++builder,在开发out应用程序的过程中,我们特别遇到了一个非常严重的错误。症状很简单,这个过程消失了。日志只是突然结束,找不到崩溃转储或任何东西,也不存在僵尸进程。沃森医生没有注意到任何东西没有留下任何痕迹 该错误不容易重现,重现该错误平均需要3-4小时,重复执行相同的操作。所以在某个地方存在某种种族状况。我们有处理SEH和正常异常的特殊函数,所以这些都不应该被忽略 调试必须在一台特殊的计算机上进行,因为它运行在非常专用的硬件上。因此,只有远程调试可用。当远程调试被连接时,C++ Builder没有注意到

在开发out应用程序的过程中,我们特别遇到了一个非常严重的错误。症状很简单,这个过程消失了。日志只是突然结束,找不到崩溃转储或任何东西,也不存在僵尸进程。沃森医生没有注意到任何东西没有留下任何痕迹

该错误不容易重现,重现该错误平均需要3-4小时,重复执行相同的操作。所以在某个地方存在某种种族状况。我们有处理SEH和正常异常的特殊函数,所以这些都不应该被忽略

调试必须在一台特殊的计算机上进行,因为它运行在非常专用的硬件上。因此,只有远程调试可用。当远程调试被连接时,C++ Builder没有注意到应用程序丢失,当我们试图在不存在的进程上进行任何调试时崩溃和烧毁。 我们在该软件中使用了多种技术:

  • OpenGL
  • Directshow+一些COTS过滤器
  • COM/DCOM
  • 与专用硬件通信的串行COM端口
  • C++Builder(使用与VC++不同的堆栈框架)
所以,正如你所理解的,我在这里没有太多的工作要做。我现在所做的是,我试图通过在代码中的不同位置进行日志记录来缩小它的范围,以发现代码中是否存在某个特定的错误点。我还试图删除我正在执行的操作的许多方面,以使案例尽可能简单。但这是一个非常复杂的操作,这个过程需要很多时间,而且时间(通常)是一种稀缺资源


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

如果您想更频繁地调试场景,请尝试在虚拟机中运行此程序并拍摄“快照”经常在它发生之前


这里的问题可能与您提到的通过串行端口连接的专用硬件的状态不一致。

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


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

当Windows下的本机代码遇到堆栈溢出(通常是由于无限递归)时,该过程有时会完全按照您所描述的那样消失。标准错误对话框和异常处理需要一些堆栈空间,如果没有剩余空间,则无法运行。(Windows的更高版本可以更好地处理此问题,并且应该始终引发异常-根据此定义,Windows XP不是“更高版本”。)

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


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

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



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

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

我在此将这类错误命名为“百慕大三角错误”。您运行这类错误的确切Windows版本是什么?这是在定制的嵌入式XP上运行的。@caf-hehe,我实际上将这类错误命名为忍者错误,因为它扼杀了进程并消失得无影无踪:首先,所有硬件使得虚拟化环境几乎不可能(并非双关语)。其次,我无法理解硬件的状态如何影响我们的流程。它只能通过串行端口访问。所以,内部的错误可能会导致固件挂起、通信问题,但进程终止???我猜windbg会在不熟悉的堆栈帧上遇到问题,但如果它给我的地址比我现在的地址更多的话。我会看一看的。谷歌搜索windbg Borland表明,你可以得到函数名,但不能得到变量名。@MSalters,谢谢你,我不知道。我之前尝试过其他vc++sentric工具,但没有获得太多信息,但知道这一点,我肯定会尝试。在windbg中尝试使用断点,只要你认为执行语句会改变程序逻辑。@Biswanath Chowdhury:不,我没有说,我也没有打算说vc++调试器。我完全了解WinDBG与WinDBG的区别,因为两者都是并行安装在我的机器上的。VC++调试器更能理解C++,但WinDBG对x86的理解要好得多。+ 1提到编写自己的跟踪日志。在调试晦涩难懂的东西时,日志信息的每一点都像金子一样!您可能是对的,但是我们已经设置了结构化异常处理(SEH),如果发生堆栈溢出,操作系统应该通知它。在以前的案例中我也看到了