DTraceアクションでCFStringRefを印刷するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/1413623

  •  06-07-2019
  •  | 
  •  

質問

関数の呼び出しをキャッチするDTraceプローブがあり、関数の引数の1つが CFStringRef です。これは、Unicode文字列へのポインタを保持するプライベート構造です。ただし、 CFStringRef 自体は char * ではないため、 copyinstr()などの通常のDTraceメソッドは単に?cp?、これは正確には役に立ちません。

では、DTraceアクションで文字列を印刷するにはどうすればよいですか

役に立ちましたか?

解決

私が知る限り、この種のことに対する組み込みのサポートはありません。通常、ライブラリは(Bradが言及しているように)文字列をデコードするプローブを公開します。そのため、ライブラリを変更できないため、 pid プロバイダーを使用してユーザー関数にフックし、自分でデコードする必要があります。

解決策( std :: string をダンプするためにC ++で使用するアプローチに非常に似ています)は、ベースから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

32ビットまたは64ビットのどちらのバイナリに対して実行しているかに応じて、正しい typedef のコメントを外します。 10.6で両方のアーキテクチャに対してこれをテストしましたが、正常に動作します。

他のヒント

これを直接行うことはできないと考えていますが、CFString / NSStringをchar *としてフィードするカスタム静的プローブを作成できます。これはcopyinstr()で使用できます。これを行う方法については、記事こちら

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top