当我在 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]
而不是 args0
和 args1
。这可能对您的 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 令人困惑而放弃了它。
我想得到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]
而不是 args0
和 args1
。这可能对您的 dTrace 实施很重要。
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 令人困惑而放弃了它。