【问题标题】:Examining C/C++ Heap memory statistics in gdb检查 gdb 中的 C/C++ 堆内存统计信息
【发布时间】: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 返回类型);这可能是一个指针,但我不知道如何取消引用它(不是指向内存的指针)。

标签: linux gdb malloc x86-64 heap-memory


【解决方案1】:

@fd - RedHat bug 有你的答案。

mallinfo 函数已被弃用,不会更新。真正的查询统计 API 是 TDB。今天,你有malloc_statsmalloc_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() 的文档了吗?第一个参数是否描述了竞技场编号?我在输出中看到 ,并且在我的测试中 malloc_stats() 显示了许多领域的统计信息(此外: mallinfo() 似乎也受到限制,因为它只显示来自零的信息- th arena,这就是为什么我对它的测试与我看到的 top 报告的内存使用不匹配;此外,没有一个单独的 arena 统计数据增长到足以击中我之前引用的错误)。
  • 我找不到 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() 显示来自所有领域的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-18
  • 2020-05-09
  • 2011-01-07
  • 1970-01-01
  • 2015-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多