我想知道是否可以通过 dlopen 和朋友对动态链接库进行沙箱化。目的是从库中的错误中恢复,而不会破坏整个应用程序,例如 SEGFAULT 等。
有人在这方面有经验吗?
您可以在调用库之前fork(),然后将结果传递给您的母进程。让母进程等待子进程的数据,如果崩溃则报告错误。
好的,一般来说异常处理高度依赖于操作系统。我将做一些假设并尝试提供一些通用的指导。请注意,这绝不是一个详尽的答复,但应该作为一个起点。
我会假设:
在大多数情况下,您对防止内存泄漏感兴趣。
由于您提到了 dlopen (否则您会说 LoadLibrary),因此您对 Windows(这是整个其他蜡球)不感兴趣
您知道链接到 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 以获取更多示例和有关加载类等的详细信息。
如果您有更具体的需求,请发布它们,我会看看我是否可以提供更多信息。
干杯