2017-03-16 70 views
0

我正在一個安全的嵌入式系統中工作,並且我想修改一下異常處理。 __cxa_allocate_exception正在使用malloc()爲異常對象分配內存。 malloc/new在安全應用程序中是不允許的,所以我必須重寫它。修改不使用malloc的「__cxa_allocate_exception」

現在我的問題:有沒有辦法避免malloc在這種情況下?

一些替代方案是:

  • 使用靜態緩衝區,這將導致在多任務/多核心應用程序的問題,所以我不能做到這一點。
  • 在堆上寫入也會導致一些麻煩,因爲堆可能已滿(內存不足不會工作)。
  • 最後,也許我可以分配(例如)16kb的任務堆棧空間,每個異常對象將有一個1kb的常量大小。這樣,我可以處理多達16個例外。如果它有任何意義或者甚至是可能的,我對這個堆棧的理解可悲的是很低,要評估它。
+0

線程局部變量是一個可行的解決方案嗎? – arrowd

+0

你真的*需要*例外嗎?在小型嵌入式系統中,異常通常是一個壞主意。更不用說在C++中拋出異常通常非常昂貴,所以應該只用於真正的異常事件。 –

+0

預先保留內存會增加內存不足的風險,而不是減少內存。 –

回答

0

看一看:gcc-6.3.0/libstdc++-v3/libsupc++/eh_alloc.cc(或更高版本)。(內存)類在匿名命名空間中被指定並實例化爲emergency_pool。您可以調整宏值,或者完全替換實現 - 只要您在使用池時考慮線程安全性即可。

如果您事先了解了調用堆棧深度,則可以修復池緩衝區的值,該值永遠足夠。同樣,爲了線程安全,您可能需要同步原語。

如果這還不夠,__cxa_allocate_exception如果分配失敗,則調用std::terminate。這裏的std::set_terminate可能會爲您提供挽救重要信息的最後機會。


線程安全的,使用相同的__gnu_cxx::__mutex對象池並與__gnu_cxx::__scoped_lock成語一起。這樣,您不依賴於任何東西libsupc++不依賴於像標準庫原子或std::mutexstd::lock_guard - 即創建對libstdc++的依賴關係。

+0

謝謝你,你的回答對我來說是完美的。我使用emergency_pool作爲exception_pool。就像你說的那樣,我根據堆棧深度調整了緩衝池。目前我正在尋找一種保證線程安全的好方法。 – xMutzelx

+0

@xMutzelx - 您可以使用與池相同的作用域鎖定(請參閱更新)。 –

+0

謝謝你的幫助。你的回答是完美的地方。 – xMutzelx