メモリの二重解放エラー処理調査メモ

メモリの二重解放エラーが発生した時、
どのような処理が行われているのか調べてます。

```c:main.c
#include <stdio.h>
main(void)
{
  FILE *fp = fopen("hogehoge", "w");
  fclose(fp);
  fclose(fp);
}
```

コンパイルして実行すると

`*** Error in ``./a.out': double free or corruption (top): 0x08dbd008 ***
zsh: abort (core dumped)  ./a.out`

とメモリの二重解放を教えてくれるメッセージが。
（通常ならglibcがバックトレースやメモリマップを出力してくれるそうですが、
私の環境では何故か出力されませんでした）

・straceしてみる

`% strace ./a.out`
==================ここから実行結果======================
execve("./a.out", ["./a.out"], [/* 73 vars */]) = 0
brk(0)                                  = 0x9662000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7740000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=80341, ...}) = 0
mmap2(NULL, 80341, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb772c000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\233\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1758972, ...}) = 0
mmap2(NULL, 1768060, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb757c000
mprotect(0xb7725000, 4096, PROT_NONE)   = 0
mmap2(0xb7726000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a9000) = 0xb7726000
mmap2(0xb7729000, 10876, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7729000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb757b000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb757b940, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7726000, 8192, PROT_READ)   = 0
mprotect(0x8049000, 4096, PROT_READ)    = 0
mprotect(0xb7763000, 4096, PROT_READ)   = 0
munmap(0xb772c000, 80341)★←メモリ解放               = 0
brk(0)                                  = 0x9662000
brk(0x9683000)                          = 0x9683000
open("hogehoge", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(3)                                = 0
open("/dev/tty", O_RDWR|O_NOCTTY|O_NONBLOCK) = 3
writev(3, [{"*** Error in \`", 14}, {"./a.out", 7}, {"': ", 3}, {"double free or corruption (top)", 31}, {": 0x", 4}, {"09662008", 8}, {" ***\\n", 5}], 7*** Error in `./a.out': double free or corruption (top): 0x09662008 ***
) = 72
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb773f000★←ここでエラー発生？
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
gettid()                                = 9536
tgkill(9536, 9536, SIGABRT)             = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=9536, si_uid=1000} ---
+++ killed by SIGABRT (core dumped) +++
zsh: abort (core dumped)  strace ./a.out
==================ここまで実行結果======================
munmap()でメモリを解放しているようですが、
解放したアドレス0xb772c000が
その後アクセスされてるようには見えませんね。

システムコールでメモリに不正なアクセスが行われる前に、
何かがそれ検知してプロセスをkillしているのでしょうか。

今後も調査を続けます。