Насколько я знаю, нет встроенной поддержки такого рода вещей. Обычно библиотека будет публиковать пробник, который декодирует строку для вас (как упоминает Брэд). Так как в вашем случае вы не можете изменить библиотеку, вам нужно будет использовать провайдера pid
и подключиться к пользовательской функции и самостоятельно декодировать ее.
Решение (которое очень похоже на подход, который вы использовали бы на C++ для дампа std::string
), заключается в том, чтобы выгрузить указатель, который хранится со смещением на два слова от указателя базы 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
Просто unco mment right typedef
в зависимости от того, работаете ли вы с 32-битным или 64-битным двоичным кодом. Я тестировал это на обеих архитектурах на 10.6, и он отлично работает.
Используя эту программу и этот файл зонда, я просто получаю большой список: dtrace: ошибка на включенном зонде ID 1 (ID 93815: pid11402: sc: mungeString: entry): недействительный адрес (0x7c8) в действии # 5 на DIF смещение 12 Вывод из линии, которая печатает строку, я видеть, что весь строковый addrs является немного необычной: Вызывается mungeString: arg0 = 0x100001068 строки адр = 7c8 добавления второго, другой постоянной строки и mungeString'ing его, я получаю тот же string addr для обеих строк. – TALlama
Хорошо, я могу сказать по адресам памяти, что вы должны использовать 10.6 и создавать 64-битное приложение. Я написал тестовое приложение (в спешке!) На 10,5, поскольку в то время у меня был доступ. Я должен был бы использовать sizeof (intptr_t) для смещения в сценарии DTrace, чтобы быть нейтральным с духом (а не с жестким кодом 8, который теперь будет 16 в 64-битном приложении). Я посмотрю на машину 10.6. – gavinb
@TALlama Попробуйте обновленный сценарий выше. Я тестировал его как в 32-битных, так и в 64-битных двоичных файлах, и он отлично работает. – gavinb