当我在 MacOS 中跟踪 "malloc:return" 时,DTrace 报告不正确的值

DTrace report uncorrect value when I tracing "malloc:return" in MacOS

我想得到malloc的return值,我的DTrace命令是:

sudo dtrace -n 'pid32519::malloc:return {printf("%p %p %p %p %p %p %p %p %p %p %s\n",arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,probefunc);}'

provider的pid是一个小程序如下:

printf("%d\n",getpid());
getchar();
int cnt=50;
void* a = malloc(1000);
printf("%llx\n",a);
a = malloc(1000);
printf("%llx\n",a);
a = malloc(1000);
printf("%llx\n",a);
a = malloc(1000);
printf("%llx\n",a);
getchar();
return 0;

我发现一些文档说“arg1 持有 return 值”,但结果是:

CPU     ID                    FUNCTION:NAME
  8  10499                    malloc:return f a 1 0 0 0 0 0 0 60000000a malloc

  8  10499                    malloc:return f f 1 0 0 0 0 0 f00000000 60000000a malloc

  8  10499                    malloc:return f 10 1 0 0 0 0 0 f00000010 60000000a malloc

  8  10499                    malloc:return f 10 1 0 0 0 0 1000000000 f00000010 60000000a malloc

有 none 个 args 等于 return 的 malloc 值,它在哪里?

根据 DTrace Guide, FBT provider:

20.2.2. return probes

While a given function only has a single point of entry, it may have many different points where it returns to its caller. You are usually interested in either the value that a function returned or the fact that the function returned at all rather than the specific return path taken. FBT therefore collects a function's multiple return sites into a single return probe. If the exact return path is of interest, you can examine the return probe args[0] value, which indicates the offset (in bytes) of the returning instruction in the function text.

If the function has a return value, the return value is stored in args[1]. If a function does not have a return value, args[1] is not defined.

请注意使用 args[0]args[1] 而不是 args0args1。这可能对您的 dTrace 实施很重要。

pid 提供程序 return 探测器的

arg0 包含特定 return 站点函数的偏移量;在这种情况下 0xf。 return 值是可疑的,这表明 malloc 正在制作一个“tail-call”(调用函数的快捷方式,其值将由调用函数 returned并允许省略堆栈帧)。我们可以在反汇编输出中看到这一点:

libsystem_malloc.dylib`malloc:
0x7ff80c57f4d0 <+0>:  movq   %rdi, %rsi
0x7ff80c57f4d3 <+3>:  leaq   0x41a25b26(%rip), %rdi    ; virtual_default_zone
0x7ff80c57f4da <+10>: movl   [=10=]x1, %edx
0x7ff80c57f4df <+15>: jmp    0x7ff800152a59            ; _malloc_zone_malloc

检测 pid$target::_malloc_zone_malloc:return 似乎会产生合理的 return 值。

FWIW 这种行为绝对令人困惑;在 DTrace 的开发过程中,我们考虑过让 tail-call return 有一个特殊的名称,但由于 more 令人困惑而放弃了它。