GDBでSegmentation Faultの原因を突き止める

 Linuxのプログラムをデバッグするとき、一番困ることはあの有名の「Segmentation Fault」ですね。
プログラムが膨大でマルチプロセス等を使っていたら、どこで問題を起こしているのかすらわからないです。
 本編はLinuxのCore Dump機能で問題発生行を特定する方法を紹介します。
 まず、前提としてはSegmentation Faultは再現できること。(当たり前ですよね)
 下記のプログラムを例とします。
#include<stdio.h>
#include<string.h>

#define DATA "TEST"

char            mngfile[2][50];

int main()
{
  memset( mngfile, '\0', sizeof(mngfile) );

  GetMngFile(mngfile);

  return 0;
}

int GetMngFile( mngfile )
  char            mngfile[2][50];
{
  int i=0;
  char    file[128];
  for(i=0;i<999;i++)
  {
    memset( file, '\0', sizeof(file) );

    strcpy(file,"abc");
    sprintf(mngfile[i],"%s_%s",file,DATA);
    printf("%d,%s\n",i,mngfile[i]);
  }
  return 0;
}
 次に、コンパイルオプションに「-g」を付けてコンパイルします。
  gcc test2.c -g -o test2
 多くのLinuxではデフォルトCoreDump機能を無効にしてあるため、有効にします。
  ulimit -c unlimited (生成するCoreのサイズを制限しない)
 プログラムを実行してみます。
  ./test2
  セグメンテーション違反です (core dumped)
 この時、カレントディレクトリで「core.11504」のようなファイルが生成されます。

 このCoreをGDBでデバッグしてみましょう。
  gdb ./test2 core.11504

  ・・・
  Core was generated by `./test2'. 
  (test2がCoreを吐いている)
  Program terminated with signal 11, Segmentation fault.
  (シグナル11でプログラムが終了され、セグメンテーション違反発生)
  Reading symbols from /lib/tls/libc.so.6...done.
  Loaded symbols for /lib/tls/libc.so.6
  Reading symbols from /lib/ld-linux.so.2...done.
  Loaded symbols for /lib/ld-linux.so.2
  #0  0x0058668b in _IO_default_xsputn_internal () from /lib/tls/libc.so.6 
  (最終実行ステップはlibc.so.6ライブラリの_IO_default_xsputn_internal()関数内にある)
(gdb)bt  (BackTraceしてみます。)
#0  0x0058668b in _IO_default_xsputn_internal () from /lib/tls/libc.so.6
#1  0x005645fa in vfprintf () from /lib/tls/libc.so.6
#2  0x0057c71b in vsprintf () from /lib/tls/libc.so.6
#3  0x0056995b in sprintf () from /lib/tls/libc.so.6
#4  0x080484ce in GetMngFile (mngfile=0x8049740) at test2.c:27
#5  0x08048441 in main () at test2.c:12
わたしのソースにのみ興味があるので、先頭にあるStack Frame番号の詳細をみます。
(gdb) frame 4
#4  0x080484ce in GetMngFile (mngfile=0x8049740) at test2.c:27
27          sprintf(mngfile[i],"%s_%s",file,DATA);

これでソースの27行目のsprintfで問題があることを判明しました。
このソースをよく見ると、配列mngfileの定義数を超えたメモリー領域のデータ改ざんのあったので、
これで問題判明です。