Search code examples
cheap-memorydtrace

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


I want to get the return value of malloc, my DTrace command is:

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);}'

and the pid of provider is a tiny program as follow:

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;

I found some documentation that say "arg1 holds return value", but the result is:

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

There is none of args equaled the return value of malloc and where is it?


Solution

  • arg0 of the pid provider return probe contains the offset into the function of the particular return site; in this case 0xf. The return values are suspicious which suggests that malloc is making a "tail-call" (a shortcut by which a function is called whose value will be returned by the calling function and allows a stack frame to be elided). We can see this in the disassembly output:

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

    Instrumenting pid$target::_malloc_zone_malloc:return instead seems to produce reasonable return values.

    FWIW this behavior is definitely confusing; during the development of DTrace we considered having tail-call returns have a special name, but discarded that as being more confusing.