具体例1: すでにfree済みのアドレスを操作しようとしてエラー
レポート結果
ログからわかること
・対象のプロセスIDは 37695
・アドレス 0x619000000580 において、heap-use-after-free を検出した
・PCレジスタが 0x00010b5b3aa8, BPレジスタが 0x7ffee46a5a10, SPレジスタが 0x7ffee46a51c0 の状態だった
・スレッドT0(メインスレッドのこと)で発生
・1バイトの書き込みをしようとした時にアドレス0x619000000580が違反した事を検知した
・test61.cpp の 11行目から呼び出された memset で発生(※コンパイラが自動的に memsetの代わりに __asan_memset を呼び出す処理に書き換えていた)
・アドレス 0x619000000580 は、0x619000000580 から始まる 1024バイトの領域の先頭である。
・test61.cppの8行目で スレッドT0によって解放済
・test61.cppの6行目で 以前はスレッドT0によって確保されていた。
【SUMMARY 以降】
・違反になったアドレスより前の領域は確保されていないヒープ領域(fa)
・違反になったアドレス以降は解放済みのヒープ領域(fd)
【ログから推測できる不具合の内容】
・free されたあとにアクセスしないようにシーケンスを制御し忘れている(アドレス変数をNULLに設定忘れとか。フラグ変更忘れとか。)
参考)上記のログを発生させたソースコード
#include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { // ヒープ確保 char *ptr = (char *) malloc(1024); // ヒープ解放 free(ptr); // 解放したアドレスに対する操作 memset(ptr, 0, 1); return 0; }
参考)コンパイル・実行例
$ clang++ -g -O0 -o test61 -fsanitize=address test61.cpp $ ./test61
具体例2: すでにdelete済みのアドレスを操作しようとしてエラー
レポート結果
ログからわかること
・対象のプロセスIDは 37872
・アドレス 0x619000000580 において、heap-use-after-free を検出した
・PCレジスタが 0x000101181aa8, BPレジスタが 0x7ffeeead5a00, SPレジスタが 0x7ffeeead51b0 の状態だった
・スレッドT0(メインスレッドのこと)で発生
・1バイトの書き込みをしようとした時にアドレス0x619000000580が違反した事を検知した
・test62.cpp の 11行目から呼び出された memset で発生(※コンパイラが自動的に memsetの代わりに __asan_memset を呼び出す処理に書き換えていた)
・アドレス 0x619000000580 は、0x619000000580 から始まる 1024バイトの領域の先頭である。
・test62.cppの8行目で スレッドT0によって解放済
・test62.cppの6行目で 以前はスレッドT0によって確保されていた。
【SUMMARY 以降】
・違反になったアドレスより前の領域は確保されていないヒープ領域(fa)
・違反になったアドレス以降は解放済みのヒープ領域(fd)
【ログから推測できる不具合の内容】
・free されたあとにアクセスしないようにシーケンスを制御し忘れている(アドレス変数をNULLに設定忘れとか。フラグ変更忘れとか。)
参考)上記のログを発生させたソースコード
#include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { // ヒープ確保 char *ptr = new char[1024]; // ヒープ解放 delete [] ptr; // 解放したアドレスに対する操作 memset(ptr, 0, 1); return 0; }
参考)コンパイル・実行例
$ clang++ -g -O0 -o test62 -fsanitize=address test62.cpp $ ./test62
とてもわかりやすいです.
助かりました.ありがとうございます.