O ile mi wiadomo, nie ma wbudowanej obsługi tego typu rzeczy. Zazwyczaj biblioteka publikuje sondę, która dekoduje ciąg znaków (jak wspomina Brad). Ponieważ w twoim przypadku nie możesz zmodyfikować biblioteki, musisz skorzystać z dostawcy pid
i podłączyć się do funkcji użytkownika i sam ją odkodować.
Rozwiązanie (które jest bardzo podobne do podejścia, którego można użyć w C++ do zrzutu std::string
) jest zrzucenie wskaźnika, który jest przechowywany z przesunięciem 2 słów od wskaźnika bazowego CFStringRef
. Zauważ, że ponieważ CFString
może przechowywać łańcuchy wewnętrznie w różnych formatach i reprezentacjach, może to ulec zmianie.
Biorąc trywialne zastosowanie testu:
#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;
}
Poniższy dtrace
skrypt wypisze wartość ciągu pierwszego argumentu, zakładając, że jest to 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));
}
a wyjście będzie coś na przykład:
$ sudo dtrace -s dump.d -c ./build/Debug/dtcftest
12
Called mungeString:
arg0 = 0x2030
string addr = 1fef
string val = My test data
Simply unco w zależności od tego, czy używasz 32-bitowego, czy 64-bitowego pliku binarnego. Przetestowałem to na obu architekturach na 10.6 i działa dobrze.
Używając tego programu i tego pliku sondy, dostaję dużą listę tego: dtrace: błąd przy włączonym ID sondy 1 (ID 93815: pid11402: sc: mungeString: wpis): nieprawidłowy adres (0x7c8) w akcji # 5 w DIF przesunięcie 12 Zaciągnięcie linię, która drukuje ciąg, widzę, że wszyscy addrs smyczkowe są odrobinę nietypowe: Called mungeString: arg0 = 0x100001068 ciąg addr = 7c8 Dodawanie drugi, inny stały ciąg i mungeString'ing to, otrzymuję ten sam addr string dla obu ciągów. – TALlama
Ok, z adresów pamięci mogę stwierdzić, że musisz używać wersji 10.6 i tworzyć aplikację 64-bitową. Napisałem aplikację testową (w pośpiechu!) Na 10.5, ponieważ było to wszystko, do czego miałem dostęp w tym czasie. Powinienem był użyć sizeof (intptr_t), aby przesunięcie w skrypcie DTrace było neutralne względem łuku (zamiast twardego kodu 8, który miałby teraz 16 w 64-bitowej aplikacji). Przyjrzę się maszynie 10.6. – gavinb
@ TALlama Proszę wypróbować zaktualizowany skrypt powyżej. Przetestowałem to na 32-bitowych i 64-bitowych plikach binarnych i działa dobrze. – gavinb