3

我想知道是否可以通过 dlopen 和朋友对动态链接库进行沙箱化。目的是从库中的错误中恢复,而不会破坏整个应用程序,例如 SEGFAULT 等。

有人在这方面有经验吗?

4

3 回答 3

4

您可以在调用库之前fork(),然后将结果传递给您的母进程。让母进程等待子进程的数据,如果崩溃则报告错误。

于 2010-07-17T13:41:33.863 回答
2

好的,一般来说异常处理高度依赖于操作系统。我将做一些假设并尝试提供一些通用的指导。请注意,这绝不是一个详尽的答复,但应该作为一个起点。

我会假设:

  1. 在大多数情况下,您对防止内存泄漏感兴趣。

  2. 由于您提到了 dlopen (否则您会说 LoadLibrary),因此您对 Windows(这是整个其他蜡球)不感兴趣

  3. 您知道链接到 C++ 符号的细微差别。如果您没有在 dlopen c++ 上的 mini howto 上阅读它

一般来说

如果不涉及提供数据和代码段沙盒的专用操作系统,则没有针对所描述问题的通用解决方案,有可信系统和专用操作系统内核可以做到这一点,但我假设你想在一个好的旧操作系统上做到这一点*nix 或 windows 环境。

编译器的东西使问题进一步复杂化(您的 C++ 编译器是否默认生成弱符号?通常会)这会影响异常处理在 try-catch 中的发生方式。

引发信号的简单操作系统异常处理(SIGSEGV、SIGFPE 等):

POSIX系统下支持sigaction ...

假设您想防止诸如不良内存寻址之类的通用事物。在 dlopen 库之前使用 sigaction 捕获 SIGSEG(以防止 .init 函数),然后在调用库中的函数之前进行信号检查。考虑使用 SA_STACK 以确保您的处理程序跳转到您可以很好地控制的堆栈中,并考虑使用 SA_SIGINFO 以确保您的处理程序获取有关源的信息。

一个很好的起点是GNU libc 上的信号处理手册

在 C++ 下:使用包装器和 try-catch 来捕获软异常

试试 { foo(); } catch() { // 做点什么 }

其中 foo 是指向 dll 中的函数的弱符号,请参阅 c++ dlopen mini-howto 以获取更多示例和有关加载类等的详细信息。

如果您有更具体的需求,请发布它们,我会看看我是否可以提供更多信息。

干杯

于 2010-07-17T14:22:46.753 回答
0

您将如何将段错误与您的应用程序和相关动态库区分开来?如 che 所述,创建一个单独的进程来隔离库似乎是最好的方法。

编辑:

发现了这个相关的问题,指向一个CERT建议,如果您希望可移植性,建议不要从 SIGSEGV 处理程序返回。

于 2010-07-17T14:22:52.353 回答