My program:
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); }
Some output:
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
Why mistakes? This seems to be the name of the class (the only one %s, and I don't get any errors if I delete it), but why does it consider that the names of some classes are invalid pointers?
%s
Is there a way to get error messages to really tell which line of my DTrace program caused the problem?
Is there a way to invoke, object_getClassNameinstead of doing this dance with structure control?
object_getClassName
For what it's worth, the program I'm tracking works fine - it doesn't crash, so I don't think the classes are really broken.
.
:
http://www.friday.com/bbum/2008/01/03/objective-c-using-dtrace-to-trace-messages-to-nil/
, DYLD_SHARED_REGION avoid. dtrace , .
DYLD_SHARED_REGION
avoid
, vmmap.
vmmap
vmmap PID . , , , 0x90206b98. , , , , , , , , dtrace .
vmmap PID
0x90206b98
, copyin/copyinstr , . , , , copyin [str] a: 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); }
. , DTrace Objective-C. DTrace - , Objective-C . Objective-C .. DTrace , , . , objc - objc, DTrace ( , ), ..
, .
DTrace , DTrace . if, , ( -, DTrace) .. , DTrace script , . , , DTrace " " ( , ), - , DTrace, , , , .
if
, , , , , , VM. DTrace , , - , VM .
, , , , , , , NSLog(), - .