ずっとデバッグビルドで開発をしていて、古いデバイスでちょっと時間のかかってしまう処理を何とかしないといけなくなったのだけど、リリースビルドにしたらどれくらい時間がかかるのか試しにビルドしたらEXC_ARM_BREAKPOINTでクラッシュするようになってしまった。
Xcode 6.1を使っていて、クラッシュするのはarmv7のデバイスのみ。しかも最適化レベルをO2以上にしたときだけクラッシュする。
止まるのはif文の後が多く、アセンブリにしたコードを見てみるとブランチ命令の後に”trap”という命令が挿入されていて、どうもそこで止まっているみたい。

trapが挿入されているところを調べてみると、ほとんどがtbb命令の前。tbbって知らなかったのだけど、調べてみたらテーブルブランチとのこと。つまり、条件文をジャンプテーブルで最適化しているようだ。
つまり上のアセンブリのコードは

ということを意味している。もちろん自分ではこんなコードは書いてなくて、コンパイラが勝手に最適化して勝手にassertを仕込んで、勝手にassertにひっかかっているのである。それに最適化を切れば普通に動いているわけで、まあ十中八九コンパイラのバグだと思うわけです。
だいたい、最適化されたコード(fastest, smallest)のはずなのにassertが挿入されるってどういうことよ。このコンパイラはまだ開発中で自信がないからassertを入れてるということでしょうか?
でもまあ実際にバグがあるわけで、バグでおかしな挙動をしたり別の場所でクラッシュするよりは、最適化の失敗の場所がわかるところでクラッシュしてくれた方がありがたいのではあるんだけどね。

調べてみるとXcode 6.3 betaがあるので、それでもテストをしてみた(わざわざOSをYosemiteにアップデートまでして)。
すると上の箇所ではクラッシュしなかったものの、他の場所でクラッシュしてた。そのケースではtbbは使ってなかったけど、やはりブランチ命令の後にtrapが仕込まれていて、そこで引っかかっている。

そしてそのコードからif文を取り除いてみたところ、今度は関数の先頭のところにtrap命令が仕込まれるようになって、やはりクラッシュする。

とは言え、Xcode 6.3 betaで少し改善されたようで、クラッシュする箇所が減ったおかげで、問題のあった関数ひとつだけを別ファイルにして、そのファイルだけ最適化レベルをO1にしたら動くようになった。なのでしばらくはXcode 6.3 betaで開発することにしよう。
幸い(?)、開発は順調に遅れていてリリースまでまだしばらくかかるので、とりあえずAppleにバグレポ出して様子見。リリースまでに直ってくれてるといいなあ。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Anti Spam Code *