Насколько я знаю, для такого рода вещей нет встроенной поддержки. Обычно библиотека публикует зонд, который декодирует строку для вас (как упоминает Брэд). Так как в вашем случае вы не можете изменить библиотеку, вам нужно будет использовать провайдера 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, и он отлично работает.