如何在DTrace操作中打印CFStringRef? [英] How do I print a CFStringRef in a DTrace action?

查看:166
本文介绍了如何在DTrace操作中打印CFStringRef?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个DTrace探针来捕获对函数的调用,该函数的参数之一是CFStringRef.这是一个私有结构,其中包含一个指向unicode字符串的指针.但是CFStringRef本身并不是char*,因此普通的DTrace方法(例如copyinstr())仅返回?cp?,这并不是完全有用.

I have a DTrace probe catching calls to a function, and one of the function's arguments is a CFStringRef. This is private structure that holds a pointer to a unicode string. But the CFStringRef is not itself a char*, so normal DTrace methods like copyinstr() just return ?cp?, which isn't exactly helpful.

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

So how can I print out the string in the DTrace action?

推荐答案

据我所知,这种类型的东西没有内置的支持.通常,一个库会发布一个探针,为您解码字符串(如Brad所述).因此,由于您无法修改该库,因此需要使用pid提供程序并连接到用户函数中,然后自行对其进行解码.

As far as I know, there is not built-in support for this kind of thing. Usually a library would publish a probe that decodes the string for you (as Brad mentions). So since in your case you can't modify the library, you'll need to use the pid provider and hook into a user function, and decode it yourself.

解决方案(与您在C ++中转储std::string所使用的方法非常相似)是转储出指针,该指针与基本CFStringRef指针的偏移量为2个字.请注意,由于CFString可以在内部以各种格式和表示形式存储字符串,因此可能会发生变化.

The solution (which is very similar to the approach you would use in C++ to dump a std::string) is to dump out the pointer which is stored at an 2 word offset from the base CFStringRef pointer. Note that since a CFString can store strings internally in a variety of formats and representations, this is subject to change.

给出简单的测试应用程序:

Given the trivial test application:

#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:

The following dtrace script will print the string value of the first argument, assuming it is a 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

根据在32位还是64位二进制文​​件上运行,只需取消注释正确的typedef.我已经在10.6的两种体系结构上对此进行了测试,并且效果很好.

Simply uncomment the right typedef depending on whether you are running against a 32-bit or 64-bit binary. I have tested this against both architectures on 10.6 and it works fine.

这篇关于如何在DTrace操作中打印CFStringRef?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆