開発環境 | iOS(iPhone) SDK 4.0 |
実行環境 | iOS 3.1.3 |
インターネットからJpeg画像をダウンロードして表示するアプリケーションを開発していたとき、 特定のJpeg画像を読みだしたときにiOS SDK側でEXC_BAD_ACCESSが起きて困ったことがありましたので、 解析結果と対策を書いておきます。
iOS SDK 4.0で開発したコードを古いiPodのiOS 3.1.3で動かしたときにEXC_BAD_ACCESSが起きました。
iPhone Simulatorでは起きませんでした。
Jpeg画像については依存性があり、いくつかのJpeg画像(確認した範囲では4つ)で高確率で問題が起きておりましたが、
それらのJpeg画像以外では問題は起きませんでした。
EXC_BAD_ACCESSが起きている所はコードの以下の場所でした。
UIImage *image = [UIImage imageWithContentsOfFile:@"***"];
デバッガからバックトレースを取ってみたところ、以下のようになっていました。
(gdb) bt #0 0x3407c2f4 in readCanon1DMKIICustomFunctions () #1 0x340653d4 in readProps () #2 0x34064d78 in readProps () #3 0x34064d78 in readProps () #4 0x34064910 in readTiffPropsFromData () #5 0x34064828 in readExifData () #6 0x34060fd8 in initImageJPEG () #7 0x340607bc in _CGImagePluginInitJPEG () #8 0x3404e174 in makeImagePlus () #9 0x3404dff0 in CGImageSourceCreateImageAtIndex () #10 0x331b7438 in _UIImageRefAtPath () #11 0x331b71b4 in -[UIImage initWithContentsOfFile:] () #12 0x332267f8 in +[UIImage imageWithContentsOfFile:] () #13 0x000201a8 in -[ImageFrameView layoutSubviews] () at /***/***.m:110 #14 0x331fa2d8 in -[UIView(CALayerDelegate) _layoutSublayersOfLayer:] () #15 0x324ba1c0 in -[CALayer layoutSublayers] () #16 0x324b9edc in CALayerLayoutIfNeeded () #17 0x324b9844 in CA::Context::commit_transaction () #18 0x324b9474 in CA::Transaction::commit () #19 0x324c15dc in CA::Transaction::observer_callback () #20 0x32407830 in __CFRunLoopDoObservers () #21 0x3244f346 in CFRunLoopRunSpecific () #22 0x3244ec1e in CFRunLoopRunInMode () #23 0x342e91c8 in GSEventRunModal () #24 0x331b5c30 in -[UIApplication _run] () #25 0x331b4230 in UIApplicationMain () #26 0x000029ec in main (argc=1, argv=0x2ffff5c0) at /***/main.m:14
なんぞこれ・・・という感じですが、
readExifDataの中で問題が起きていたので、念のためJpeg画像のExifデータを確認してみました。
結果、特に問題は見つかりませんでしたが、Canon EOS 7D で撮影したJpeg画像であることが分かりました。
Canonの画像特有の問題かと思い、Exif編集ソフトでCanonのMakerNoteを取り除いてみたところ、EXC_BAD_ACCESSは起きず 問題は起きなくなりました。CanonのMakerNote読み出しに関するiOS 3.1.3の不具合ではないかと思っています。
iOSアプリの方で、imageWithContentsOfFileにデータを渡す前に、Exif編集ソフトがやるようにCanonのMakeNoteを取り除く処理を追加して、 この問題を回避しました。
投稿者 MASATO : 2011年01月16日 16:22 | トラックバック