Thursday, December 24, 2009

Inspecting Crashes With GDB

SATOSHI ABE ON BLOG: Getting Started With GDB の続き。


このポストにおいて、プログラムのクラッシュを GDB で debug してみる。例として挙げるプログラム :
#include <stdio.h>

int array [2];

int main()
{
  array[0] = 0;
  array[1] = 1;
  printf("%d\n", array[0]);
  printf("%d\n", array[1]);
  printf("%d\n", array[10000]);
  return(0);
}


3 つ目の printf で segfault が発生する。実際に実行してみる :

% gcc -g -Wall -o HelloWorld.o HelloWorld.c
% ./HelloWorld.o
0
1
Segmentation fault
%


このぐらいの、短く、かつ、簡単なプログラムの場合、debugger を活用する意味もないが、とりあえず GDB を活用してみよう。キーワードは breakpoint と stepping だ。次の例において printf に breakpoint を指定している。debug している状況において、正確な行番号を特定できていない場合も考えられるだろう。

% gdb
(gdb) file HelloWorld.o
Reading symbols from /home/satoshiabe/Desktop/HelloWorld.o...done.
(gdb) break printf
Breakpoint 1 at 0x400418
(gdb) run
Starting program: /home/satoshiabe/Desktop/HelloWorld.o

Breakpoint 1, 0x00007ffff7abfb50 in printf () from /lib/libc.so.6
(gdb) step
Single stepping until exit from function printf,
which has no line number information.
0
main () at HelloWorld.c:10
10 printf("%d\n", array_a[1]);
(gdb) step

Breakpoint 1, 0x00007ffff7abfb50 in printf () from /lib/libc.so.6
(gdb) step

Single stepping until exit from function printf,
which has no line number information.
1
main () at HelloWorld.c:11
11 printf("%d\n", array_a[10000]);
(gdb) step

Program received signal SIGSEGV, Segmentation fault.
main () at HelloWorld.c:11
11 printf("%d\n", array_a[10000]);
(gdb) step

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) quit
%


breakpoint によって制御したフローを step コマンドで 1 行ずつ実行していく。これで、実際に segfault が発生する行を特定できる。

No comments: