- blogs:
- cles::blog
2010/06/26

glibcのdouble free検知

C 言語についていろいろ調べていて、わざとダブルフリーするようなプログラムを書くと glibc がスタックトレースを吐いて ABORT することに気づきました。バリバリ C を使う人にとっては当たり前の挙動なのかもしれませんが、プログラミングの道には最初から Java で入ってしまったので、メモリ管理を自分でやる言語をほとんどメインで使ったことがない自分にとっては興味深い挙動でした。
test.c
#include <stdio.h>
#include <stdlib.h>
int main(){
int *i = malloc(sizeof(int));
free(i);
free(i);
return 0;
}
例えば上記のようなプログラムを実行すると下記のような出力になるようです。
$ gcc test.c
$ ./a.out
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x09ae0008 ***
======= Backtrace: =========
/lib/libc.so.6[0x2215a5]
/lib/libc.so.6(cfree+0x59)[0x2219e9]
./a.out[0x804840a]
/lib/libc.so.6(__libc_start_main+0xdc)[0x1cde9c]
./a.out[0x8048321]
======= Memory map: ========
00199000-001b4000 r-xp 00000000 08:02 53674048 /lib/ld-2.5.so
001b4000-001b5000 r-xp 0001a000 08:02 53674048 /lib/ld-2.5.so
001b5000-001b6000 rwxp 0001b000 08:02 53674048 /lib/ld-2.5.so
001b8000-0030a000 r-xp 00000000 08:02 53674260 /lib/libc-2.5.so
0030a000-0030c000 r-xp 00152000 08:02 53674260 /lib/libc-2.5.so
0030c000-0030d000 rwxp 00154000 08:02 53674260 /lib/libc-2.5.so
0030d000-00310000 rwxp 0030d000 00:00 0
003e1000-003ec000 r-xp 00000000 08:02 53674904 /lib/libgcc_s-4.1.2-20080825.so.1
003ec000-003ed000 rwxp 0000a000 08:02 53674904 /lib/libgcc_s-4.1.2-20080825.so.1
009f8000-009f9000 r-xp 009f8000 00:00 0 [vdso]
08048000-08049000 r-xp 00000000 08:02 40763512 /tmp/a.out
08049000-0804a000 rw-p 00000000 08:02 40763512 /tmp/a.out
09ae0000-09b01000 rw-p 09ae0000 00:00 0 [heap]
b7f1e000-b7f1f000 rw-p b7f1e000 00:00 0
b7f31000-b7f32000 rw-p b7f31000 00:00 0
bfc55000-bfc6a000 rw-p bffea000 00:00 0 [stack]
Aborted
ちなみにこの挙動についてはMALLOC_CHECK_で調整できるようです。
man malloc 3
Recent versions of Linux libc (later than 5.4.23) and GNU libc (2.x) include a malloc implementation which is tunable via environment variables. When MALLOC_CHECK_ is set, a special (less efficient) implementation is used which is designed to be tolerant against simple errors, such as double calls of free() with the same argument, or overruns of a single byte (off-by-one bugs). Not all such errors can be protected against, however, and memory leaks can result. If MALLOC_CHECK_ is set to 0, any detected heap corruption is silently ignored and an error message is not generated; if set to 1, the error message is printed on stderr, but the program is not aborted; if set to 2, abort() is called immediately, but the error message is not generated; if set to 3, the error message is printed on stderr and program is aborted. This can be useful because otherwise a crash may happen much later, and the true cause for the problem is then very hard to track down.
ということで、 MALLOC_CHECK_ を変えて実行するとこんな感じ。
$ MALLOC_CHECK_=0 ./a.out
$ MALLOC_CHECK_=1 ./a.out
malloc: using debugging hooks
*** glibc detected *** ./a.out: free(): invalid pointer: 0x09aec008 ***
$ MALLOC_CHECK_=2 ./a.out
Aborted
$ MALLOC_CHECK_=3 ./a.out
malloc: using debugging hooks
*** glibc detected *** ./a.out: free(): invalid pointer: 0x08799008 ***
======= Backtrace: =========
/lib/libc.so.6[0x224f4c]
/lib/libc.so.6(cfree+0xdb)[0x221a6b]
./a.out[0x804840a]
/lib/libc.so.6(__libc_start_main+0xdc)[0x1cde9c]
./a.out[0x8048321]
======= Memory map: ========
00199000-001b4000 r-xp 00000000 08:02 53674048 /lib/ld-2.5.so
001b4000-001b5000 r-xp 0001a000 08:02 53674048 /lib/ld-2.5.so
001b5000-001b6000 rwxp 0001b000 08:02 53674048 /lib/ld-2.5.so
001b8000-0030a000 r-xp 00000000 08:02 53674260 /lib/libc-2.5.so
0030a000-0030c000 r-xp 00152000 08:02 53674260 /lib/libc-2.5.so
0030c000-0030d000 rwxp 00154000 08:02 53674260 /lib/libc-2.5.so
0030d000-00310000 rwxp 0030d000 00:00 0
003e1000-003ec000 r-xp 00000000 08:02 53674904 /lib/libgcc_s-4.1.2-20080825.so.1
003ec000-003ed000 rwxp 0000a000 08:02 53674904 /lib/libgcc_s-4.1.2-20080825.so.1
00bed000-00bee000 r-xp 00bed000 00:00 0 [vdso]
08048000-08049000 r-xp 00000000 08:02 40763512 /tmp/a.out
08049000-0804a000 rw-p 00000000 08:02 40763512 /tmp/a.out
08799000-087ba000 rw-p 08799000 00:00 0 [heap]
b7f9c000-b7f9d000 rw-p b7f9c000 00:00 0
b7faf000-b7fb0000 rw-p b7faf000 00:00 0
bf9fc000-bfa11000 rw-p bffea000 00:00 0 [stack]
Aborted
デフォルト(環境変数に何も設定されていない状態)ではMALLOC_CHECK_=3と同じ状態になるみたいです。
トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/3622
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form
コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。
OpenID を使ってログインすることができます。
サイト内検索
検索ワードランキング
へぇが多いエントリ
- crontab -r とやってしまった... (2)
- Jawbone Companion (beta) (1)
- GPS ロガーを自作 (1)
- MPC-HC で連続再生を行う(解... (1)
閲覧数が多いエントリ
1 . アーロンチェアのポスチャーフィットを修理(114399)
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(112925)
3 . 年次の人間ドックへ(112354)
4 . 2023 年分の確定申告完了!(1つめ)(111923)
5 . 三菱鉛筆がラミーを買収(111797)
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(112925)
3 . 年次の人間ドックへ(112354)
4 . 2023 年分の確定申告完了!(1つめ)(111923)
5 . 三菱鉛筆がラミーを買収(111797)
cles::blogについて
Referrers