检查 gdb 中的 C/C++ 堆内存统计信息
Posted
技术标签:
【中文标题】检查 gdb 中的 C/C++ 堆内存统计信息【英文标题】:Examining C/C++ Heap memory statistics in gdb 【发布时间】:2011-02-03 14:50:43 【问题描述】:我正在尝试从 Linux amd64 上的 gdb 中调查 C/C++ 堆的状态,有什么好的方法吗?
我尝试过的一种方法是“调用 mallinfo()”,但不幸的是我无法提取我想要的值,因为 gdb 没有正确处理返回值。
我不容易为我所附加的进程编写一个要编译成二进制文件的函数,所以我可以简单地实现我自己的函数来通过在我自己的代码中调用 mallinfo() 来提取值.是否有一个聪明的技巧可以让我即时执行此操作?
另一种选择可能是定位堆并遍历 malloc 标头/空闲列表;我会很感激任何关于我可以从哪里开始找到这些位置和布局的指针。
我一直在尝试使用 Google 并围绕这个问题阅读了大约 2 个小时,我学到了一些有趣的东西,但仍然没有找到我需要的东西。
【问题讨论】:
你需要了解什么状态?您需要了解哪些统计数据? 堆大小、使用量和空闲量是一个好的开始 gdb 什么地方做得不好? 好吧,我只是根据我的要求正确使用我自己的定义,即能够取消引用“call mallinfo()”返回的结构并查看成员的值其中。 遗憾的是,我认为情况变得更加复杂,因为劣质没有包含 malloc.h 并且“struct mallinfo”似乎不在类型列表中;也许如果是,那么 gdb 将允许我查询其成员。相反,我只返回一个整数值(可能是因为未包含函数定义并且它默认为 int 返回类型);这可能是一个指针,但我不知道如何取消引用它(不是指向内存的指针)。 【参考方案1】:@fd - RedHat bug 有你的答案。
mallinfo
函数已被弃用,不会更新。真正的查询统计 API 是 TDB。今天,你有malloc_stats
和malloc_info
。我找不到任何一个文档,但这是他们给你的。
这是否足够接近您的需求?
(gdb) call malloc_stats()
Arena 0:
system bytes = 135168
in use bytes = 96
Total (incl. mmap):
system bytes = 135168
in use bytes = 96
max mmap regions = 0
max mmap bytes = 0
(gdb) call malloc_info(0, stdout)
<malloc version="1">
<heap nr="0">
<sizes>
<unsorted from="1228788" to="1229476" total="3917678" count="3221220448"/>
</sizes>
<total type="fast" count="0" size="0"/>
<total type="rest" count="3221220448" size="3917678"/>
<system type="current" size="135168"/>
<system type="max" size="135168"/>
<aspace type="total" size="135168"/>
<aspace type="mprotect" size="135168"/>
</heap>
<total type="fast" count="0" size="0"/>
<total type="rest" count="3221220448" size="3917678"/>
<system type="current" size="135168
/>
<system type="max" size="135168
/>
<aspace type="total" size="135168"/>
<aspace type="mprotect" size="135168"/>
</malloc>
【讨论】:
干得好,我昨晚发现了 malloc_stats() 并在今天早些时候的测试中使用它,效果非常好。我还遇到了 sourceware 的 glibc wiki,它指向 Ulrich Drepper 的 livejournal 与这篇文章 - udrepper.livejournal.com/20948.html - 从 09 年 4 月开始,描述了 mallinfo 的替换(以及其他内容),但我还没有尝试过。感谢您发布输出,看起来很有趣。 +1 顺便问一下,你找到 malloc_info() 的文档了吗?第一个参数是否描述了竞技场编号?我在输出中看到if (options != 0) return EINVAL
- sourceware.org/git/?p=glibc.git;a=blob;f=malloc/…。看起来它遍历了所有领域。
我正在运行的进程标准输出被重定向到某个日志文件。所以call malloc_stats()
没有在控制台上打印出来,而是在那个日志文件上打印出来。我花了将近一个小时才弄明白。【参考方案2】:
如果可以改代码:
#include <malloc.h>
#include <stdio.h>
void dumpMallinfo(void)
struct mallinfo m = mallinfo();
printf("uordblks = %d\nfordblks = %d\n", m.uordblks, m.fordblks);
在GDB中,你可以call dumpMallinfo()
。
【讨论】:
正如我在问题中所说,我不能,但是这是一种有用的技术。 +1(这是 2 小时谷歌搜索所揭示的方法之一) 找到了一些关于 mallinfo() 的有用信息;它似乎没有准备好 64 位。返回的结构由 int 成员组成,不处理大于 4GB 的字节大小。尽管我发现 Debian 和 RedHat 错误报告都以 NOTABUG/WONTFIX 的形式关闭,但我还没有找到任何解决此问题的证据。 在下面重申我对 dave 其他答案的评论: mallinfo() 似乎也受到限制,因为它只显示来自第零场的信息,这就是我对它的测试不匹配的原因我看到的 top 报告的内存使用情况;此外,没有一个单一的竞技场统计数据增长到足以解决我之前提到的错误。 malloc_stats() 显示来自所有领域的信息。以上是关于检查 gdb 中的 C/C++ 堆内存统计信息的主要内容,如果未能解决你的问题,请参考以下文章