1

Trace32 で Linux リンク リストをユーザー フレンドリーな方法で印刷しようとしています。

1. 利用可能な既知の方法は既にありますか?

そうでない場合は、モジュールリストの例を示します。

グローバル変数があります

static struct list_head modules;

どこ

struct list_head {
        struct list_head *next, *prev;
};

そのため、T32 では、実行時に next および prev ポインターのリストが表示されるだけでv.v modules、実際には有用な情報はありません。ただし、モジュール リストのすべてのノードはコンテナー タイプの一部です。この場合、構造体モジュール

struct module {
         ...
         struct list_head list;
         ...
}

通常、Linux はコンテナー ポインターを抽出するために、container_ofマクロを使用します。

/**
  * container_of - cast a member of a structure out to the containing structure
  * @ptr:        the pointer to the member.
  * @type:       the type of the container struct this is embedded in.
  * @member:     the name of the member within the struct.
  *
  */
 #define container_of(ptr, type, member) ({                      \
         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
         (type *)( (char *)__mptr - offsetof(type,member) );})

この例struct list_head では、listメンバーであるポインターを知っているので、コンテナーへのポインターを取得するためにstruct module呼び出す必要があります。container_of(modules->next, struct module, list)

これを T32 でアーカイブできるようにするにはlist、コンテナー タイプのメンバーのオフセットを計算する必要があります。

誰でもこれを達成する方法を知っていますか?

4

2 に答える 2

4

2 つの質問があるようですね。

  1. リンクされたリストを表示するには?
  2. 構造体のメンバーのバイトオフセットを取得するには?

リンクされたリストを表示するには、コマンドVar.CHAINまたは VAR.FixedCHAIN をお勧めします。どちらのコマンドにも、構造体の変数名と次の要素の名前の 2 つの必須引数があります。( TRACE32 マニュアルですべてのオプションの引数とフォーマット オプションを調べることができます。)

したがって、最初の単純なケースを次のように表示します

Var.CHAIN modules modules.next   

'next' が NULL を指すまで、完全なリストを示すテーブルがウィンドウに表示されます。

:以下のコメントでWrymarkiが述べているように、回答の最初の部分は実際には間違っています。Var.CHAIN は通常の連結リストでは機能しますが、「Linux 連結リスト」では機能しません。「Linux リンク リスト」(Wrymarki 作) の解決策は、container_of() マクロ (下記参照) を使用して、リストをループし、Var.AddWatch でリスト エントリをウォッチ ウィンドウに追加する PRACTICE スクリプトを作成することです。


構造体のメンバーのオフセットを取得するには、ソース コードで行うのと同じように、プリプロセッサ マクロを宣言することをお勧めします。または、TRACE32 は typeof() やstatement expressionsなどの GCC 固有の拡張機能を認識しないため、ソース コードとほぼ同じです。

とにかく、次のようにして offsetof() マクロを取得できます

sYmbol.NEW.MACRO offsetof(type,member) ((int)(&((type*)0)->member))

プリプロセッサ マクロは、TRACE32 のすべての HLL 式内で使用できます (すべての Var.* コマンドおよび関数を使用)。例えば:

Var.AddWatch offsetof(struct module,list)

注: sYmbol.NEW.MACRO は、マクロ名にスペースを使用できません。. のoffsetof(type,member)代わりに記述する必要がありoffsetof(type, member)ます。

ウィンドウ sYmbol.List.MACRO でマクロを表示できます

オプション /MACRO: を使用して ELF をロードするときに、コンパイラがこれをサポートしている場合 (GCC はオプション -g3 を使用)、ソース コードからマクロを取得することもできますData.LOAD.Elf * /MACRO。ただし、TRACE32 は GCC 固有の拡張機能や「__builtin_offsetof()」などの内部マクロを認識しません。


container_of()プリプロセッサ マクロを次のように宣言することもできます。

sYmbol.NEW.MACRO container_of(ptr,type,member) ((type *)((char *)(ptr)-offsetof(type,member)))

たとえば、次のように使用します。

Var.View container_of(modules->next,struct module,list)
于 2015-11-05T10:44:35.767 に答える