2010-07-17 142 views
3

我想知道是否可以通过dlopen和朋友沙盒动态链接库。其目的是从库中的错误中恢复,而不会撕毁整个应用程序,例如SEGFAULT等。C++沙盒动态库

任何人都有过这方面的经验吗?

回答

1

好吧,一般来说,异常处理是高度依赖操作系统。我将做出一些假设并尝试提供一些通用指导。请知道,这绝不是一个详尽的答复,但应该成为一个开始的地方。

我会假设:

  1. 在大多数情况下,你有兴趣在维护对内存泄漏。

  2. 你有没有兴趣在Windows(这是全其它球头的蜡),因为你提到的dlopen(你会以其他方式表示的LoadLibrary)

  3. 您知道链接的细微差别针对C++符号。如果你没有在mini howto on dlopen c++

读了它一般来说

不存在对上述问题没有通用的解决方案,而不涉及专业操作系统提供的数据和代码段砂拳击有可信系统和专业操作系统内核,可以做到这一点,但我认为你想在一个好的旧的* nix或Windows环境中做到这一点。

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

简单的操作系统异常处理(SIGSEGV,SIGFPE等):

在POSIX系统配套的sigaction ...

比方说,你想防止类似事情的通用错误的内存寻址。在调用库之前使用sigaction陷阱SIGSEG(以防止.init函数),然后在调用库中的函数之前进行信号检查。考虑使用SA_STACK来确保您的处理程序跳转到您有良好控制权的堆栈中,并使用SA_SIGINFO确保您的处理程序获取有关源的信息。

一个很好的开始,这是在Signal handling on GNU libc manual

在C++:使用包装,并用的try-catch赶上软例外

尝试{ 富(); } 赶上(){// 做一些 }

其中foo是一个弱符号指向功能,在您的DLL see c++ dlopen mini-howto for a lot more examples and details on loading classes etc.

如果你有更具体的需求,张贴,我去看看如果我可以提供更多信息。

干杯

4

您可以在致电图书馆之前fork(),然后将结果传递给您的母亲进程。让母亲等待来自孩子的数据,或者如果它崩溃则报告错误。

+0

谢谢你的时间。我曾考虑过这种方法,但这是一个相当重的手段,希望能有一个更优雅的解决方案。 – Corvusoft 2010-07-17 13:48:04

+2

当你链接库代码时,你与它共享内存,这意味着它的错误不仅可以是段错误,还可以用垃圾覆盖你的内存。如果你想防范,流程分离是最好的选择。 – che 2010-07-17 14:35:00

+0

由于分叉创建了一个全新的上下文(即使它本质上是相同的,它仍然是一个副本),分叉并不是正确的方法,这很简单,因为增加您喜欢的库的使用次数是“不同的” – 2010-07-17 19:13:54

0

你如何区分你的应用程序和有问题的动态库段错误?创建一个独立的进程来隔离库所描述的似乎是最好的方法。

编辑:

发现this相关的问题,在CERT advisory指着不建议如果你希望移植到从SIGSEGV处理程序返回。

+0

使用sigaction SA_SIGINFO,您可以确定发送信号的上下文,这意味着如果以编程方式回溯,可以确定引发信号的函数,并确定它是否是库中的函数,并且由于您正在捕捉信号,你可以正确地恢复。执行fork()不是确定库的弹性的好方法... – 2010-07-17 19:12:14