0

現在、カーネルモジュールをデバッグしています。この目的のために、デバッグ情報を使用してカーネル全体を構築しました(kallsymsなどを生成します...)。

を試すとnm my_module.ko、モジュールに含まれるシンボルのリストが表示されます。記号リストに表示されないために一部の記号が欠落していることを除いて、すべて問題ありません。これについての私の感覚は、関連する関数が自動的にインライン化されているということです。

とにかく、qemu-kgdb/gdb でカーネルを実行すると、「不足している」関数が呼び出されていることがわかります。これは、どのコードパスでも使用されていないため、コンパイラがそれを消去しなかったことを意味します (したがって、私の「感覚」)。

シンボルが表示されないため、ブレークポイントを設定できず、実行中のコード パスを確認できるようにgdb が展開しません。gdb に展開を指示する方法がわからないことを理解してください。
残念ながら、コード パスのこの部分を確認したいのですが、どうすればよいですか?

編集: トムの答えで示唆されているように、私はfile:line以下の構文を使用してみました:

私のコードファイルは次のようになります:

int foo(int arg) // The function that I suspect to be inlined - here is line 1
{
    /* Blabla */
    return 42;
}

void foo2(void)
{
    foo(0); // Line 9
}

を試しb file.c:1ましたが、ブレークポイントにヒットしましたが、foo()関数は展開されません。もちろん、foo2何が起こったのかを確認するためにブレークポイントも設定したので (これはうまくいきました)、デバッグ シンボルを作成しています。

4

2 に答える 2

2

使用している gdb のバージョンはわかりません。

非常に古いバージョンの gdb では、インライン関数がサポートされていません。これは 6.8 にも当てはまり、おそらく 7.0 にも当てはまりました -- 私は覚えていません。gdb の NEWS ファイルを見て確認できます。

その後、インライン関数のブレークポイントをサポートする gdb のいくつかのバージョンがありましたが、「file:line」構文のみを使用していました。したがって、エディターで関数を検索し、その行番号を見つけて、次のように入力します。

(gdb) break myfile.c:777

7.4 または 7.5 (私は忘れています) から始まる gdb のさらに最近のバージョンでは、「関数」がインライン化されていれば、「ブレーク関数」を問題なく処理します。

これはすべて、debuginfo が利用可能な場合にのみ機能します。したがって、これを試して失敗した場合は、古い gdb を使用しているか、-g の使用を忘れているかのいずれかです。

コンパイルでどのオブジェクトが -g に欠けていたかを gdb 内で確認する良い方法はありません。ただし、.o ファイルに対して「readelf -WS」を実行し、.debug_info セクションを持たないファイルを探すことで、シェルから非常に簡単に確認できます。

于 2013-06-03T14:27:37.060 に答える