2010-07-17 61 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