2

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

  • 如果我们在嵌入式机器上的 Debug 中运行相同的应用程序,它不会崩溃。
  • 如果我们__try/__except在嵌入式机器上围绕主循环进行更新,它不会崩溃。

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

所以我有两个问题:

  1. 即使在发行版中运行,其行为是否__try/__except类似于调试?
  2. 如果我们在 Release 模式下发生崩溃,但在 Debug 模式下没有崩溃,我应该扫描哪些代码?
4

2 回答 2

3

如果你正在使用__try{ } __except()你不应该。
那些和 C++ 代码不能很好地混合。(例如,您不能在用这些对象包装的函数的堆栈上包含 C++ 对象。try {} catch() {}如果您使用catch(...)(带有省略号),则应该使用 C++,它的作用与__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()

使用前两个之一可能会让您很快查明您的问题。如果您希望对过程中可能出现的所有错误情况进行绝对控制,剩下的就在那里。

具体来说,SetUnhandledExceptionFilter()您可以设置一个函数过滤器来记录导致异常的代码的地址。然后,您可以使用调试器来确定该代码。使用 DbgHelp 库和提供给过滤器函数的信息,您可以编写一些代码,打印出崩溃的完整堆栈跟踪,包括符号和行号。

确保你设置你的构建配置来为发布构建发出调试符号。他们只能帮助并且不会做任何事情来减慢您的应用程序(但可能会使其更大)

于 2012-05-21T21:37:09.280 回答
0

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

然后这样做。

推荐使用围绕整个程序的单个__try块(以及每个工作线程的入口点),它可以让您在退出之前写出故障转储并进行错误报告。使用 SEH 无法进行太多恢复,因为异常只是没有携带足够的信息来有效地区分不同的故障。不过,存储整个程序状态并将其拉入调试器非常有用。

注意:一些视频驱动程序会导致它们也捕获的 SEH 异常,也许某些逻辑期望安装多个 SEH 范围,这是您的__try块提供的。

于 2012-05-21T21:44:47.187 回答