Edited at

はじめてのgdb

linux環境でC言語のデバッグを行う方にむけて、gdbの使い方を説明します。

初心者向けです。


gdbとは

デバッガです。ブレークポイントを張ったり、ステップ実行したり、

変数の中身を覗いたり、書き換えたり...そういうことが出来ます。

gccと同様、linuxには標準でインストールされています。

昔からあるツールであり、コマンドラインでの操作を行います。

IDEのデバッガがどうしても使えない環境でのデバッグに役立ちます。


メリット、デメリット

メリット:

・たいていのlinux環境で使える

・実行中のプログラムにattachしてデバッグ可能

デメリット:

・GUI画面がない。コマンドを覚える必要がある


使い方1:gdbから直接起動

①ソースファイルを、デバッグ可能な方式でコンパイルする

gcc -g3 test.c

→a.outが生成

※-g3とするとマクロの展開が可能となります。

②生成したオブジェクトファイルをgdbコマンドから実行

gdb a.out

→以後、gdbよりコマンドの入力を求められる

※この状態では、プログラムは実行されません。

③実行前にブレークポイントを設定

b test.c:256 # test.cの256行目にブレークを張る

b main # 関数main先頭にブレークを張る

④実行

run

※引数つきで実行したい場合は、run aaa bbb ccc と実行。


使い方2:既に稼動しているプログラムをデバッグ

①デバッグしたいプログラムのプロセスID(PID)を確認

ps -ef | grep a.out

※一番左端のフィールドに出てくる数字がPID

②attachする

gdb #引数無しで実行

attach 12345(↑で確認したpid)

※gdb attach $(pgrep a.out) とすれば、①、②を一行で実施できます。

以後、gdbを使ってブレークポイントを貼ったり変数を覗いたり出来ます。

プロセスを変えたいときはdetachしてから別のプロセスをアタッチできます。


コマンド集

主要なコマンドを紹介します。

すべて省略系で書いています。(ex. break -> b)

・ブレーク関連

コマンド
効果

b func1
関数func1にブレークポイントを貼る

b test.c:123
test.cの123行目にブレークポイントを貼る

w var1
変数var1にウォッチポイントを設定

i b
ブレークポイント一覧を表示

d no
番号に対応するブレークポイントを削除

・実行関連

コマンド
効果

n
ステップ実行(1行ずつ実行/関数は飛ばす)

s
ステップ実行(1行ずつ実行/関数の中に入る)

c
次のブレークポイントまで処理を実行

f
現在の関数を抜けるまで処理を実行

u
現在のループを抜けるまで処理を実行

ret -1
現在の関数を戻り値-1として強制的に抜ける ※以降の処理は実行されない

・参照

コマンド
効果

p var1
変数var1の値を見る
(構造体ならa.bでメンバ変数を参照可能。ポインタなら*fpなどで中身を見れる。p strlen(buf)、p buf[3]、p a->bなど結構柔軟に見れます)

bt
バックトレース(現在の関数が呼び出されるまでの経路)を表示

l
ソースコードを表示

info macro マクロ名
マクロの定義を確認

i lo
ローカル変数を全部見る

・値の書き換え

コマンド
効果

p var1=-1
変数var1の値を-1に変更


その他TIPS


  • bash等で使用しているショートカットを使用可能です。

    (例:Ctrl+aでカーソルを行頭に移動。参考: readlineの使い方)

    また、Tabキーによる変数名やgdb内コマンドの補完もしてくれます。

    (古い環境だとできないこともあります)


  • set print elements 0を実行するとメモリや構造体の全情報を表示してくれます。

    (サイズの大きい配列や構造体は、デフォルトだと途中までしか表示されません)


  • Ctrl-xを押した後、1または2を押すとTUIモードに移行します。

    画面が2分割され、ソースコードを見ながら上記コマンドを実行できるようになります。

    http://d.hatena.ne.jp/murase_syuka/20150912/1442021005


  • 子プロセスを生むプログラムの場合、以下のコマンドで子プロセスのデバッグが可能になります。

    set follow-fork-mode child



より詳細な情報

http://flex.phys.tohoku.ac.jp/texi/gdb-j/gdb-j_toc.html

http://sourceware.org/gdb/current/onlinedocs/gdb/