当来自外部库的线程不可预测地崩溃我的应用程序时,我该怎么办

What can I do when a thread from an external library crashes my application unpredictably?

本文关键字:我的 崩溃 应用程序 我该怎么办 不可预测 外部 线程      更新时间:2023-10-16

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

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

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

将该库移出您的流程

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

拦截并控制"坏"库的线程

您可以为进程挂接/拦截/重载系统调用(在类似POSIX的操作系统中,有几种方法可以做到这一点,但最简单的方法是使用LD_PRELOAD变量并预加载代码中的共享对象。Windows确实提供了类似的功能,但我不知道它被称为什么)。

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

从技术上讲,这是可行的,但我担心的是,在捕获并抑制该异常之后,您无法真正判断库将继续正常运行。因此,第一种方法更有可能奏效。

希望能有所帮助。

您可以通过安装带有SetUnhandledExceptionFilter的回调来捕获异常。并在线程启动时杀死它。

然而,这个例外是令人讨厌的。std::bad_alloc的常见原因不仅是内存不足,还可能是由损坏的堆触发的。两者都是不可恢复的情况,杀死线程不会恢复泄漏的内存,也不会破坏堆。此外,您已经通过杀死线程泄露了线程的堆栈。一般来说,你启动相机的几率很小,很可能会很快再次爆炸。只有当你的程序在没有摄像头的情况下仍然有用时,才考虑尝试这个。

在进程外运行它,这样您就可以完全失去状态,这是一种选择,但您需要的进程互操作非常痛苦,而且相对昂贵。

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