how*_*rks 26 c memory-leaks gdb
有没有办法,我可以找到正在运行的进程的内存泄漏?我可以使用 Valgrind 在进程开始之前查找内存泄漏。我可以使用 GDB 将其附加到正在运行的进程。如何调试正在运行的进程的内存泄漏?
小智 17
我认为memleax正是您想要的。
它通过附加来调试正在运行的进程的内存泄漏,而无需重新编译程序或重新启动目标进程。非常方便,适合生产环境。
它适用于 GNU/Linux 和 FreeBSD。
注意:我是作者,欢迎提出任何建议。
== 编辑 ==
我还编写了另一个工具libleak,它通过 LD_PRELOAD 挂钩内存功能。
无需修改目标程序。虽然您必须使用 LD_PRELOAD 重新启动进度,但您可以在运行期间启用/禁用检测。
由于没有信号陷阱,对性能的影响要小得多。
与类似工具(例如 mtrace)相比,它在可疑内存泄漏点打印完整的调用堆栈。
小智 17
找出导致内存泄漏的进程的PID。
ps -aux
Run Code Online (Sandbox Code Playgroud)捕获/proc/PID/smaps并保存到某个文件中,例如BeforeMemInc.txt.
/proc/PID/smaps并保存afterMemInc.txt找到 firstsmaps和 2nd之间的区别smaps,例如
diff -u beforeMemInc.txt afterMemInc.txt
记下内存增加的地址范围,例如:
beforeMemInc.txt afterMemInc.txt
---------------------------------------------------
2b3289290000-2b3289343000 2b3289290000-2b3289343000 #ADDRESS
Shared_Clean: 0 kB Shared_Clean: 0 kB
Shared_Dirty: 0 kB Shared_Dirty: 0 kB
Private_Clean: 0 kB Private_Clean: 0 kB
Private_Dirty: 28 kB Private_Dirty: 36 kB
Referenced: 28 kB Referenced: 36 kB
Anonymous: 28 kB Anonymous: 36 kB #INCREASE MEM
AnonHugePages: 0 kB AnonHugePages: 0 kB
Swap: 0 kB Swap: 0 kB
KernelPageSize: 4 kB KernelPageSize: 4 kB
MMUPageSize: 4 kB MMUPageSize: 4 kB
Locked: 0 kB Locked: 0 kB
VmFlags: rd wr mr mw me ac VmFlags: rd wr mr mw me ac
Run Code Online (Sandbox Code Playgroud)使用 GDB 转储正在运行的进程的内存或使用获取核心转储 gcore -o process
我在运行过程中使用 gdb 将内存转储到某个文件。
gdb -p PID
dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
Run Code Online (Sandbox Code Playgroud)现在,使用strings命令或hexdump -C打印dump_outputfile.dump
strings outputfile.dump
Run Code Online (Sandbox Code Playgroud)您可以获得可读的形式,您可以在其中将这些字符串定位到您的源代码中。
分析您的来源以查找泄漏。
在 Linux 上,您可以在程序中启用mtrace,但这是代码更改。
在 OpenBSD 上,您可以尝试malloc stats。
Google 的泄漏检查器也可能值得一看,与 mtrace 不同,您可以使用它LD_PRELOAD来避免重新编译。
我认为如果不直接在源代码中程序启动后提供对分配监视的支持,你就不走运了。我能想到的原因有两个:
但是,如果您的程序在虚拟机内运行,则该环境可能会提供对监视分配的支持。我知道 Java 有几个附加到正在运行的程序或 VM 的分配和垃圾收集监视工具(例如VisualVM )。