プログラムからvalgrind(Memcheck)のV bitsとA bitsを書き換える
この記事は移行作業中です。レイアウトが崩れる場合があります。
valgrindとは、メモリに関するデバッガ。
そのツールであるMemcheckは、メモリリークや不正なアクセスを検出する。
不正なアクセスの検出のために、V bits(Valid-value bits)とA bits(Valid-address bits)が用意されている。
V bits
・Readする前に何かしらの値で初期化されているかチェックするためのデータ
・メモリやレジスタ1ビットに対して1つの論理値を用意
・何かが書き込まれたらフラグを立てる
・フラグが立っていない状態で読み込みが行われたら未初期化の不正アクセスと見做す
A bits
・Read/Writeするメモリアドレスが有効なものであるかチェックするためのデータ
・メモリアドレス1つに対して論理値を用意
・起動時に全てのデータ領域(グローバル変数)のフラグを立てる
・アロケート時にフラグを立てる
・メモリ解放時にフラグを削除
・スタックポインタレジスタが上下するたびにAビットのフラグを立てる,または削除
(スタックポインタとベースポインタの間が有効になるようにする)
・システムコールなどが発生した際に適切なフラグを設定
プログラムで表すと、V bitsは
int i;
printf("%d\n", i);
のようなコードを検出し、A bitsは
char* ptr = malloc(10);
free(ptr);
ptr = ...
のようなコードを検出する。
これらのビットは自動的に書き換えられるが、プログラムから書き換えることもできる。
valgrindをインストールし、対象のプログラムで「memcheck.h」をインクルードする。
利用可能な操作は「memcheck.h」にマクロとして定義されている。
サンプルプログラム
https://github.com/Matumo/Komono/blob/master/Sample/valgrind/memcheck.c
プログラム内で値を書き換えるには以下のマクロが使える。
ptr でポインタ、size で ptr から後ろの何バイトを対象とするか指定する。
VALGRIND_MAKE_MEM_NOACCESS(ptr, size)
メモリアドレスを無効にセット
VALGRIND_MAKE_MEM_UNDEFINED(ptr, size)
メモリアドレスを有効にセットするが,定義状態は無効にセット
VALGRIND_MAKE_MEM_DEFINED(ptr, size)
メモリアドレスと定義状態を有効にセット
VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(ptr, size)
メモリアドレスが有効なら定義状態を有効にセット?
プログラム内でチェックをしたいときは以下のマクロが使える。
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(ptr, size)
メモリのアドレスチェック
VALGRIND_CHECK_MEM_IS_DEFINED(ptr, size)
メモリのアドレスと定義済みであるかのチェック