【问题标题】:Is it possible to get the result of objc method in dtrace?是否可以在 dtrace 中获取 objc 方法的结果?
【发布时间】:2011-08-12 22:44:36
【问题描述】:

我写了一个动作,当任何 objc 方法返回时触发 (objc:::return)。 现在,我需要获取返回值。有可能吗?

【问题讨论】:

    标签: objective-c dtrace


    【解决方案1】:

    总而言之:不,您无法在 DTrace 探针中获取 Objective-C 方法的返回值。

    Bill Bumgarner 有一个post on tracing messages to nil,他在其中说:

    除此之外:objc_msgSend() 的返回目前无法通过 dtrace 进行跟踪。鉴于该函数实际上并没有返回,这并不奇怪 — 就 dtrace 而言,它只不过是序言。

    这篇博文相当陈旧(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: 的返回值。不过这只是运气,可能是由-initWithInt: 调用的函数(例如CFNumberCreate()CFMakeCollectable())引起的,最终将预期值放入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 的核心基础对应物。在某些时候,方法或方法调用的函数将 0x600 移动到 RAX,这是 DTrace 错误地 认为是返回值的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-06
      • 1970-01-01
      • 1970-01-01
      • 2017-09-29
      • 2022-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多