Reputation: 8722
This question is asking the same thing, but when I tried:
typedef long long ptr_t;
objc$target:NSWindow:-setTitle?:entry
{
printf( "%30s %10s %x %x %x\n", probemod, probefunc, arg0, arg1, arg2 );
this->str = *(ptr_t*)copyin(arg2+2*sizeof(ptr_t), sizeof(ptr_t));
printf("string addr = %p\n", this->str);
printf("string val = %s\n", copyinstr(this->str));
}
It didn't work. arg2 should be the address of the NSString. I got:
NSWindow -setTitle: 100685240 7fff92d82f73 7fff78a6eb80 string addr = 7fff8e7e83b9 string val=Window dtrace: error on enabled probe ID 5 (ID 35737: objc9434:NSWindow:-setTitle::entry): invalid address (0x6c007400690074) in action #8 at DIF offset 24
You can assuming a MacRoman or ASCII encoding of the NSString - basically no need to worry about complicated (from the DTrace perspective) encodings.
Upvotes: 1
Views: 661
Reputation: 1562
Whether or not your question really is the same as the other one depends on whether or not the internal representation of an NSString is the same as that of a CFStringRef. I don't know, and I hope that someone else can clarify, but I suspect that the answer is that the two are different. The D script in the other question's answer implies that a CFStringRef has a character pointer, but playing around with gdb suggests that an NSString looks like this:
struct NSString { uintptr_t pad[2]; char name[1]; /* variable length array */ };
Here's a corresponding script in action:
bash-3.2# cat title.d typedef struct { uintptr_t pad[2]; char name[1]; } NSString_t; objc$target:NSWindow:-setTitle?:entry { self->namep = (uintptr_t)arg2 + offsetof(NSString_t, name); printf("name = %s\n", copyinstr(self->namep)); } bash-3.2# ps -ef | fgrep -i firefox 501 31895 204 0 0:01.22 ?? 0:04.48 /opt/Applications/Firefox.app/Contents/MacOS/firefox -psn_0_27167207 0 32045 31422 0 0:00.05 ttys000 0:00.06 fgrep -i firefox bash-3.2# dtrace -arch x86_64 -Cqs title.d -p 31895 name = Mozilla Firefox name = New Tab name = New Tab name = Mozilla Firefox name = New Tab ^C bash-3.2#
If you're inspecting a 32-bit process then use -arch i386
and dtrace(1) will adjust its notion of pointer sizes appropriately.
Upvotes: 2