ウェブサイト検索

GNU デバッガーまたは GDB: Linux プログラム用の強力なソース コード デバッグ ツール


デバッガは、あらゆるソフトウェア開発システムにおいて重要な役割を果たします。誰も一度にバグのないコードを書くことはできません。開発の過程でバグが発生し、さらなる機能強化のために解決する必要があります。開発システムはデバッガなしでは不完全です。オープンソース開発者コミュニティを考慮すると、GNU Debugger が最良の選択です。 UNIX タイプのプラットフォームでの商用ソフトウェア開発にも使用されます。

gdb とも呼ばれる GNU デバッガ を使用すると、実行中のコードや、プログラムがクラッシュする直前に何をしようとしていたかをこっそり確認できます。 GDB は基本的に、ソース コード内の欠陥を見つけるために 4 つの主要な作業を行うのに役立ちます。

  1. 一般的な動作に影響を与える可能性のある引数を指定して、プログラムを開始します。
  2. 指定された条件でプログラムを停止します。
  3. クラッシュが発生したか、プログラムがいつ停止したかを調べます。
  4. コードを変更し、変更したコードを即座に試します。

gdb を使用すると、C や C++ で書かれたプログラムを手間をかけずにデバッグできます。現時点では、DModula-2Fortran などの他のプログラミング言語のサポートは部分的です。

GNU デバッガーまたは GDB の使用を開始する

GDB は、gdb コマンドを使用して呼び出します。 gdb を発行すると、プラットフォームに関する情報が表示され、以下に示すように (gdb) プロンプトが表示されます。 。

[root@fedora20 ~]# gdb
サンプル出力
GNU gdb (GDB) Fedora 7.6.50.20130731-19.fc20 
Copyright (C) 2013 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law.  Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-redhat-linux-gnu". 
Type "show configuration" for configuration details. 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
Find the GDB manual and other documentation resources online at: 
<http://www.gnu.org/software/gdb/documentation/>. 
For help, type "help". 
Type "apropos word" to search for commands related to "word". 
(gdb)

ヘルプ リスト」と入力すると、gdb 内で使用できるさまざまなクラスのコマンドが表示されます。 「help 」と入力し、その後にクラス名を入力すると、そのクラスのコマンドのリストが表示されます。すべてのコマンドのリストを表示するには、「help all」と入力します。コマンド名の略語は、明確であれば許可されます。たとえば、「next」または「c」と入力する代わりに、「n」と入力できます。 >続行など。

最も一般的に使用される GDB コマンド

一般的に使用されるgdb コマンドを次の表に示します。これらのコマンドは、gdb コマンド プロンプト (gdb) から使用します。

Command

説明

run

プログラムの実行を開始する

quit

gdb を終了

print expr

expr 変数名も指定できる式を出力します

next

次の行に移動

step

次の行にステップイン

continue

現在の行からプログラムの終わりまたは次のブレークポイントまで続行します

2 つのコマンド stepnext の違いに注意してください。次の行が関数呼び出しである場合、next コマンドは関数内には入りません。一方、step コマンドは関数内に移動して、そこで何が起こるかを確認できます。

GDB を使用したサンプル セッション

次のソースコードを考えてみましょう。


// sum.c
#include <stdio.h> 

int sum (int a, int b) { 
	int c; 
	c = a + b; 
	return c; 
} 

int main() { 
	int x, y, z; 
	printf("\nEnter the first number: "); 
	scanf("%d", &x); 
	printf("Enter the second number: "); 
	scanf("%d", &y); 
	z = sum (x, y); 
	printf("The sum is %d\n\n", z); 
	return 0; 
}

出力ファイルをデバッグするには、次のように -g オプションを使用して gcc に出力ファイルをコンパイルする必要があります。

gcc -g sum.c -o sum

出力ファイルsumは、次の 2 つの方法のいずれかを使用して gdb に添付できます。

1. 出力ファイルを gdb の引数として指定します。

gdb sum

2. file コマンドを使用して、gdb 内で出力ファイルを実行します。

gdb
(gdb) file sum

list コマンドは、ソース コード ファイル内の行を一覧表示し、ポインタを移動します。したがって、最初のリストには最初の 10 行が表示され、次のリストには次の 10 行が表示されます。

(gdb) list
1	#include <stdio.h>   
2	 
3	int sum (int a, int b) { 
4		int c; 
5		c = a + b; 
6		return c; 
7	} 
8	 
9	int main() { 
10		int x, y, z;

実行を開始するには、run コマンドを発行します。これで、プログラムが正常に実行されるようになりました。しかし、デバッグのためにソース コードにブレークポイントをいくつか置くのを忘れましたよね?これらのブレークポイントは、関数または指定した行に指定できます。

(gdb) b main

: 私はブレイクの略語bを使用しました。

main 関数にブレークポイントを設定した後、プログラムを再実行すると 11 行目で停止します。行番号が事前にわかっている場合は、同じことが有効になります。

(gdb) b sum.c:11

ここで、next または n コマンドを使用してコード行をステップ実行します。関数にブレークポイントが設定されていない限り、next コマンドは関数コード内には入らないことに注意することが重要です。では、print コマンドを試してみましょう。以下のように関数sumにブレークポイントを設定します。

(gdb) b sum 
Breakpoint 1 at 0x4005aa: file sum.c, line 5. 
(gdb) r 
Starting program: /root/sum 

Enter the first number: 2 
Enter the second number: 3 

Breakpoint 1, sum (a=2, b=3) at sum.c:5 
5		c = a + b; 
(gdb) p a 
$1 = 2 
(gdb) p b 
$2 = 3
(gdb) c 
Continuing. 
The sum is 5 

[Inferior 1 (process 3444) exited normally]

実行中のプログラムにコマンド ライン パラメータが必要な場合は、run コマンドとともに同じパラメータを指定します。

(gdb) run   . . .

現在実行中のプログラムに関連付けられた共有ライブラリ ファイルは、次のようにリストされます。

(gdb) info share 
From                To                  Syms Read   Shared Object Library 
0x00000035a6000b10  0x00000035a6019c70  Yes         /lib64/ld-linux-x86-64.so.2 
0x00000035a641f560  0x00000035a6560bb4  Yes         /lib64/libc.so.6

変数の変更

GDB は、プログラムの実行中に変数を変更することもできます。これを試してみましょう。上で述べたように、16 行目にブレークポイントを設定し、プログラムを実行します。

(gdb) r 
Starting program: /root/sum 

Enter the first number: 1 
Enter the second number: 2 

Breakpoint 1, main ( ) at sum.c:16 
16		printf("The sum is %d\n\n", z); 
(gdb) set z=4 
(gdb) c 
Continuing. 
The sum is 4

ここでa=1b=2となり、結果はz=3となるはずです。ただし、ここでは main 関数の最終結果を z=4 に変更しました。このように、gdb を使用するとデバッグが容易になります。

ブレークポイントの有効化/無効化

すべてのブレークポイントのリストを取得するには、「info ブレークポイント」と入力します。

(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep y   0x00000000004005c2 in main at sum.c:11

ここではブレークポイントが 1 つだけあり、それが To です。有効 ブレークポイントを無効にする場合は、無効コマンドとともにブレークポイント番号を指定します。後で有効にするには、enable コマンドを使用します。

(gdb) disable 1 
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep n   0x00000000004005c2 in main at sum.c:11

delete コマンドを使用してブレークポイントを削除することもできます。

実行中のプロセスのデバッグ

GNU/Linux システムでは、多数のプロセスがバックグラウンドで実行されています。実行中のプロセスをデバッグするには、まずその特定のプロセスのプロセス ID を見つける必要があります。 pidof コマンドはプロセスの pid を取得します。

pidof <process_name>

次に、この pid を gdb にアタッチする必要があります。方法は2つあります。

1. gdb とともに pid を指定します。

gdb -p <pid>

2. gdb からattach コマンドを使用します。

(gdb) attach <pid>

それは今のところすべてです。これらは、ソース コードのデバッグを始めるための gdb の基本にすぎず、上で説明したものよりもはるかに多くのことを意味します。たとえば、スタック情報、環境変数などを使用してデバッグできます。これらすべてを試してみてください…