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

如何在dtrace操作中打印cfStringRef?

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

    我有一个dtrace探针捕捉对函数的调用,函数的参数之一是 CFStringRef . 这是一个私有结构,包含指向Unicode字符串的指针。但是 CFSTRIGRIEF 本身不是 char* ,所以普通的dtrace方法 copyinstr() 就回来 ?cp? 这并没有什么帮助。

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

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

    据我所知,这种东西没有内置的支持。通常,一个库会发布一个为您解码字符串的探针(正如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 脚本将打印第一个参数的字符串值,假定它是 CFSTRIGRIEF 以下内容:

    #!/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    15 年前

    我相信您不能直接这样做,但是您可以创建一个定制的静态探针,它以char*形式馈送cfstring/nsstring,您可以使用copyinstr()。我在一篇文章中描述了如何做到这一点 here .

    推荐文章