前に、C Hello World プログラムを使用して C プログラムを作成およびコンパイルする方法の基本について説明しました。
この記事では、6 つの簡単な手順で gdb デバッガーを使用して C プログラムをデバッグする方法について説明します。
デバッグ用にエラーのある C プログラムのサンプルを作成
C プログラムのデバッグを学ぶために、数値の階乗を計算して出力する次の C プログラムを作成してみましょう。ただし、この C プログラムには、デバッグ目的でいくつかのエラーが含まれています。
$ vim factorial.c # include <stdio.h> int main() { int i, num, j; printf ("Enter the number: "); scanf ("%d", &num ); for (i=1; i<num; i++) j=j*i; printf("The factorial of %d is %d\n",num,j); }
$ cc factorial.c $ ./a.out Enter the number: 3 The factorial of 3 is 12548672
gdb で最も役立つコマンドを確認しながらデバッグしましょう。
ステップ 1. デバッグ オプション -g を使用して C プログラムをコンパイルする
-g オプションを使用して C プログラムをコンパイルします。これにより、コンパイラはデバッグ情報を収集できます。
$ cc -g factorial.c
注:上記のコマンドは、以下に示すようにデバッグに使用される .out ファイルを作成します。
ステップ 2. gdb を起動します
以下に示すように、C デバッガー (gdb) を起動します。
$ gdb a.out
ステップ 3. C プログラム内にブレークポイントを設定する
Syntax: break line_number
その他の形式:
- break [file_name]:line_number
- break [file_name]:func_name
エラーが疑われる C プログラムにブレーク ポイントを配置します。プログラムの実行中、デバッガーはブレーク ポイントで停止し、デバッグするプロンプトが表示されます。
プログラムを開始する前に、次のブレークポイントをプログラムに配置しましょう。
break 10 Breakpoint 1 at 0x804846f: file factorial.c, line 10.
ステップ 4. gdb デバッガーで C プログラムを実行する
run [args]
gdb デバッガーで run コマンドを使用して、プログラムの実行を開始できます。 run args を介してプログラムにコマンドライン引数を与えることもできます。ここで使用したサンプル プログラムはコマンド ライン引数を必要としないため、run を指定してプログラムの実行を開始します。
run Starting program: /home/sathiyamoorthy/Debugging/c/a.out
C プログラムを実行すると、最初のブレーク ポイントまで実行され、デバッグのプロンプトが表示されます。
Breakpoint 1, main () at factorial.c:10 10 j=j*i;
以下のセクションで説明するように、さまざまな gdb コマンドを使用して C プログラムをデバッグできます。
ステップ 5. gdb デバッガー内の変数値の出力
Syntax: print {variable} Examples: print i print j print num
(gdb) p i $1 = 1 (gdb) p j $2 = 3042592 (gdb) p num $3 = 3 (gdb)
上記のように、factorial.c では、変数 j を初期化していません。したがって、ガベージ値を取得すると、階乗値として大きな数値になります。
変数 j を 1 で初期化してこの問題を修正し、C プログラムをコンパイルして再度実行してください。
この修正後でも factorial.c プログラムに問題があるようです。まだ間違った階乗値が返されるためです。
したがって、ブレークポイントを 10 行目に配置し、次のセクションで説明するように続行してください。
ステップ 6. 続行、ステップ オーバーとイン – gdb コマンド
プログラムがブレークポイントで停止したときに選択できる gdb 操作には 3 種類あります。それらは次のブレークポイントまで継続しており、次のプログラム行にステップ インまたはステップ オーバーしています。
- c または continue:デバッガーは次のブレークポイントまで実行を続けます。
- n または next:デバッガーは次の行を単一の命令として実行します。
- s または step:次と同じですが、関数を単一の命令として扱わず、代わりに関数に入り、1 行ずつ実行します。
続行またはステップスルーすることで、'for ループ' 条件チェックで <=を使用していないことが問題の原因であることが判明した可能性があります。 <から <=に変更すると問題が解決します。
gdb コマンドのショートカット
頻繁な gdb 操作のほとんどには、次のショートカットを使用してください。
- l – リスト
- p – 印刷
- c – 続行
- s – ステップ
- ENTER:Enter キーを押すと、以前に実行したコマンドが再度実行されます。
その他の gdb コマンド
- コマンド: gdb コマンド l または list を使用して、デバッグ モードでソース コードを出力します。 l line-number を使用して特定の行番号を表示します (または) l function を使用して特定の関数を表示します。
- 注意:バックトラック – すべてのスタック フレーム、または最も内側の COUNT フレームのバックトレースを出力します。
- 助けて – 特定の gdb トピックのヘルプを表示 — help TOPICNAME.
- やめる – gdb デバッガーを終了します。