使用DTrace记录发送到剥离类的所有消息

时间:2014-06-15 14:44:01

标签: objective-c dtrace

使用DTrace记录发送到班级的所有邮件通常很容易,例如使用here中的trace_msg_send.sh脚本:

#!/usr/sbin/dtrace -s
#pragma D option quiet

unsigned long long indention;
int indentation_amount;

BEGIN {
  indentation_amount = 4;
}

objc$target:$1::entry
{
    method = (string)&probefunc[1];
    type = probefunc[0];
    class = probemod;
    printf("%*s%s %c[%s %s]\n", indention * indentation_amount, "", "->", type, class, method);
    indention++;
}
objc$target:$1::return
{
    indention--;
    method = (string)&probefunc[1];
    type = probefunc[0];
    class = probemod;
    printf("%*s%s %c[%s %s]\n", indention * indentation_amount, "", "<-", type, class, method);
}

鉴于代码:

$ cat > test.m
#include <stdio.h>
#import <Foundation/Foundation.h>

@interface TestClass : NSObject

+ (int)randomNum;

@end

@implementation TestClass

+ (int)randomNum {
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

@end

int main(void) {
    printf("num: %d\n", [TestClass randomNum]);
    return 0;
}
^D

您将使用DTrace脚本获得以下输出:

$ gcc test.m -lobjc -o test
$ ./test
num: 4
$ sudo ./trace_msg_send.d -c ./test TestClass
num: 4
-> +[TestClass randomNum]
<- +[TestClass randomNum]

但是如果我们剥离二进制文件:

$ strip test
$ sudo ./trace_msg_send.d -c ./test TestClass
dtrace: failed to compile script ./trace_msg_send.d: line 11: probe description objc49043:TestClass::entry does not match any probes

脚本不再有效。

有没有办法告诉DTrace,剥离的类/消息实现位于何处?

也许使用class-dump提供的信息,就像Import class-dump info into GDB的答案一样。


我创建了一个脚本,试图在运行时比较类名,但它似乎不起作用:

#!/usr/sbin/dtrace -s
#pragma D option quiet

unsigned long long indention;
int indentation_amount;

BEGIN {
  indentation_amount = 4;
}

objc$target:::entry
{
    // Assumes 64 bit executable
    isaptr = *(uint64_t *)copyin(arg0, 8);
    class_rw = *(uint64_t *)copyin(isaptr + 4*8, 8);
    class_ro = *(uint64_t *)copyin(class_rw + 8, 8);
    classnameptr = *(uint64_t *)copyin(class_ro + 4*4 + 8, 8);
    classname = copyinstr(classnameptr);

    type = classname == $$1? (string)&probefunc[0]: "";
    method = classname == $$1? (string)&probefunc[1]: "";

    arrow = classname == $$1? "->": "";
    space = classname == $$1? " ": "";
    bracket1 = classname == $$1? "[": "";
    bracket2 = classname == $$1? "]": "";
    current_indention = classname == $$1? indention: 0;
    indention = classname == $$1? indention + 1: indention;

    newline = classname == $$1? "\n": "";

    classname = classname == $$1? classname: "";

    printf("%*s%s%s%.1s%s%s%s%s%s%s", current_indention * indentation_amount, "", arrow, space, type, bracket1, classname, space, method, bracket2, newline);
}

运行sudo ./trace_msg_send2.d -c ./test TestClass打印:

num: 4
dtrace: error on enabled probe ID 179 (ID 13922: objc3517:NSObject:+load:entry): invalid address (0x7fff8204e03e) in action #5 at DIF offset 12
dtrace: error on enabled probe ID 186 (ID 13915: objc3517:__IncompleteProtocol:+load:entry): invalid address (0x7fff8204e01f) in action #5 at DIF offset 12
dtrace: error on enabled probe ID 195 (ID 13906: objc3517:Protocol:+load:entry): invalid address (0x7fff8204e034) in action #5 at DIF offset 12
-> +[TestClass initialize]

缺少-> -[TestClass randomNum:]

0 个答案:

没有答案