如何从DTrace脚本打印NSString

时间:2013-03-21 02:52:59

标签: cocoa nsstring dtrace

question提出同样的问题,但是当我尝试时:

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));
}

它不起作用。 arg2应该是NSString的地址。我得到了:

  

NSWindow -setTitle:100685240 7fff92d82f73 7fff78a6eb80 string addr = 7fff8e7e83b9 string val = Window   dtrace:启用的探测ID 5上的错误(ID 35737:   objc9434:NSWindow:-setTitle :: entry):地址无效   (0x6c007400690074)在DIF偏移24的行动#8中

您可以假设NSString的MacRoman或ASCII编码 - 基本上不需要担心复杂(从DTrace角度来看)编码。

1 个答案:

答案 0 :(得分:2)

你的问题是否真的与另一个问题相同 一个取决于NSString的内部表示 与CFStringRef的相同。我不知道,我希望 其他人可以澄清,但我怀疑答案是这样的 两者是不同的。另一个问题答案中的D脚本暗示着 一个CFStringRef有一个字符指针,但正在播放 围绕gdb建议NSString看起来像这样:

struct NSString {
    uintptr_t pad[2];
    char name[1];       /* variable length array */
};

这是一个相应的脚本:

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#

如果您正在检查32位进程,请使用-arch i386,dtrace(1)将适当调整其指针大小的概念。