2

我的应用程序使用了一个相机库,它会不断地向我的应用程序发送图像。不幸的是,这个库启​​动了一个抛出异常(或导致抛出异常)的线程并且不处理它。结果整个应用程序崩溃。有没有办法防止应用程序崩溃?我可以在外部线程上安装异常处理程序吗?

关于我的具体情况的一些细节:崩溃线程的调用堆栈中没有我可以控制的函数。我什至不知道线程到底是做什么用的。但是我用调试器停止程序,我可以知道它是哪个线程,那将崩溃。不幸的是,线程非常随机地崩溃,有时需要一个多小时才能发生某些事情。我正在使用 Visual Studio C++ 2010,调试器告诉我,它是一个 std::bad_alloc。

4

2 回答 2

2

我没有处理过 Windows,所以我无法为您提供执行此操作的具体方法,但这里有两个我认为适用于任何现代操作系统的想法。

将该库移出您的流程

您可以创建一个“帮助”应用程序,充当“主”应用程序和库之间的桥梁。这样,当“帮助”应用程序崩溃或开始出现故障(即使用太多内存等)时,您可以安全地反弹它而不会影响主应用程序。任何 IPC 方式都可用于在该“助手”和您的主应用程序之间建立通信。

“坏”库的拦截和控制线程

您可以挂钩/拦截/重载进程的系统调用(在类似 POSIX 的操作系统中,这样做的方法很少,但最简单的是使用LD_PRELOAD变量和预加载代码共享对象。Windows 确实提供了类似的功能,我不要计算它叫什么)。

CreateThread然后,您可以通过拦截线程创建例程/系统调用 ( ?)注入自己的代码,该代码可以将第三方库的线程例程包装在 try-catch 块中。

这在技术上是可行的,但我担心的是,您无法真正告诉库在您捕获并抑制该异常后会继续正常运行。所以第一种方法更有可能运作良好。

希望能帮助到你。

于 2012-08-22T16:08:38.710 回答
1

您可以通过使用 SetUnhandledExceptionFilter 安装回调来捕获异常。并在线程触发时杀死线程。

然而,例外是一个令人讨厌的例外。std::bad_alloc 的常见原因不仅是内存不足,还可能由损坏的堆触发。两者都是不可恢复的情况,杀死线程不会恢复泄漏的内存,也不会破坏堆。此外,您通过杀死线程泄漏了线程的堆栈。一般来说,你让相机运转的可能性非常小,它很可能会很快再次轰炸。仅当您的程序可以在没有相机的情况下继续有用时才考虑尝试此操作。

在进程外运行它以便您可以承受完全丢失状态是一种选择,但是进程互操作您将需要它痛苦且相对昂贵。

如果您无法从供应商处获得支持,那么您需要再次购物。

于 2012-08-22T16:50:29.260 回答