Xcodeにはデフォルトでヒープ領域(mallocやnew)のアクセスオーバーランを 検知してくれる機能があります。 ただ、一発で検知してくれません。確実に検知する方法をここでは紹介します。 例えば、以下のようなヒープ領域をオーバーランするサンプルを使います。
- (IBAction)handlerA:(id)sender { // オーバーラン char* buffer = malloc(1024); memset(buffer, 0x0, 2048); free(buffer); }
このメソッドを何回か実行すると以下のようなメッセージが表示されます。 1回ではなく何回かというところが重要です。
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するようになります。
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>
を追加しましょう。