Why does DTrace give me invalid-address errors som

2019-06-27 01:48发布

我的程序:

typedef struct objc_class {
    struct objc_class *isa;
    struct objc_class *super_class;
    char *name;
    long version;
    long info;
    long instance_size;
    void *ivars;
    void *methodLists;
    void *cache;
    void *protocols;
} *Class;
struct objc_object {
    Class isa;
};

/* Code to extract the class name from arg0 based on a snippet by Bill Bumgarner: http://friday.com/bbum/2008/01/26/objective-c-printing-class-name-from-dtrace/ */

objc$target:NSObject:-init:entry {
    printf("time: %llu\n", timestamp);
    printf("arg0: %p\n", arg0);
    obj = (struct objc_object *)copyin(arg0, sizeof(struct objc_object));
    printf("obj: %p\n", obj);
    printf("obj->isa: %p\n", obj->isa);
    isa = (Class)copyin((user_addr_t)obj->isa, sizeof(struct objc_class));
    printf("isa: %p\n", obj->isa);
    classname = copyinstr((user_addr_t)(isa->name));
    printf("classname: %s\n", classname);
}

一些输出:

dtrace: script 'test.d' matched 1 probe
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
CPU     ID                    FUNCTION:NAME
  0  61630                      -init:entry time: 28391086668386
arg0: 1291ae10
obj: 6f0a1158
obj->isa: a023f360
isa: a023f360
classname: NSBitmapImageRep

  1  61630                      -init:entry time: 28391586872297
arg0: 12943560
obj: 6f4a1158
obj->isa: 2fca0
isa: 2fca0
classname: GrowlApplicationTicket

  1  61630                      -init:entry time: 28391586897807
arg0: 152060
obj: 6f4a1280
obj->isa: 2fe20
isa: 2fe20
classname: GrowlNotificationTicket

  2  61630                      -init:entry time: 28391079142905
arg0: 129482d0
obj: 700a1128
obj->isa: a0014140
isa: a0014140
classname: NSDistributedObjectsStatistics

  2  61630                      -init:entry time: 28391079252640
arg0: 147840
obj: 700a1250
obj->isa: a0014780
isa: a0014780
classname: NSDistantObjectTableEntry

为什么错误? 这似乎是在类名(这是唯一%s ,如果我删除它,我没有得到任何错误),但为什么它认为一些类的名字是无效的指针?

有没有什么办法让错误信息实际上告诉我,这我的DTrace程序的线产生的问题?

有没有一种方法来调用object_getClassName而不是做这种结构检查的舞蹈?

对于它的价值,我的作品的跟踪程序精细它没有崩溃,所以我不相信真班被打破。

Answer 1:

科林是非常接近正确。

看到:

http://www.friday.com/bbum/2008/01/03/objective-c-using-dtrace-to-trace-messages-to-nil/

更可能的情况是,你需要设置DYLD_SHARED_REGION环境变量来avoid 。 DTrace的唯一真正有效打击映射内存,实际上是驻留在物理内存。

你可以弄清楚什么是使用丢失vmmap命令行工具。

vmmap PID您的应用程序产生上述故障的消息后。 纵观输出,看看有什么样的区域地址0x90206b98掉进去。 鉴于该地址,则很有可能中的内存不可写的共享存储块,它可能不是居民,因此,DTrace的不能从中读取。



Answer 2:

当COPYIN / copyinstr的是,不是在故障尚未页面上使用了发生此错误。 一个常见的解决方法是让功能有关使用该数据,然后COPYIN [STR]在一个::: return子句。 例如:

syscall::open:entry
{
    self->filename = arg0;  /* Hang on to the file name pointer.  */
}

syscall::open:return
/self->filename/
{
    @files[copyinstr(self->filename)] = count();
    self->filename = 0;
}

END
{
    trunc(@files, 5);
}


Answer 3:

我还没有完全跟踪下来自己。 这有可能是DTrace是试图解决一些Objective-C的符号。 虽然DTrace是一种动态跟踪工具不与Objective-C的在运行时动态加载的东西好网。 当Objective-C的不加载新类等的DTrace必须解决这一点,它需要一点时间,尤其是当你的应用刚刚起步。 即使它得到的东西加载,你objc应用程序仍在加载新的类到objc运行时其可能的DTrace可以得到搞砸了,并在错误的顺序打印方法(如果你在乎看到正确的顺序方法正在执行中) ,打印不正确定时的结果,等等。



Answer 4:

这是根据所提供的信息,我最好的猜测。

DTrace的是故意设计成这样一种方式,使DTrace的脚本确定性越好。 这就是为什么有没有if语句,循环,子程序等,这是因为在你的DTrace脚本代码在内核模式下运行,用户无法土地的一部分(不是通过自身的DTrace提供的伪子程序等)过程(ES)被跟踪。 在一般情况下,信息的DTrace访问是“只读”(最喜欢的概括,这是不完全正确),能摆弄的程序位,或内核,以作为DTrace的强大的东西可能会导致事情去非常,非常错误的,非常非常快。

美元甜甜圈,您遇到的问题,是因为要在核心由VM系统没有映射指针所指向的页面。 唯一的DTrace可以检查是核心 - 它不能双误让VM系统在页面加载内存信息。

你也许可以帮助缓解这个问题,如果你有什么样的阶级“应该”,并迫使页在核心做了一堆假的NSLog()的,在一些方便的引用所需的类语句被映射的想法在程序中启动较早的时间点。



文章来源: Why does DTrace give me invalid-address errors sometimes but not always?