読者です 読者をやめる 読者になる 読者になる

Pebble's Diary

プログラマーの作業メモ

Xcodeでヒープ領域アクセスオーバーランを短時間で見つける

Xcodeにはデフォルトでヒープ領域(mallocやnew)のアクセスオーバーランを 検知してくれる機能があります。 ただ、一発で検知してくれません。確実に検知する方法をここでは紹介します。 例えば、以下のようなヒープ領域をオーバーランするサンプルを使います。

- (IBAction)handlerA:(id)sender
{
    // オーバーラン
    char* buffer = malloc(1024);
    memset(buffer, 0x0, 2048);
    free(buffer);
}

このメソッドを何回か実行すると以下のようなメッセージが表示されます。 1回ではなく何回かというところが重要です。

f:id:pebble8888:20140324213543p:plain

MemoryLeakBuster(55357,0x1f64a28) malloc: *** error for object 0xca53804: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug

これを一回実行した時に検知できるようにするには、

free(buffer);

の後ろに以下の1行を追加します。

assert( malloc_zone_check(NULL) );

この時点で全てのヒープメモリのヘルスチェックを行い、 異常がある時にassertするようになります。

f:id:pebble8888:20140324214614p:plain

MemoryLeakBuster(55372,0x1f64a28) malloc: *** invariant broken for small free 0x9277a00 followed by 0x9277e00 in region [0x9000000-0x9281a00] (end marker incorrect) should be 2; in fact 0
MemoryLeakBuster(55372,0x1f64a28) malloc: *** small region 63 incorrect szone_check_all() counter=1
*** error: check: small region incorrect
*** set a breakpoint in malloc_error_break to debug

malloc_zone_check関数がコンパイルできない場合は、

#include <malloc/malloc.h>

を追加しましょう。