C ++:__ try ... _除外;在发布模式下隐藏崩溃?

时间:2012-05-21 21:20:02

标签: c++ crash try-catch buildconfiguration

我有一个在嵌入式Windows XP机器上运行的DX9应用程序。当将其自动化过夜进行浸泡测试时,它会在大约六到八个小时后崩溃。在我们的开发。机器(Win 7)我们似乎无法重现这个问题。我也很确定这不是内存泄漏。

  • 如果我们在嵌入式计算机上的Debug中运行相同的应用程序,它就不会崩溃。
  • 如果我们在嵌入式计算机上的主循环更新周围放置一个__try/__except,它就不会崩溃。

我知道在Debug中,本地堆栈周围有一些额外的字节填充,可能会“隐藏”本地数组访问超出范围,或某种未初始化的变量正在偷偷摸摸。

所以我有两个问题:

  1. 即使在发布中运行,__try/__except的行为是否与调试类似?
  2. 如果我们在发布模式下崩溃但在调试模式下没有崩溃,我应该扫描代码是什么类型的东西?

2 个答案:

答案 0 :(得分:3)

如果您使用的是__try{ } __except(),则不应该这样做 那些和C ++代码混合不好。 (例如,你不能在包含那些函数的堆栈上有C ++对象。如果使用try {} catch() {}(带省略号),你应该使用C ++ catch(...)它与{{{{1}基本相同1}}

__except()try.. catch在调试和发布中的行为相同。

如果您怀疑自己的问题是意外异常,则应阅读以下所有内容:

__try .. __except

使用前两个中的一个可能会让您很快找到问题所在。如果您想要对过程中可能出现的所有错误情况进行绝对控制,那么其余的就在那里。

具体来说,使用SetUnhandledExceptionFilter() _set_se_translator() _CrtSetReportMode() _RTC_SetErrorFunc() _set_abort_behavior() _set_error_mode() _set_new_handler() _set_new_mode() _set_purecall_handler() set_terminate() set_unexpected() _set_invalid_parameter_handler() _controlfp() 可以设置一个函数过滤器,它记录导致异常的代码的地址。然后,您可以使用调试器来指向该代码。使用DbgHelp库和过滤器函数提供的信息,您可以编写一些代码,打印出崩溃的完整堆栈跟踪,包括符号和行号。

确保设置构建配置以便为发布版本发出调试符号。他们只能帮助而且不做任何事情来减缓你的申请(但也许会让它变大)

答案 1 :(得分:0)

  

如果我们在嵌入式计算机上的主循环更新周围放置__try / __except,它就不会崩溃。

然后这样做。

整个程序周围的单个__try块(以及每个工作线程的入口点)是推荐的方法,它允许您在退出之前写出崩溃转储并生成错误报告。您可以使用SEH进行很多恢复,因为例外情况只是没有足够的信息来有效地区分不同的故障。但是,存储整个程序状态并将其拉入调试器非常有用。

注意:某些视频驱动程序会导致他们也遇到的SEH异常,也许某些逻辑可能会安装多个SEH范围,而__try阻止了这些范围。