Hasta donde yo sé, no hay soporte incorporado para este tipo de cosas. Por lo general, una biblioteca publicará una sonda que decodifica la cadena por usted (como lo menciona Brad). Entonces, como en su caso no puede modificar la biblioteca, necesitará usar el proveedor pid
y enganchar en una función de usuario, y decodificarla usted mismo.
La solución (que es muy similar al enfoque que utilizaría en C++ para volcar un std::string
) es volcar el puntero que está almacenado en un desplazamiento de 2 palabras desde el puntero CFStringRef
base. Tenga en cuenta que dado que un CFString
puede almacenar cadenas internamente en una variedad de formatos y representaciones, esto está sujeto a cambios.
Teniendo en cuenta la aplicación de prueba trivial:
#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;
}
El dtrace
siguiente script imprimirá el valor de cadena del primer argumento, si se asume que es una 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));
}
Y la salida será algo como:
$ sudo dtrace -s dump.d -c ./build/Debug/dtcftest
12
Called mungeString:
arg0 = 0x2030
string addr = 1fef
string val = My test data
Simply unco modifique el typedef
derecho dependiendo de si se está ejecutando contra un binario de 32 bits o de 64 bits. He probado esto en ambas arquitecturas en 10.6 y funciona bien.
Usando este programa y este archivo de prueba, acabo de obtener una gran lista de esto: dtrace: error en la sonda ID habilitada 1 (ID 93815: pid11402: sc: mungeString: entrada): dirección no válida (0x7c8) en la acción # 5 en DIF desplazamiento 12 Tomando la línea que imprime la cadena, veo que todos los addrs de cuerdas son un poco inusual: Llamado mungeString: arg0 = 0x100001068 cadena addr = 7C8 Adición de una segunda cadena diferente, constante y mungeString'ing, obtengo el mismo addr de cadena para ambas cadenas. – TALlama
Ok, puedo decir por las direcciones de memoria que debe estar usando 10.6 y compilando una aplicación de 64 bits. Escribí la aplicación de prueba (¡con prisa!) En 10.5 ya que era todo lo que tenía acceso en ese momento. Debería haber usado sizeof (intptr_t) para que el desplazamiento en el script DTrace sea archi neutral (en lugar de hardcode 8, que ahora sería 16 en una aplicación de 64 bits). Echaré un vistazo a una máquina 10.6. – gavinb
@TALlama Por favor intente el script actualizado arriba. Lo probé en binarios de 32 bits y de 64 bits y funciona bien. – gavinb