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

178 Views Asked by At

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?

2

There are 2 best solutions below

0
ahl On BEST ANSWER

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.

3
Andrew Henle On

Per the 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.

Note the use of args[0] and args[1] instead of args0 and args1. That might be significant to your dTrace implementation.