Is it possible to get the result of the objc method in dtrace?

I wrote an action that fires when any objc (objc: return) method returns. At the moment, I need to get the return value. Is it possible?

+7
source share
1 answer

In conclusion: no, you cannot get the return value of the Objective-C method in the DTrace probe.

Bill Bumgarner has a message about tracing messages to zero , in which he says the following:

Also: objc_msgSend() return cannot be tracked through dtrace at this time. Not surprisingly, the function does not really return - as far as dtrace is concerned, it is nothing but a preamble.

The blog post is quite old (January 2008), and it uses the pid provider, not the objc provider. However, it still works with Mac OS X v10.7.1, and it also applies to the objc provider.

Amazingly, it may seem like this sometimes works, but it depends on when DTrace reads the RAX register. Because objc_msgSend() not returned, DTrace ends up using values ​​in RAX that were stored by code, which is not necessarily a return of the tracked method.

Consider the following code:

 NSNumber *n = [NSNumber numberWithInt:1234]; printf("n has address %p\n", n); 

and the following probe:

 objc$target:NSPlaceholderNumber:-initWithInt?:return { printf("Returning from -[NSPlaceholderNumber initWithInt:]\n"); printf("\treturn value = 0x%p\n", (void *)arg1); } 

When starting using DTrace, I get the following output:

 n has address 0x4d283 Returning from -[NSPlaceholderNumber initWithInt:] return value = 0x4d283 

therefore, it seems that the probe was able to capture the return value of -initWithInt: This is only luck, probably caused by a function (e.g. CFNumberCreate() or CFMakeCollectable() ) called by -initWithInt: and which put the expected value in RAX.

Now consider the following code:

 char *c = "hello"; NSData *data = [NSData dataWithBytes:c length:strlen(c)]; NSString *s = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; printf("s has address %p\n", s); 

and the following probe:

 objc$target:NSPlaceholderString:-initWithData?encoding?:return { printf("Returning from -[NSPlaceholderString initWithData:encoding:]\n"); printf("\treturn value = 0x%p\n", (void *)arg1); } 

When starting using DTrace, I get the following output:

 s has address 0x7fcd92414ea0 Returning from -[NSPlaceholderString initWithData:encoding:] return value = 0x600 

As you can see, the addresses (i.e. return values) do not match. In fact, 0x600 is the value of kCFStringEncodingASCII , which is the equivalent of Core Foundation from NSASCIIStringEncoding . At some point, either the method or the function called by the method moved 0x600 to RAX and this is the value that DTrace mistakenly considers the return value.

+5
source

All Articles