我有一个DTrace探针捕获函数的调用,函数的一个参数是a CFStringRef
.这是一个私有结构,它包含一个指向unicode字符串的指针.但CFStringRef
它本身并不是一个char*
普通的DTrace方法,就像copyinstr()
返回一样?cp?
,这并不是很有用.
那么如何在DTrace动作中打印出字符串呢?
gav*_*inb 12
据我所知,这种东西没有内置的支持.通常,库会发布一个为您解码字符串的探测器(如Brad所述).因此,在您的情况下,您无法修改库,您需要使用pid
提供程序并挂钩到用户函数,并自行解码.
解决方案(与您在C++中用于转储的方法非常相似std::string
)是转储指针,该指针存储在距离基CFStringRef
指针2个字偏移处.请注意,由于a 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;
}
Run Code Online (Sandbox Code Playgroud)
以下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));
}
Run Code Online (Sandbox Code Playgroud)
输出将是这样的:
$ sudo dtrace -s dump.d -c ./build/Debug/dtcftest
12
Called mungeString:
arg0 = 0x2030
string addr = 1fef
string val = My test data
Run Code Online (Sandbox Code Playgroud)
typedef
根据您是针对32位还是64位二进制文件运行,只需取消注释即可.我已经在10.6上对这两种体系结构进行了测试,它运行良好.