如何使用 Dtrace 在 Solaris 10 上检查 malloc?
Posted
技术标签:
【中文标题】如何使用 Dtrace 在 Solaris 10 上检查 malloc?【英文标题】:how to use Dtrace to check malloc on Solaris 10? 【发布时间】:2013-12-13 05:58:32 【问题描述】:我遇到一个关于内存使用的麻烦错误,所以我想在 Solaris 10 上使用 Dtrace 来检查 malloc 和 free。
我使用以下命令
dtrace -l | grep malloc
输出是:
7000 fbt unix prom_malloc entry
7001 fbt unix prom_malloc return
7141 fbt genunix cacl_malloc entry
7142 fbt genunix cacl_malloc return
12319 fbt genunix rmallocmap_wait entry
12320 fbt genunix rmallocmap_wait return
13078 fbt genunix rmalloc_wait entry
13079 fbt genunix rmalloc_wait return
13526 fbt genunix rmallocmap entry
13527 fbt genunix rmallocmap return
16846 fbt genunix rmalloc entry
16847 fbt genunix rmalloc return
25931 fbt tmpfs tmp_memalloc entry
25932 fbt tmpfs tmp_memalloc return
好像没有malloc。
我检查了 Solaris 内部,发现 malloc 调用 sbrk。所以我使用以下命令:
dtrace -l | grep sbrk
但是什么也没找到。
那么
【问题讨论】:
我猜这个工具对你有用:theunixshell.blogspot.com/2013/11/… @Vijay:非常感谢您的 cmets,它是一个非常酷的工具! @Vijay:你愿意打开你工具的源代码吗? 给我发邮件 bvsarathi@gmail.com 或用您的电子邮件在博客上发表评论 【参考方案1】:已经有各种工具实现了在 Solaris 下识别内存泄漏所需的逻辑,
libumem & mdb (UMEM_DEBUG=default UMEM_LOGGING=transaction LD_PRELOAD=libumem.so.1
然后mdb's ::findleaks
)
dbx (check -leaks
)
如果您仍想采用dtrace
方式,您需要使用 pid 提供程序跟踪您怀疑泄漏内存的进程。您使用dtrace -l
搜索了内核探测器,但什么也没找到,但这是预期的,因为内核没有实现malloc
或brk
。它们是位于 C 标准库中的用户态函数。
此脚本将跟踪程序的每个 malloc
和 free
调用:
dtrace -qn '
pid$target:libc:malloc:entry
self->size=arg0;
pid$target:libc:malloc:return /self->size/
printf("malloc(%d)=%p\n",self->size,arg1);
self->size=0;
pid$target:libc:free:entry
printf("free(%p)\n",arg0);
' -c program_to_trace
如需更深入的示例,请查看http://ewaldertl.blogspot.fr/2010/09/debugging-memory-leaks-with-dtrace-and.html 和http://www.joyent.com/blog/bruning-questions-debugging
【讨论】:
您介意解释一下为什么返回指针在 arg1 而不是 arg0 中吗?我在 dtrace 上很绿色,但对于syscall::open:return
之类的东西,文件描述符位于 arg0
@genghiskhan 这是设计使然。我正在使用 pid 提供程序,它的行为与您所指的系统调用提供程序不同。使用 pid 提供程序 A return probe fires when the traced function returns or makes a tail call to another function. The value for arg0 is the offset in the function of the return instruction; arg1 holds the return value.。请注意,对于系统调用提供程序,返回值在 arg0 和 arg1 中。
太棒了。感谢您的精彩解释。【参考方案2】:
例如,为了使用 dtrace 跟踪所有 malloc 调用,通过打印每个分配,您将编写(在本例中为名为 trace-malloc.d 的文件)如下脚本:
#!/usr/sbin/dtrace -s
pid$1::malloc:entry
self->trace = 1;
self->size = arg0;
pid$1::malloc:return
/self->trace == 1/
/* log the memory allocation */
printf("<__%i;%Y;%d;malloc;0x%x;%d;\n", i++, walltimestamp, tid, arg1, self->size);
ustack(50);
printf("__>\n\n");
self->trace = 0;
self->size = 0;
然后通过传递您要跟踪的进程的进程ID来调用它, 例如:
./trace-malloc.d 12345
在复杂的程序中,内存分配和取消分配非常频繁,因此我编写了一个小程序来帮助我使用 dtrace 识别内存泄漏。跟踪 malloc / calloc / realloc 和 free 的每个内存操作,然后分析程序读取并处理所有跟踪并指出可疑的内存泄漏,还使用各种启发式方法指出强烈怀疑的内存泄漏。有兴趣的可以看这里:
https://github.com/ppissias/DTLeakAnalyzer.
【讨论】:
仅仅链接到您自己的库或教程并不是一个好的答案。链接到它,解释它解决问题的原因,提供如何解决问题的代码/过程,并否认你编写了它,这样可以得到更好的答案。见:What signifies “Good” self promotion? @Shree 帖子以“我已经写过”开头。那么,这不是一个明确的声明是谁编写了这个工具吗? @AdrianW 我总是想象没有链接的答案。如果没有链接,它的地址是一个问题,链接仅供参考,我没有标记答案。 您好,感谢您对回复的反馈,我已相应地对其进行了更改,以包括对问题的回答。目的是帮助遇到同样问题的其他人,因为不久前我还在使用 dtrace 搜索可用工具。以上是关于如何使用 Dtrace 在 Solaris 10 上检查 malloc?的主要内容,如果未能解决你的问题,请参考以下文章
哪些 DTrace 脚本值得在 Solaris 上测试和分析 Java 程序
Oracle Solaris 上的 dtrace java API?