如何重新加载经常崩溃的第 3 方 DLL

Posted

技术标签:

【中文标题】如何重新加载经常崩溃的第 3 方 DLL【英文标题】:How to reload a 3rd party DLL that crashes often 【发布时间】:2008-12-10 22:53:52 【问题描述】:

我正在使用用非托管 C++ 编写的第 3 方 DLL,它控制我们拥有的一些硬件。

不幸的是,这个 DLL 不时崩溃,我的任务是让它自动“重新加载”。我不太确定如何继续获得最佳结果。

我的项目使用 C++.Net 2.0 (2005)。我将第 3 方的东西包装在一个单独的 DLL 中。我一直在尝试 FreeLibrary() 和 LoadLibrary()。但是,当我使用 FreeLibrary() 时,仍然分配了一些内部 DLL 依赖项,并且 LoadLibrary() 会因为内存损坏而使其崩溃。

建议的另一种方法是使用 .NET 远程处理接口重构整个项目。杀死另一个进程并重新启动它会更容易,但工作量很大。

有什么建议吗?指针?提示?

【问题讨论】:

【参考方案1】:

最有效的方法是根本不在应用程序的进程中加载​​该 DLL。相反,创建第二个进程,其唯一工作是代表您的应用程序使用该 DLL。您可以使用共享内存区域、本地套接字或其他 IPC 机制来控制代理进程。

这样,当有问题的 DLL 崩溃时,您可以简单地让代理进程终止,而不必担心(几乎不可能)尝试确保 DLL 在其崩溃过程中没有损坏任何重要内容的任务。您的主进程只需要启动代理进程的新实例并继续。

【讨论】:

【参考方案2】:

我不是 Windows 专家,但我认为总体思路应该成立。

LoadLibrary、FreeLibrary 处理将 DLL 映射到进程内存空间。您看到的损坏可能是由于 DLL 中的某些代码做了一些“坏事”并且几乎​​肯定会损坏进程内存。现在如果它崩溃了,它几乎肯定会杀死它正在运行的线程——如果不是整个进程的话。

我会做出一个有根据的猜测,可靠地恢复并确保内存未损坏的唯一方法是运行一个牺牲进程作为流氓 DLL 的包装器。我认为远程接口是这样做的一种方式。可能还有其他人。

【讨论】:

对,对于本机代码,您永远不知道它损坏了哪些内存(结构) - 包括自己的 CLR。​​【参考方案3】:

LoadLibrary 和 FreeLibrary 是开始,但如果您希望能够在 DLL 中避免崩溃,则需要将所有调用包装到 SEH(结构化异常处理)__try / __catch 块中的 DLL 中。注:这与 C++ 异常和 try/catch 块完全不同。有关详细信息,请参阅 MSDN。

【讨论】:

【参考方案4】:

如果 DLL 本身崩溃而您的公司愿意这样做,那么花时间重新创建它可能是值得的。更好地解决问题,而不是仅仅包扎它。

【讨论】:

除非您要进行逆向工程,否则这可能是不可行的。对于仅软件的 DLL,这可能是一个合理的建议,但对于驱动程序来说,这并不实用。 我不能真正做到这一点,因为 DLL 直接与我一无所知的专有硬件接口。此外,还有很多非常复杂的数学算法涉及到这样的

以上是关于如何重新加载经常崩溃的第 3 方 DLL的主要内容,如果未能解决你的问题,请参考以下文章

DLL 重新加载到它们的首选地址

如何动态加载和卸载(重新加载).dll 程序集

如何使用 MSBuild 引用不同版本的 dll

用 C# 重写 MFC DLL?

如何监听来自第 3 方 DLL 的表单的“Form.Shown”和“Window.Closing”?

C#:如何包含依赖的 DLL?