6

私のプログラム:

typedef struct objc_class {
    struct objc_class *isa;
    struct objc_class *super_class;
    char *name;
    long version;
    long info;
    long instance_size;
    void *ivars;
    void *methodLists;
    void *cache;
    void *protocols;
} *Class;
struct objc_object {
    Class isa;
};

/* Code to extract the class name from arg0 based on a snippet by Bill Bumgarner: http://friday.com/bbum/2008/01/26/objective-c-printing-class-name-from-dtrace/ */

objc$target:NSObject:-init:entry {
    printf("time: %llu\n", timestamp);
    printf("arg0: %p\n", arg0);
    obj = (struct objc_object *)copyin(arg0, sizeof(struct objc_object));
    printf("obj: %p\n", obj);
    printf("obj->isa: %p\n", obj->isa);
    isa = (Class)copyin((user_addr_t)obj->isa, sizeof(struct objc_class));
    printf("isa: %p\n", obj->isa);
    classname = copyinstr((user_addr_t)(isa->name));
    printf("classname: %s\n", classname);
}

いくつかの出力:

dtrace: script 'test.d' matched 1 probe
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
dtrace: error on enabled probe ID 1 (ID 61630: objc5936:NSObject:-init:entry): invalid address (0x90206b98) in action #8 at DIF offset 28
CPU     ID                    FUNCTION:NAME
  0  61630                      -init:entry time: 28391086668386
arg0: 1291ae10
obj: 6f0a1158
obj->isa: a023f360
isa: a023f360
classname: NSBitmapImageRep

  1  61630                      -init:entry time: 28391586872297
arg0: 12943560
obj: 6f4a1158
obj->isa: 2fca0
isa: 2fca0
classname: GrowlApplicationTicket

  1  61630                      -init:entry time: 28391586897807
arg0: 152060
obj: 6f4a1280
obj->isa: 2fe20
isa: 2fe20
classname: GrowlNotificationTicket

  2  61630                      -init:entry time: 28391079142905
arg0: 129482d0
obj: 700a1128
obj->isa: a0014140
isa: a0014140
classname: NSDistributedObjectsStatistics

  2  61630                      -init:entry time: 28391079252640
arg0: 147840
obj: 700a1250
obj->isa: a0014780
isa: a0014780
classname: NSDistantObjectTableEntry

なぜエラーですか?それはクラス名のようです(それだけ%sで、削除してもエラーは発生しません)が、一部のクラスの名前が無効なポインターであると見なされるのはなぜですか?

エラーメッセージを取得して、DTraceプログラムのどの行で問題が発生したかを実際に知らせる方法はありますか?

object_getClassNameこの構造検査ダンスを行う代わりに呼び出す方法はありますか?

価値のあることとして、私がトレースしているプログラムは正常に機能します。クラッシュすることはないので、クラスが実際に壊れているとは思いません。

4

4 に答える 4

5

コリンはかなり正しいです。

見る:

http://www.friday.com/bbum/2008/01/03/objective-c-using-dtrace-to-trace-messages-to-nil/

おそらく、DYLD_SHARED_REGION環境変数をに設定する必要がありますavoid。dtrace は、物理メモリに実際に存在するマップされたメモリに対してのみ機能します。

vmmapコマンド ライン ツールを使用すると、不足しているものを把握できます。

vmmap PID上記の失敗メッセージが生成された後、アプリケーションでaを実行します。出力を見て、住所のようなものがどの地域に0x90206b98該当するかを確認します。そのアドレスを考えると、常駐していない書き込み不可の共有メモリ チャンクにある可能性が高いため、dtrace はそこから読み取ることができません。

于 2009-08-20T15:43:38.950 に答える
3

このエラーは、まだ障害が発生していないページで copyin / copyinstr が使用された場合に発生します。一般的な回避策は、関数に問題のデータを使用させてから、 :::return 句で copyin[str] を使用することです。例えば:

syscall::open:entry
{
    self->filename = arg0;  /* Hang on to the file name pointer.  */
}

syscall::open:return
/self->filename/
{
    @files[copyinstr(self->filename)] = count();
    self->filename = 0;
}

END
{
    trunc(@files, 5);
}
于 2013-09-25T14:12:36.417 に答える
2

私はこれを自分で完全に追跡していません。DTrace が一部の Objective-C シンボルを解決しようとしている可能性があります。DTrace は動的トレース機能ですが、実行時に動的にロードする Objective-C とはうまく調和しません。Objective-C が新しいクラスなどをロードする場合、DTrace はこれを解決する必要があり、特にアプリの起動時は少し時間がかかります。たとえロードされたとしても、objc アプリが新しいクラスを objc ランタイムにロードしている可能性があるため、DTrace が台無しになり、メソッドが間違った順序で出力される可能性があります (正しい順序でメソッドが実行されていることを確認したい場合)。 、間違ったタイミング結果を出力するなど。

于 2009-08-01T22:42:14.293 に答える
0

これは、提供された情報に基づく私の最善の推測です。

DTrace は、DTrace スクリプトを可能な限り確定的にするように意図的に設計されています。これが、ifステートメント、ループ、サブルーチン (DTrace 自体が提供する疑似サブルーチンを除く) などがない理由です。これは、DTrace スクリプトのコードが、プロセスの一部としてユーザー ランドではなく、カーネル モードで実行されているためです。 (es) トレースされています。一般に、DTrace がアクセスできる情報は「読み取り専用」であり (ほとんどの一般化と同様に、これは厳密には正しくありません)、DTrace と同じくらい強力なものを使用してプログラムまたはカーネルをいじることができます。非常に、非常に間違って、非常に迅速に。

ドーナツへのドル、あなたが抱えている問題は、ポインターが指すページが VM システムによってコアにマップされていないためです。DTrace は、コアにあるメモリの情報のみを調べることができます。VM システムをページにロードする二重障害はありません。

クラスが「あるべき」ものを把握していて、必要なクラスを参照するダミーの NSLog() ステートメントをいくつか都合のよい場所で実行することによって、ページを強制的にコアにマップすることができれば、問題を軽減するのに役立つ可能性があります。プログラムの起動の早い段階でポイントします。

于 2009-07-30T08:43:33.753 に答える