代码之家  ›  专栏  ›  技术社区  ›  TALlama numbers1311407

如何在DTrace操作中打印CFStringRef?

  •  8
  • TALlama numbers1311407  · 技术社区  · 16 年前

    CFStringRef CFStringRef char* ,所以正常的DTrace方法如下 copyinstr() ?cp?

    那么,我如何在DTrace操作中打印出字符串呢?

    2 回复  |  直到 16 年前
        1
  •  12
  •   gavinb    16 年前

    据我所知,这种东西没有内置支持。通常,库会发布一个探测器,为您解码字符串(正如Brad所提到的)。因此,由于在您的情况下无法修改库,您需要使用 pid 提供程序并连接到用户函数,然后自己解码。

    解决方案(与您在C++中使用的转储方法非常相似) std::string )是转储存储在距基偏移2个字处的指针 CFStringRef CFString 可以在内部以各种格式和表示形式存储字符串,这可能会发生变化。

    考虑到简单的测试应用程序:

    #include <CoreFoundation/CoreFoundation.h>
    
    int mungeString(CFStringRef someString)
    {
        const char* str = CFStringGetCStringPtr(someString, kCFStringEncodingMacRoman);
        if (str)
            return strlen(str);
        else
            return 0;
    }
    
    int main(int argc, char* argv[])
    {
        CFStringRef data = CFSTR("My test data");
    
        printf("%u\n", mungeString(data));
    
        return 0;
    }
    

    dtrace CFStringRef :

    #!/usr/sbin/dtrace -s
    
    /*
        Dumps a CFStringRef parameter to a function,
        assuming MacRoman or ASCII encoding.
        The C-style string is found at an offset of
        2 words past the CFStringRef pointer.
        This appears to work in 10.6 in 32- and 64-bit
        binaries, but is an implementation detail that
        is subject to change.
    
        Written by Gavin Baker <gavinb.antonym.org>
    */
    
    #pragma D option quiet
    
    /* Uncomment for LP32 */
    /* typedef long ptr_t; */
    /* Uncomment for LP64 */
    typedef long long ptr_t;
    
    pid$target::mungeString:entry
    {
        printf("Called mungeString:\n");
        printf("arg0 = 0x%p\n",arg0);
    
        this->str = *(ptr_t*)copyin(arg0+2*sizeof(ptr_t), sizeof(ptr_t));
        printf("string addr = %p\n", this->str);
        printf("string val  = %s\n", copyinstr(this->str));
    
    }
    

    $ sudo dtrace -s dump.d -c ./build/Debug/dtcftest 
    12
    Called mungeString:
    arg0 = 0x2030
    string addr = 1fef
    string val  = My test data
    

    只需取消对权利的注释 typedef 这取决于您是针对32位还是64位二进制文件运行。我在10.6上对这两种架构进行了测试,它运行良好。

        2
  •  1
  •   Brad Larson    16 年前

    我相信你不能直接做到这一点,但你可以创建一个自定义的静态探测,将CFString/NSString作为char*输入,你可以将其与copyinstr()一起使用。我在一篇文章中描述了如何做到这一点 here .

    推荐文章