在 GDB 中,如何找出谁在堆上分配了地址?
Posted
技术标签:
【中文标题】在 GDB 中,如何找出谁在堆上分配了地址?【英文标题】:In GDB, how to find out who malloc'ed an address on the heap? 【发布时间】:2011-03-21 00:10:22 【问题描述】:我在 GDB 中有一个指针,我怎样才能找到它在堆上的第一次分配位置?
在WinDBG中,这可以在开启gflags /i <*exe> +ust
后由!heap -p -a <0x12345678>
完成
既然 Valgrind 可以告诉我内存分配在哪里(当它检测到一些泄漏时),我想这也是可能的?
(这与观察点无关。这是考虑到我随机闯入 GDB 中的应用程序,查看指针并想知道“谁创建了这块内存”的情况?)
在 GDB 中使用反向调试是一种非常新颖的方法,并且可能是解决此问题的正确方法。我在使用 GDB 7.1 时遇到了一些问题——最新的稳定版本。反向调试是 GDB 中一个相当新的功能,所以我需要查看 HEAD (7.2) 来修复它。
它可能说明了 GDB 方法的成熟度,但我认为当它更成熟时绝对应该使用它。 (很棒的功能!)
【问题讨论】:
【参考方案1】:也许reverse debugging 在这里会有所帮助。尝试在内存地址上设置观察点并reverse-continue直到内存写入。
(gdb) watch *0x12345678
(gdb) reverse-continue
【讨论】:
谢谢!你的方法和尼古拉的方法似乎都是有效的。您的方法更聪明,可能更接近 GDB(因此是问题标题)。另一方面,了解 mtrace 和 glib 分配调试是很有见地的。在选择正确答案之前,我会同时尝试这两种方法,看看哪一种在实践中更好。 是的,这很有趣,但除了非常小的程序(更不用说多线程)之外,我认为它不实用。 @Nikolai:这似乎是真的。虽然从技术角度来看,反向调试确实令人兴奋,但在许多情况下它可能还不够成熟。一个引人注目的是record
它不会在 Hello World 程序中运行,因为它拒绝记录任何 IO(TTY、文件系统等)。仅此一点就使得在任何现实生活中使用它都不切实际。我不确定这是否是预期的行为。
是的,看来需要改进反向调试才能在实践中使用。【参考方案2】:
Valgrind 劫持内存管理调用,这就是堆检查器的工作方式。 GDB 本身没有工具可以告诉您malloc(3)
返回给定地址的位置。我建议调查mtrace 和glibc allocation debugging。
【讨论】:
谢谢!您的方法和 ks1322 似乎都有效。了解 mtrace 和 glib 分配调试很有见地。另一方面,我觉得 ks1332 的方法更聪明,可能更接近 GDB(因此是问题标题)。在选择正确答案之前,我会同时尝试这两种方法,看看哪一种在实践中更好。【参考方案3】:记录确实在 Hello World 程序上运行。 哎呀,我使用记录来调试 gdb 本身!
【讨论】:
感谢提醒!当我尝试时,我显然是无知的——它说“不支持操作或其他东西”。我认为这可能与 32bit 64bit 问题有关。我在一个纯 32 位的 Ubuntu 上再次尝试,它就像一个魅力!关于为什么它可能不适用于 Arch x86_64 的任何指导? (我怀疑它可能与 64 位版本的 glibc 或其他东西有关,我不知道:P) record/replay 有时会发出一些警告,但这并不一定意味着它不起作用。它也应该适用于 x86_64,但 i386 支持更成熟。 我调查了这个问题。这个特殊问题是因为我的 libc 被编译为包含一些 GDB 7.1 不支持的 MMX 指令。我检查了 HEAD(在撰写本文时为 7.2)并且它有效。以上是关于在 GDB 中,如何找出谁在堆上分配了地址?的主要内容,如果未能解决你的问题,请参考以下文章