Electric Fence

他人が書いたメモリ管理が酷過ぎるCプログラムを解析していて神経衰弱になる。コードを読んだり、デバッガで単純に追っかけるだけだと、中々わからない。一貫性の無い酷すぎるプログラムに嫌気が差してきて、ふと Electric Fenceのこと思い出して楽しようと使ってみる。Efence はメモリチェッカの一種で、バッファオーバーランやアンダーラン、freeしたメモリへのアクセスなどを見つけることができる。使い方はとても簡単で

 % cc prog.c -g -lefence

のようにライブラリをリンクするだけ。これだけで準備完了。このファイルを実行して、オーバーランとかするとSEGVでcore吐いて終了するようになる。gdbで追っかけるとと死亡地点が特定できるのであとは普通にデバッグすればいい。環境変数を設定すると挙動を変えることができる。

EF_DISABLE_BANNER
デフォルトでは efenceを導入すると、“Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.”とかいうバナーが表示されるんだけど、これを1にしておくと出なくなる。どうでもいい気もするけどテストとかで重要なのかな。
EF_ALIGNMENT
 このサイズ未満オーバーは検出しない。0, 1にすると全てチェック。デフォルトはマシンのintサイズ。そうなっているのはfalse positive抑制のため。
EF_PROTECT_BELOW
 1でアンダーラン検出。当たり前だけどオーバーアンダー同時チェックはできない。
EF_ALLOW_MALLOC_0
0サイズのmallocを許す。
EF_PROTECT_FREE
  1にするとfree()したところを再利用しなくなる。デフォルトではmallocで再利用されると不正アクセスがチェックされなくなるので、「あやしい」と思ったらつけておくと良い。
EF_FREE_WIPES
1にするとfree()したところを0xbdで上書きしてくれる。
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1210235200 (LWP 9762)]
0x08048505 in main () at free.c:12
12              printf("%x", *p);
(gdb) x/10x p
0xb7cd5c00:     0xbdbdbdbd      0xbdbdbdbd      0xbdbdbdbd      0xbdbdbdbd
0xb7cd5c10:     0xbdbdbdbd      0xbdbdbdbd      0xbdbdbdbd      0xbdbdbdbd
0xb7cd5c20:     0xbdbdbdbd      0xbdbdbdbd

てな感じに freeされたことがわかりやすくなる。

で、efenceなかったらゼッテー見つかんねーよ、というのが盛りだっくさん見つかったんだけど、後から後から出てきて、とってもとっても泣けてきた今の私。