2010-06-17

iPhoneアプリ開発: The Debugger has exited due to signal 10 (SIGBUS).

アプリデバッグ中に、デバッガコンソール上に次のようなメッセージを残してアプリが落ちてしまうことがあります。




プログラムはシグナルを受信しました:“0”。

The Debugger has exited due to signal 10 (SIGBUS).The Debugger has exited due to signal 10 (SIGBUS).

この SIGBUS 10 エラーは、通常、解放済みのオブジェクトにアクセスすると引き起こされます。
というわけで、解決のためにはreleaseやautoreleaseされている箇所を地道にチェックしていきます。

このチェックをしてもまだエラーが解決できない場合、次のような自動解放プールが適切に設定されているかについてもチェックしてみてください。
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//do something
[pool release];
特に、
  • 短時間では発生しないが、長時間動かし続けると SIGBUS 10 エラーで落ちる
  • 別スレッド内で無限ループする処理がある
  • 無限ループの中に、自動解放プールが設定されていない
といった場合は、無限ループの中で、自動解放プールを細かい粒度で設定することで解決する可能性があります。

具体例としては、次のようにします。

before:
- (void)start {
 [NSThread detachNewThreadSelector:@selector(startThread) toTarget:self withObject:nil];
}

- (void)proccess {
 //do something
}

- (void)startThread {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 running = YES;

 while (running) {
  [self process];
  [NSThread sleepForTimeInterval:sleepingInterval];
 }
 [pool release];
}

after:
- (void)start {
 [NSThread detachNewThreadSelector:@selector(startThread) toTarget:self withObject:nil];
}

- (void)proccess {
 //do something
}

- (void)startThread {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 running = YES;

 while (running) {
  NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init]; //...(1) for fixing sigbus error
  [self process];
  [NSThread sleepForTimeInterval:sleepingInterval];
  [innerPool release]; //...(1)'
 }
 [pool release];
}
追加しているのは(1)、(1)'の箇所です。
もともとスレッド開始の最初と最後の範囲で自動解放プールを設定しているのですが、ここではさらに while ループの中で自動解放プールを設定しています。

ついでに、Private APIですが、
[NSAutoreleasePool showPools];
により自動解放プールの各階層に入ったオブジェクトの確認ができます。エラー原因究明時の参考に。

0 件のコメント: