如何找到分配动态内存的C ++语言结构?

时间:2018-04-13 08:54:49

标签: c++ embedded

我在嵌入式系统固件代码基础上工作,目前使用动态内存分配。现在,出于可靠性原因,应删除所有动态内存分配。

作为第一步,我删除了_sbrk系统调用实现,这样所有动态分配都无法链接。由于我使用-ffunction-sections -fdata-sections进行编译并与-Wl,-gc-sections链接,因此只要没有动态内存分配,我就希望链接步骤完成。 (这在过去的C项目中对我有用,在这里不确定C ++。)

虽然预期会出现以下链接器错误消息,但它无助于找到触发动态分配的C ++构造。

[...]arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status

是否有一种有效的方法来查找使用动态堆分配的C ++语言结构(除了明显使用 new 之外)?

编辑:我正在寻找静态工具,而不是运行时仪器/分析技术。

EDIT2 :(由于有人删除了相应的标签:)该项目针对STM32F4 MCU,并与基于GCC的arm-none-eabi- *工具链进行编译和链接。

2 个答案:

答案 0 :(得分:3)

阻止与sbrk链接的问题是sbrk是堆管理过程的最底层,并不一定要调用所有分配。它只是添加到现有堆池的一种方法。

new运算符可能过载,或者是placement-new,因此甚至无需通过系统堆执行动态分配或分配。但new的实例至少会调用malloc()

GNU链接器--cref输出可能会有所帮助;这将告诉您每个符号,哪些文件引用它们。遗憾的是,GNU链接器没有ARM链接器具有的--callgraph选项,它将显示导致任何特定功能的完整调用路径。

避免动态内存分配的显式链接可能意味着删除标准库的大部分C ++特定部分 - 当然是STL容器类std::string

答案 1 :(得分:0)

  

有没有一种有效的方法来查找使用动态堆分配的C ++语言结构?

是的,有:地块。

Massif是一个内存分析器,可以帮助您确定代码库中内存的分配位置。使用这样的列表,您可以更改所有有罪的代码并再次检查没有动态分配。

来自Massif (valgrind) documentation

  

Massif是一个堆分析器。它测量程序使用的堆内存量。 [...]重要的是,Massif不仅会告诉您程序正在使用多少堆内存,还会提供非常详细的信息,指示程序的哪些部分负责分配堆内存。

     

默认情况下,Massif不会测量[直接用于分配内存的低级系统调用]但是,如果您希望测量 all 程序使用的内存,则可以使用{{ 1}}。

由于你在嵌入式系统上工作,它可能会使你的代码库有点困难;但是可以通过拥有一个linux / windows端口或通过在你的特定目标上运行massif来实现。