web-dev-qa-db-ja.com

あるマシンでgdbを実行し、別のマシンでkgdbカーネルを実行するにはどうすればよいですか?

2台のマシンを実行したい:

  1. デバッグされたマシン:kgdbオプションを使用してコンパイルされたカーネル。
  2. デバッガマシン:gdbを実行するため

マシン2からマシン1をデバッグするにはどうすればよいですか?

4
Milad Khajavi

gdbserver

あなたが探しているように聞こえます gdbserver

gdbserverは、Unixライクなシステム用の制御プログラムであり、通常のデバッグスタブにリンクせずに、ターゲットリモートを介してプログラムをリモートGDBに接続できます。

ターゲットマシン上

デバッグするプログラムのコピーが必要です。 gdbserverはプログラムのシンボルテーブルを必要としないため、必要に応じてプログラムを削除してスペースを節約できます。ホストシステム上のGDBは、すべてのシンボル処理を行います。

target $ gdbserver Host:2345 emacs foo.txt

注:次のように実行中のプロセスにアタッチすることもできます。

_target$ gdbserver comm --attach pid
_

1台のGDBホストマシン

GDBにはシンボルとデバッグ情報が必要なため、プログラムのストリップされていないコピーが必要です。プログラムのローカルコピーの名前を最初の引数として使用して、通常どおりGDBを起動します。 (--baud' option if the serial line is running at anything other than 9600bps.) After that, use target remote to establish communications with gdbserver. Its argument is either a device name (usually a serial device, like/dev/ttyb 'も必要になる場合があります)、またはHost:PORTの形式のTCPポート記述子。例:

_   (gdb) target remote the-target:2345
_

GDBスタブ

マニュアルで説明されている「リモートスタブ」と呼ばれる別の方法があります。公式マニュアルは、gnu.org Webサイトの GDB Documentation にあります。 GDBユーザーズマニュアル 、セクション 20.5、リモートスタブの実装 に目を通し、gdbserverの代わりにこの機能を使用する方法を説明します。

この方法は、ドキュメントで次のように説明されています。

次のステップは、gdbが実行されているマシン(ホストマシン)と通信するためにシリアルポートを使用するようにプログラムを調整することです。一般的に、スキームは次のようになります。

したがって、VMホストとゲストの両方にシリアルポートをセットアップし、この方法を使用してゲストのカーネルをデバッグできる可能性があります。

参考文献

2
slm

KGDB + QEMUステップバイステップ

私のQEMU + Buildrootの例は、実際のハードウェアなしでそれを味わうための良い方法です: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/1969cd6f8d30dace81d9848c6bacbb8bad9dacd8#kgdb

長所と短所対他の方法:

  • アドバンテージvsQEMU:
    • ハードウェアベンダーはデバイスの正確なソフトウェアモデルをリリースすることを好まないため、デバイスのソフトウェアエミュレーションがないことがよくあります。
    • qEMUよりもはるかに高速な実際のハードウェア
  • jTAGに対する利点:追加のJTAGハードウェアが不要で、セットアップが簡単
  • qEMUおよびJTAGと比較した場合の欠点:可視性が低く、煩わしい。 KGDBは、ホストと通信できるように動作するカーネルの特定の部分に依存しています。だから例えばパニックに陥り、起動シーケンスを表示できません。

主な手順は次のとおりです。

  1. 次のコマンドでカーネルをコンパイルします。

    CONFIG_DEBUG_KERNEL=y
    CONFIG_DEBUG_INFO=y
    
    CONFIG_CONSOLE_POLL=y
    CONFIG_KDB_CONTINUE_CATASTROPHIC=0
    CONFIG_KDB_DEFAULT_ENABLE=0x1
    CONFIG_KDB_KEYBOARD=y
    CONFIG_KGDB=y
    CONFIG_KGDB_KDB=y
    CONFIG_KGDB_LOW_LEVEL_TRAP=y
    CONFIG_KGDB_SERIAL_CONSOLE=y
    CONFIG_KGDB_TESTS=y
    CONFIG_KGDB_TESTS_ON_BOOT=n
    CONFIG_MAGIC_SYSRQ=y
    CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
    CONFIG_SERIAL_KGDB_NMI=n
    

    それらのほとんどは必須ではありませんが、これは私がテストしたものです。

  2. QEMUコマンドに追加します。

    -append 'kgdbwait kgdboc=ttyS0,115200' \
    -serial tcp::1234,server,nowait
    
  3. LinuxカーネルソースツリーのルートからGDBを実行します。

    gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'
    
  4. GDBの場合:

    (gdb) c
    

    ブートが終了するはずです。

  5. QEMUの場合:

    echo g > /proc/sysrq-trigger
    

    そしてGDBは壊れるべきです。

  6. これで完了です。通常どおりGDBを使用できます。

    b sys_write
    c
    

Ubuntu14.04でテスト済み。

KGDB + Raspberry Pi

上記とまったく同じセットアップは、Raspberry Pi 2、Raspbian Jessie2016-05-27でほぼ機能しました。

PiでQEMUの手順を実行する方法を学ぶ必要があります。これは、簡単にグーグルできます。

  • https://www.raspberrypi.org/documentation/linux/kernel/building.md で説明されているように、構成オプションを追加してカーネルを再コンパイルします。残念ながら、デフォルトのカーネルビルドにはオプションがありませんでした。シンボルをデバッグするため、再コンパイルが必要です。

  • ブートパーティションのcmdline.txtを編集し、以下を追加します。

    kgdbwait kgdboc=ttyAMA0,115200
    
  • gdbをシリアルに接続します。

    gdb -ex 'file vmlinux' -ex 'target remote /dev/ttyUSB0'
    

    シリアルに慣れていない場合は、これをチェックしてください: https://www.youtube.com/watch?v=da5Q7xL_OTo 必要なのは安価なアダプターです このような 。 KGDBを試す前に、シリアルを介してシェルを取得し、シェルが機能していることを確認してください。

  • 行う:

    echo g | Sudo tee /proc/sysrq-trigger
    

    シリアルはすでにGDBによって取得されているため、SSHセッション内から。

この設定により、sys_writeにブレークポイントを設定し、プログラムの実行を一時停止し、ソースを一覧表示して続行することができました。

ただし、sys_writenextを実行すると、GDBがハングして、このエラーメッセージが数回出力されることがありました。

Ignoring packet error, continuing...

そのため、セットアップに問題があるのか​​、それとも、より複雑なRaspbianイメージでバックグラウンドプロセスが実行しているためにこれが予想されるのかがわかりません。