我写了一个 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/

10-15 06:57