GNUデバッガ

GNUデバッガ(単にGDBとも)は、GNUソフトウェア・システムで動く標準のデバッガである。これは、多くのUnix系システムで動作可能な移植性の高いデバッガであり、AdaC言語C++Objective-CPascalFORTRANFreeBASICGoといったプログラミング言語に対応している[2][3]

GNUデバッガ
開発元GNUプロジェクト
初版1986年 (38年前) (1986)
最新版
12.1[1] / 2022年5月1日 (23か月前) (2022-05-01)
リポジトリ ウィキデータを編集
プログラミング
言語
C
対応OSUnix-like, Windows
種別デバッガ
ライセンスGPL
公式サイトgnu.org/software/gdb/
テンプレートを表示

歴史

GDBは初め、GNU Emacs が「そこそこ安定化」した後、1986年GNU システムの一部として リチャード・ストールマン が書いた[4]。GDBは、GNU General Public License (GPL) の下でリリースしている フリーソフトウェア である。これは、BSDに付属していたdbx英語版デバッガをモデルにしている[4]

1990年から1993年まではジョン・ギルモアが保守をしていた[5]。現在はFree Software Foundationによって任命されたGDB運営委員会によって保守されている[6]

技術詳細

機能

GDBは、プログラムの実行の変更や追跡といった充実した機能を提供する。プログラム内部の 変数 の値を修正したり、監視したりすることや、プログラムの通常の動作とは別に 関数 を呼び出すことができる。

2003年 現在、GDBのターゲット・プロセッサは、以下のとおりである。

標準リリースでサポートされている、さほど有名でないターゲット・プロセッサには、以下がある。

新しいリリースでは、これらの一部をサポートしていない可能性がある。GDBには、M32RやV850といった、日本製のCPUをターゲットにしたコンパイル済みのシミュレータがある[7]

GDBはまだ活発に開発されている。バージョン7.0の新機能には、Pythonスクリプトのサポートが含まれ[8]、バージョン7.8ではGNU Guileスクリプトもサポートされている[9]。バージョン7.0からは「リバーシブルデバッグ」がサポートされている。これは、クラッシュしたプログラムを巻き戻して何が起こったのかを確認するように、デバッグセッションを後退させることができる[10]

遠隔デバッグ

GDBには「遠隔」モードがあり、しばしば組込みシステムのデバッグで使われる。遠隔操作では、GDBとデバッグ対象のプログラムは別のマシンで動作する。GDBは、GDBプロトコルをシリアルやTCP/IP経由で理解する遠隔「スタブ」と通信することができる[11]。スタブプログラムは、通信プロトコルのターゲット側を実装したGDB付属の適切なスタブファイルにリンクすることで作成できる[12]。または、gdbserver英語版を使用して、プログラムを変更せずにリモートでデバッグすることもできる。

GDBを使い、動いているLinuxカーネルをソース・レベルでデバッグするKGDBでも、同じモードを使っている。KGDBを使い、カーネル開発者は、アプリケーション・プログラムのようにカーネルをデバッグできる。カーネル・コードにブレークポイントを設定でき、ステップ動作ができ、変数を参照できる。ハードウェアのデバッグ・レジスタ (debugging register) が使えるアーキテクチャでは、ウォッチポイントが設定できる。ウォッチポイントとは、特定のメモリー・アドレスを実行したり、アクセスしたときのブレークポイントをかけるものである。KGDBには、シリアルケーブルイーサネットを使ってデバッグ対象マシンに繋がったマシンが必要となる。FreeBSDでは、FireWire DMAを使ったデバッグもできる[13]

グラフィカルユーザーインタフェース

このデバッガは、グラフィカルユーザインタフェース (GUI) は含まれておらず、デフォルトはコマンドラインユーザインタフェース (CUI) である。UltraGDB、Xxgdb、Data Display Debugger (DDD)、NemiverKDbgXcode デバッガ、GDBtk/Insight、HP Wildebeest Debugger GUI (WDB GUI) など、いくつかのフロントエンドが構築されている。CodeliteCode::BlocksDev-C++GeanyGNAT Programming Studio (GPS)、KDevelopQt CreatorLazarusMonoDevelopEclipseNetBeansVisual Studioなどの統合開発環境は、GDBとインターフェースをとることができる。GNU Emacsには「GUDモード」があり、VIM用のツールが存在する(例: clewn)。これらのツールはIDEにあるデバッガと同様の機能を提供する。

他にも、メモリリーク検出器など、GDBと連動するように設計されたデバッグツールもある。

コマンド例

gdb program"program" をデバッグ (シェル上で操作)
run -vロードされたprogramをパラメータを指定して実行
btバックトレース (programがクラッシュした場合)
info registersすべてのレジスタをダンプ
disas $pc-32, $pc+32逆アセンブル(等価なコマンドは x/64i $pc-32[14] )

セッション例

C言語で書かれた以下のソースコードを考える。

#include <stdio.h>#include <stdlib.h>#include <string.h>size_t foo_len( const char *s ){  return strlen( s );}int main( int argc, char *argv[] ){  const char *a = NULL;  printf( "size of a = %lu\n", foo_len(a) );  exit( 0 );}

Linux上のGCCコンパイラを使用する場合、生成されたバイナリに適切なデバッグ情報を含めるために-gフラグを使用して上記のコードをコンパイルしなければならない。これにより、GDBを使用してバイナリを検査できる。上記のコードを含むファイルが example.c という名前であると仮定すると、コンパイルのためのコマンドは次の様になる。

$ gcc example.c -Og -g -o example

そして、バイナリを実行できるようになった。

$ ./exampleSegmentation fault

サンプルコードを実行するとセグメンテーションフォールトが発生するので、GDBを使用して問題を検査することができる。

$ gdb ./exampleGNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16)Copyright (C) 2011 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <https://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".For bug reporting instructions, please see:<https://www.gnu.org/software/gdb/bugs/>...Reading symbols from /path/example...done.(gdb) runStarting program: /path/exampleProgram received signal SIGSEGV, Segmentation fault.0x0000000000400527 in foo_len (s=0x0) at example.c:88  return strlen (s);(gdb) print s$1 = 0x0

この問題は8行目にあり、strlen関数を呼び出す際に発生する (引数 sNULL であるため)。strlen の実装 (インライン関数かどうか) に応じて出力が異なる場合がある。

コマンド bt でプログラムのスタック・トレースをとると、main関数からソースコードの階層を降りてstrlen関数が呼び出されている流れを確かめられる。

GNU gdb (GDB) 7.3.1Copyright (C) 2011 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <https://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 "i686-pc-linux-gnu".For bug reporting instructions, please see:<https://www.gnu.org/software/gdb/bugs/>...Reading symbols from /tmp/gdb/example...done.(gdb) runStarting program: /tmp/gdb/exampleProgram received signal SIGSEGV, Segmentation fault.0xb7ee94f3 in strlen () from /lib/i686/cmov/libc.so.6(gdb) bt#0  0xb7ee94f3 in strlen () from /lib/i686/cmov/libc.so.6#1  0x08048435 in foo_len (s=0x0) at example.c:8#2  0x0804845a in main (argc=<optimized out>, argv=<optimized out>) at example.c:16

この問題を修正するには、変数 a (main関数内) に有効な文字列を含まなければならない。コードの修正版は次の通りである。

#include <stdio.h>#include <stdlib.h>#include <string.h>size_t foo_len( const char *s ){  return strlen(s);}int main( int argc, char *argv[] ){  const char *a = "This is a test string";  printf( "size of a = %lu\n", foo_len(a) );  exit( 0 );}

GDB内で実行ファイルを再コンパイルして実行すると、正しい結果が得られるようになった。

GDBは printf の出力を画面に表示し、プログラムが正常に終了したことをユーザに知らせる。

脚注

関連項目


外部リンク

ドキュメント

チュートリアル