TODESKING
技術ブログ

GDBでsegmentation Faultの原因を調査する(on OSX)

作業ログです。

1
2
§ ./ctags -R ~/.vim
Segmentation fault: 11

グエッ。というわけで原因を調査するはめに。

コアダンプ取る

1
$ ulimit -c unlimited

/cores/core.{PID}にコアダンプが出力されるようになる。

なんかcore file size: cannot modify limit: Operation not permittedとか言われて変更できないことがある(参照)けど、どうにかする。

gdbでコアダンプ読む

1
2
3
4
5
$ gdb -c /cores/core.1234
GNU gdb (GDB) 7.7.1
....
"/cores/core.1234": no core file handler recognizes format
(gdb)

とか言われて読み込みに失敗する。いったいなんなんだ(未解決)

検索すると普通にこれで読めるという説と対応してねえよという説があって謎。

コンパイルオプションをあれしてGDBであれする

1
2
# Makefile
CFLAGS    = -g -O0 -ggdb

-ggdb でGDB用デバッグ情報を付与できる。

1
2
3
4
5
6
7
8
$ gdb ./ctags
...
Reading symbols from ./ctags...done.
(gdb) r -R ~/.vim
Starting program: ./ctags -R ~/.vim

Program received signal SIGSEGV, Segmentation fault.
0x00007fff8b85ef80 in ?? ()

フムー落ちた

スタックトレース見る

1
2
3
4
5
(gdb) bt
#0  0x00007fff8b85ef80 in ?? ()
#1  0x00007fff5fbfee10 in ?? ()
#2  0x0000000100033fa8 in findVimTags () at vim.c:720
Backtrace stopped: frame did not save the PC

フレーム #2 の中身見る

1
2
3
(gdb) frame 2
#2  0x0000000100033fa8 in findVimTags () at vim.c:720
720             if ( strncmp ((const char*) line, "UseVimball", (size_t) 10) == 0 )

lineという変数怪しいですね

1
2
(gdb) p line
$1 = (const unsigned char *) 0x0

ヌル

で、ソースの該当箇所を見るとNULLチェック忘れてるということがわかる。

1
2
3
4
5
6
line = readVimLine(); // May returns NULL

if ( strncmp ((const char*) line, "UseVimball", (size_t) 10) == 0 )
{
  parseVimBallFile (line);
}

おわり

Comments