我有一个错误导致我的应用程序消失而没有错误消息或类似的东西。该应用程序刚刚从屏幕上消失,它不再列在任务管理器上。
该应用程序是一个C ++ Builder应用程序(CBuilder2007),我已经尝试了所有我想到的尝试捕获此错误。它很少发生,它从未在我的机器上崩溃,只在我们在办公室的测试机器中崩溃过一次。对于我们的一个客户来说,它更频繁地发生,但我们还没有找到实现它的方法,或者找到发生这种情况的情况。这是一个沉重的多线程应用程序。
我在这个应用程序中启用了madExcept,但它没有抓到任何东西。我已经使用set_terminate
和set_unexpected
RTL例程添加了处理程序,没有任何运气。
我所拥有的唯一信息来自我所做的“加载器应用程序”包装器,以从主应用程序获取返回代码。它以C0000005
代码退出,我相信这意味着发生了访问冲突。奇怪的是,如上所述,甚至没有Windows错误框或类似的东西。
问题是:有任何想法试图抓住这个吗?因为我甚至不知道这可能发生的事情(我在应用程序周围有很多日志记录,但应用程序崩溃之前的“踪迹”并没有导致任何地方)我的想法set_terminate
和set_unexpected
例程是为了获得一个堆栈跟踪来试图查看错误的生成位置,但到目前为止这些例程根本没有被调用(至少在我的办公室里发生这种情况的唯一时间)< / p>
提前致谢
[Update 22.Sept.2009]使用AddVectoredHandlerException我能够从崩溃中获得一个callstack,现在我可以开始尝试隔离并修复bug。感谢!!!
答案 0 :(得分:6)
terminate
/ unexpected
仅由C ++运行时调用,仅用于C ++异常。
访问冲突是一个SEH例外 - 要注意这一点,您需要SetUnhandledExceptionFilter或AddVectoredExceptionHandler(如果它是&gt; = XP)。然后,您可以使用MiniDumpWriteDump和相关的。
创建一个小型转储答案 1 :(得分:3)
我偶然遇到过这样的问题,应用程序似乎停止了。不会调用异常处理程序或崩溃处理程序等。该应用程序似乎只是立即终止。
不幸的是,我无法就如何弄清楚提供任何简单的建议。这里的其他回复有一些好主意。如果根据PiotrLegnica的回应,你还没有抓住未处理的异常,那么你应该这样做。
但是,如果程序真的像我看到的那样立即终止,那么即使是在SetUnhandledExceptionFilter
注册的处理程序也无济于事。该程序在调用处理程序之前停止所有执行和内存不足。
尽管如此,我还是想到了一些想法:
WindowProc
。确保调用约定,参数列表和返回值都正确匹配。如果正在编译函数指针以使代码编译,则可能隐藏了可能导致不良事件发生的不匹配。关于日志记录的主题:当我不得不帮助追踪这样的问题时,我们最终创建了一个日志记录机制,每次程序启动时都会创建一个唯一命名的日志,如果该计划正常结束。这样,每次发生终止问题时,都会留下另一个日志文件。我们使用日期时间戳作为唯一命名方面的一部分。日志的内容只是记录程序中发生的操作。我们经历了几次迭代检查日志,然后添加了更多的日志记录语句,直到最终导致我们来源。在追踪问题的同时,这种机制让我们对问题的发生频率有了清晰的认识。你可能会考虑类似的事情。
答案 2 :(得分:1)
我之前看到过这种情况发生在C ++代码上两次:
使用LoadLibrary
和GetProcAddress
动态加载Windows API,然后通过使用错误的调用约定声明的函数指针调用它(它应该有__stdcall
但是没有“T)。
当一个类有一个函数指针作为成员变量,并且在初始化之前调用了函数指针。
答案 3 :(得分:1)
您必须在调试模式下运行应用程序,并通过越来越多地运行复杂场景集来进行压力测试,这样您就可以在调试模式下捕获异常。
同样尝试再次查看包含访问线程之间共享内存的代码,可能是多线程的问题,你可以尝试在每个共享内存访问上设置锁定以确保多线程处理(但这会降低性能) )
答案 4 :(得分:1)
Re:应用程序消失,客户机器是否在Windows中关闭了“报告错误”设置?它隐藏在“系统”控制面板中,当它关闭时,正常的Windows崩溃通知对话框被压制。
答案 5 :(得分:1)
也许添加一个好的,老式的信号处理程序可能至少可以说明发生了什么?
答案 6 :(得分:1)
如果您无法在本地重现,那么您将遇到困难。 正如其他人所建议的那样,捕获崩溃转储或使用调试器捕获程序当然是最佳选择。
如果这是我的问题,我会尝试使用sysinternals中的Process Monitor进行监控。将其设置为仅监视您的进程,如果需要很长时间,请确保它由文件支持。这可能会告诉您哪个线程处于活动状态以及进程结束时发生了什么。您也可以尝试为Windows找到相应的“truss” - 一个监控系统调用的程序。
答案 7 :(得分:0)
我可能会考虑过去做的另外两件事:堆栈溢出(无限递归,导致大型临时变量位于堆栈上的错误参数等),或者辅助中未处理的异常线程。
答案 8 :(得分:0)
配置您的应用以在发生崩溃时编写小型转储。
我不确定这在CBuilder中是怎么回事,但在visual studio中你可以直接加载这个转储,它会显示一个完整的callstack和导致崩溃的源代码行。
我经常使用它来查找客户机器上发生崩溃的原因 但是,特别是对于多线程应用程序而言,真正的错误(例如内存早期发布)很可能在实际崩溃之前发生了一段时间,因此找到根本原因可能仍然非常困难。
答案 9 :(得分:0)
订阅Windows错误报告。有些客户可能会向微软公司报告AV,他们很乐意与您分享收集的堆栈跟踪信息。作为一个好处,您可以获得有关应用程序可靠性的详细数据。管理层喜欢这些。例如。您可以设定“到2010年将错误频率降低50%”的目标。
答案 10 :(得分:0)
让您的应用程序运行,然后附加windbg(崩溃模式),即第一次出现第二次机会异常生成转储。记得放上符号文件(PDB)。