2013年10月28日月曜日

Fatal signal 11 (SIGSEGV) ・・・ なんだよこれ!

何の音沙汰もなくアプリが落ちる。
あまつさえ端末が再起動し始める。

こんな場合、OpenGLのBuffer問題を考慮してみるのが有効かもしれません。
WebViewを使っている時も原因は同じようですが、こちらはクラスライブラリ内部の話なので解決策はよく分かりませんが。

先ず発生条件ですが、OSでは

・GB以前は無かった。ICS以降。ICSでも初めは問題なかった。

で、端末では

・シングルコアでは見た事が無い。どうもデュアルコア以降らしい。
・ainol Novo7Fire(CM10.1)だと起動後暫くすると発生。
・SAMSUNG GalaxyTab7.7Plusだと起動直後にフリーズ。

アプリでは

・別のスレッドでOpenGLを叩いている。
・例外では何も拾えない。

となります。何が推測できるかといいますと、

どうもGPUが参照中にアクセス保護しているメモリ領域に対して、アプリ側がコンフリクトを起こしている。

という事です。

OpenGLにデータを渡すためにnioのBufferクラスを使いますが、内部で持っているネイティブのメモリアクセスに対して何もしてなさそうです。
OpenGLに渡したBuuferへのアクセスを、OpenGLを叩いているスレッドだけに絞ると、このエラーはピタッと収まりました。

こんな事がありましたので、ご参考になれば。



2014/07/16 追記

少し具体的な説明です。
OpenGLは初期化したスレッドからのみ呼び出しが可能という仕様は知られていますが、
Javaで呼ぶ場合にデータを渡すために使ったBufferクラスのインスタンスへの書き込みも該当します。
OpenGLがBufferのメモリを覗いてせっせと描画している時に、別スレッドからBufferのメモリにアクセスするとコケるという具合です。

解決策としては、メインのスレッドではBufferに直接書き込まず、更新用の情報を別に用意します。
OpenGLを叩くスレッドで、描画する前に更新内容をBufferに適用すれば問題解決です。
面倒くさいんですが、マルチコアCPUの恩恵を受けるためには致し方ありません。








0 件のコメント:

コメントを投稿