我写了一个 Action ,当任何objc方法返回(objc::: return)时都会触发。
现在,我需要获取返回值。可能吗?
最佳答案
总结:不,您无法在DTrace探针中获得Objective-C方法的返回值。
Bill Bumgarner有一个post on tracing messages to nil,其中他说:
该博客文章比较老(2008年1月),它使用pid提供程序,而不是objc提供程序。也就是说,它自Mac OS X v10.7.1起仍然有效,并且也适用于objc提供程序。
有趣的是,它有时似乎可以工作,但这取决于DTrace何时读取RAX寄存器。由于objc_msgSend()
不返回,因此DTrace最终使用了RAX中已由代码存储的值,这些值不一定是所跟踪方法的返回。
考虑以下代码:
NSNumber *n = [NSNumber numberWithInt:1234];
printf("n has address %p\n", n);
和以下探针:
objc$target:NSPlaceholderNumber:-initWithInt?:return
{
printf("Returning from -[NSPlaceholderNumber initWithInt:]\n");
printf("\treturn value = 0x%p\n", (void *)arg1);
}
使用DTrace运行时,得到以下输出:
n has address 0x4d283
Returning from -[NSPlaceholderNumber initWithInt:]
return value = 0x4d283
因此,该探针似乎能够捕获
-initWithInt:
的返回值。不过,这只是运气,可能是由CFNumberCreate()
调用的函数(例如CFMakeCollectable()
或-initWithInt:
)引起的,最终将期望值放入RAX中。现在考虑以下代码:
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);
和以下探针:
objc$target:NSPlaceholderString:-initWithData?encoding?:return
{
printf("Returning from -[NSPlaceholderString initWithData:encoding:]\n");
printf("\treturn value = 0x%p\n", (void *)arg1);
}
使用DTrace运行时,得到以下输出:
s has address 0x7fcd92414ea0
Returning from -[NSPlaceholderString initWithData:encoding:]
return value = 0x600
如您所见,地址(即返回值)不匹配。实际上,0x600是
kCFStringEncodingASCII
的值,它是NSASCIIStringEncoding
的Core Foundation对应项。在某个时候,方法或方法调用的函数将0x600移到了RAX上,这就是DTrace错误地认为它是返回值。关于objective-c - 是否有可能在dtrace中获得objc方法的结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7047097/