Memory leaks Gdb在特定区域转储内存,将格式化输出保存到文件中

Memory leaks Gdb在特定区域转储内存,将格式化输出保存到文件中,memory-leaks,gdb,dump,coredump,Memory Leaks,Gdb,Dump,Coredump,我有一个有缺陷(内存泄漏)的软件。 作为证据,我有1GB的core.dump文件。堆大小是900MB,所以很明显,有些东西分配了内存,但并没有释放内存 所以,我有一个记忆区域要这样检查 (gdb) x/50000s 0x200000000 然而,只有用肉眼很难猜出哪个对象或结构没有被释放。 我跟踪的想法是,“将gdb格式的输出保存到一个文件中,并运行模式匹配以查看哪个魔术字符串最多。”因此,我的问题是: 如何将以下命令的输出保存到文本文件中,以便编写分析器 (gdb) x/10000000s

我有一个有缺陷(内存泄漏)的软件。 作为证据,我有1GB的core.dump文件。堆大小是900MB,所以很明显,有些东西分配了内存,但并没有释放内存

所以,我有一个记忆区域要这样检查

(gdb) x/50000s 0x200000000
然而,只有用肉眼很难猜出哪个对象或结构没有被释放。 我跟踪的想法是,“将gdb格式的输出保存到一个文件中,并运行模式匹配以查看哪个魔术字符串最多。”因此,我的问题是:

如何将以下命令的输出保存到文本文件中,以便编写分析器

(gdb) x/10000000s 0x20000000    <-- I need this output into a file
 (gdb) x/10000000s 0x20000000
(gdb)x/100000000000x20000000
如何将以下命令的输出保存到文本文件中,以便编写分析器

(gdb) x/10000000s 0x20000000    <-- I need this output into a file
 (gdb) x/10000000s 0x20000000
这其实很简单:

(gdb) set height 0    # prevent GDB from stopping every screenfull
(gdb) set logging on  # GDB output is now also copied into gdb.txt
(gdb) x/10000000s 0x20000000
(gdb) quit
瞧,在
gdb.txt
中享受您的输出吧

我有一个有缺陷(内存泄漏)的软件。。。将gdb格式的输出保存到一个文件中,并运行模式匹配以查看哪个魔术字符串出现最多

这种想法不大可能产生令人满意的结果。考虑:

void some_function() {
   std::vector<string> *v = new std::vector<string>();
   // code to insert and use 1000s of strings into "v".
   return;  // Oops: forgot to delete "v".
}
void some_函数(){
std::vector*v=新的std::vector();
//在“v”中插入并使用1000个字符串的代码。
return;//Oops:忘记删除“v”。
}
即使你能有效地“看到出现最多的神奇字符串”,你也会发现你正在泄漏所有字符串;但它们不是问题,泄漏“v”才是问题所在

因此,您真正想要的是构建一个图,其中分配的区域指向其他分配的区域,并找到该图的“根”。这几乎不可能用手做到

那么,什么更有可能帮助您找到内存泄漏呢?幸运的是,有很多工具可以为您解决此问题:

  • ,
  • 谷歌堆泄漏
  • ,
  • 。。。等等等等
您可以使用gdb的“转储”功能,请参阅:

例如:

dump binary memory result.bin 0x200000000 0x20000c350
这将为您提供一个普通的二进制转储int文件
result.bin
。您还可以使用以下命令将其转储为十六进制格式:

dump ihex memory result.bin 0x200000000 0x20000c350

使用dump命令比使用gdb日志记录hack(这在某种程度上对我来说都不起作用)要清楚得多。

您可以编写简单的lkm来实现这一点

lkm:
#include <linux/kernel.h>
#include <linux/module.h>

int  *ptr=(int*)0Xc18251c0; //the address you want to read from kernel space
int module_i(void)
{
 printk("%d\n",*ptr);
}
module_init(module_i);

gdb中还有一个专用的dump命令。另请参见:您只需使用/dev/kmem或/proc/kcore即可。此外,这并不能回答这个问题。