2017-03-16 56 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