dtrace 동작에서 cfstringref를 어떻게 인쇄합니까?
문제
기능에 대한 dtrace 프로브를 잡는 DTRACE를 가지고 있으며 함수의 인수 중 하나는 CFStringRef
. 이것은 유니 코드 문자열에 대한 포인터를 보유하는 개인 구조입니다. 하지만 CFStringRef
그 자체가 아닙니다 char*
, 정상적인 dtrace 방법과 같은 방법 copyinstr()
그냥 돌아 오세요 ?cp?
, 정확히 도움이되지 않습니다.
그렇다면 dtrace 동작에서 문자열을 어떻게 인쇄 할 수 있습니까?
해결책
내가 아는 한, 이런 종류의 일에 대한 내장 지원은 없습니다. 일반적으로 라이브러리는 브래드가 언급 한 것처럼 문자열을 디코딩하는 프로브를 게시합니다. 따라서 귀하의 경우 라이브러리를 수정할 수 없으므로 사용해야합니다. pid
제공자와 사용자 기능에 연결하여 직접 해독하십시오.
솔루션 (C ++에서 사용하는 접근 방식과 매우 유사합니다. std::string
)은베이스에서 2 개의 단어 오프셋에 저장된 포인터를 덤프하는 것입니다. CFStringRef
바늘. 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;
}
다음과 같은 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의 두 아키텍처에 대해 이것을 테스트했으며 잘 작동합니다.
다른 팁
나는 당신이 이것을 직접 할 수 없다고 생각하지만 cfstring / nsstring에서 copyinst ()와 함께 사용할 수있는 cfstring / nsstring에서 공급되는 사용자 지정 정적 프로브를 만들 수 있습니다. 기사 에서이 작업을 수행하는 방법을 설명합니다 여기.