こんにちは、iOSエンジニアのいっちー(@0IcchI)です。 最近はインターン終了を迎えるなか、引越しや卒業などでバタバタしており、若かりし頃の自分が広げまくった風呂敷をやっと畳んでるような気がしてます。
...これからシェアハウスなどを始めるので、まだまだ風呂敷は広げていきます😌
本題ですが、ミラティブではアニメーション素材の表示などにSDWebImageというライブラリを利用しているのですが、そこでクラッシュが発生していました。
本記事ではそのクラッシュの解消方法と、その過程で得た学びについて紹介します。
経緯
ミラティブではクラッシュレポートツールのFirebase Crashlyticsを使って監視を行っています。 具体的にはベロシティアラートやクラッシュレートをSlackチャンネルに流したり、エンジニアが逐次不審なクラッシュの有無を確認したりしています。
今回のクラッシュはベロシティアラートとして通知が来たわけではなく、エンジニアにより不審なクラッシュとして発見されたものです。
(SDWebImageを使用している方はクラッシュを見逃していないか確認してみてください✔︎)
以前に、サーバーから受け取った大容量の画像が表示されないという事象が起きていたため、類似する事象と推測し優先度を上げて調査を行いました。
クラッシュ状況の把握
問題となっていたクラッシュのスタックトレースはこのような感じです。
見ての通りSDAnimatedImage.m - line127でクラッシュしています。
「NSAllocateMemoryPages(_:) failed」と書かれているので、メモリ割り当てに失敗したということでしょう。
このようなケースではヒープオーバーフローやメモリリークなどを疑います。 クラッシュ時の状況の把握や原因の推測もできましたが、だからと言って修正するのには時間がかかりそうです。
クラッシュ解消のためにやったこと
出来ることとして、同じ問題を抱えている人を探し対応策を真似ること、開発元にIssueとして報告することがあると思います。
僕は同じ問題を抱えている人を探しに行きました。検索ウィンドウに「クラッシュ」「クラッシュしたメソッド名」を打ち込んで検索すると見つかりやすい気がします。
今回は「crash SDAnimatedImage initWithData:scale:options:」と検索したら出てきました。
ちなみに、Issueを報告する場合はcontributing guidelinesを読んでからにしてくださいと言われています。気をつけなければ。
クラッシュの原因と対応
このIssueを見つけたことによってクラッシュの原因と解消方法が分かりました。
上記Issueによると、原因はinitWithAnimatedImageDataメソッド内で不要なデータコピーを行なっていたことにあるそう。 SDWebImage5.15.1でそれに対応する修正を入れたことで、メモリ不足によるクラッシュが解消されたようです。
つまり、SDWebImage5.15.1以降にアップデートすれば良いということですね!
アップデートした結果、クラッシュは解消されました🎉
学び
今回のクラッシュと類似したクラッシュが1ヶ月前に起こっており、その原因はサーバーから大容量の画像が送られてきたことがありました。
てっきりそれが原因だと思い込んでいたため、調査の前半はサーバーから受け取っている画像の容量の調査を行なっていました。
結果としては全く見当違いの調査に😢
この経験から、事前情報に関わらずライブラリ関係のクラッシュ調査では「同じ問題を抱えている人を探すこと」をTODOに入れておいた方が良いだろうなと思いました。
学び!
We are hiring!
ミラティブでは『好きでつながり、自分の物語(ナラティブ)が生まれる居場所』を実現するエンジニアを募集中です!
https://speakerdeck.com/hr_team/engineers-handbookspeakerdeck.com