出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/05/17 00:30 UTC 版)
「GNUデバッガ」の記事における「セッション例」の解説
C言語で書かれた以下のソースコードを考える。 #include #include #include 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 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:...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関数を呼び出す際に発生する (引数 s が NULL であるため)。strlen の実装 (インライン関数かどうか) に応じて出力が異なる場合がある。 コマンド bt でプログラムのスタック・トレースをとると、main関数からソースコードの階層を降りてstrlen関数が呼び出されている流れを確かめられる。 GNU gdb (GDB) 7.3.1Copyright (C) 2011 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later 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:...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=, argv=) at example.c:16 この問題を修正するには、変数 a (main関数内) に有効な文字列を含まなければならない。コードの修正版は次の通りである。 #include #include #include 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内で実行ファイルを再コンパイルして実行すると、正しい結果が得られるようになった。 GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16)Copyright (C) 2011 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later 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:...Reading symbols from /path/example...done.(gdb) runStarting program: /path/examplesize of a = 21[Inferior 1 (process 14290) exited normally] GDBは printf の出力を画面に表示し、プログラムが正常に終了したことをユーザに知らせる。
※この「セッション例」の解説は、「GNUデバッガ」の解説の一部です。
「セッション例」を含む「GNUデバッガ」の記事については、「GNUデバッガ」の概要を参照ください。