修改“__cxa_allocate_exception”,表示没有使用malloc

时间:2017-03-16 10:57:02

标签: c++ exception gcc exception-handling malloc

我在一个安全的嵌入式系统中工作,我想稍微修改一下异常处理。 __cxa_allocate_exception正在使用malloc()为异常对象分配内存。安全应用程序中不允许malloc / new,因此我必须重写它。

现在我的问题:在这种情况下,有没有办法避免使用malloc?

一些替代方案是:

  • 使用静态缓冲区,这会导致多任务/多核应用程序出现问题,所以我不能这样做。
  • 在堆上写入也会造成一些麻烦,因为堆可能已满(内存不足会无效)。
  • 最后,也许我可以分配(例如)16kb的任务堆栈空间,并且每个异常对象将具有1kb的常量大小。这样,我可以处理多达16个例外。如果它有任何意义或者甚至是可能的话,我对堆栈的理解可悲的是低,对它进行评级。

2 个答案:

答案 0 :(得分:4)

查看:gcc-6.3.0/libstdc++-v3/libsupc++/eh_alloc.cc(或更高版本)。在匿名命名空间中指定pool(内存)类并将其实例化为emergency_pool。您可以调整EMERGENCY宏值,或者完全替换实现 - 只要您在使用池时考虑线程安全性。

如果您事先了解调用堆栈深度,则可以修复池缓冲区的值,该值始终足够。同样,为了线程安全,您可能需要同步原语。

如果这还不够,__cxa_allocate_exception会在分配失败时调用std::terminate。这里std::set_terminate可能为您提供挽救重要信息的最后机会。

对于线程安全性,请使用与池相同的__gnu_cxx::__mutex对象以及__gnu_cxx::__scoped_lock惯用法。这样你就不依赖于任何libsupc++不依赖的东西,比如标准库原子或std::mutexstd::lock_guard - 即创建对libstdc++的依赖

答案 1 :(得分:3)

我们发布了一个开放源代码库,该库实现了用于异常处理的内存池:https://github.com/ApexAI/static_exception