Unityで作ったWindowsアプリのクラッシュ原因を調査する
概要
こんにちは、ambr, Inc.でクライアントエンジニアをしているサックーです。
この記事はambr, Inc. Advent Calendar 2024 12日目の記事です。
今回はUnityのIL2CPPで作ったWindowsアプリがクラッシュした原因を調査していく方法を紹介します。
先日、エディタでは発生せずにビルドでのみ発生するクラッシュがありました。
さらに、仕込んでいるログ出しでも原因を特定できませんでした。
そこでクラッシュ時に生成されるdmpファイルを解析していきます。
準備
ビルド時の設定
Build SettingsにあるCopy PDB files
にチェックを入れてビルドします。
Development build
じゃなくて大丈夫です。
この状態でビルドすると、dllに対応したpdbファイルが含まれていることがわかります。
実践
dmpを見つける
まずは先ほどビルドしたものでクラッシュを発生させます。
するとC:\Users\【ユーザー名】\AppData\Local\Temp\【Company Name】\【Product Name】\Crashes
にクラッシュレポートが生成されているはずです。
クラッシュタイミングごとにフォルダ分けされていて、その中にdmpファイルがあります。
WinDbgを使っていく
WinDbgのインストール
dmpファイルを解析するツールとしてWinDbgをインストールしておきます。
パスの設定
先ほどインストールしたWinDbgを開き、pdbファイルへパスの設定をします。
今回の使い方だとビルドごとに設定する必要があります。
File > Settings > Debugging settings > Default symbol path
に行き、使用したビルド(=dllとpdbファイルがある)のフォルダを指定してください。
dmpファイルを解析する
メインの画面に戻り、ワークスペース?にdmpファイルをD&Dすると読み込んでくれます。
Path validation summary
がOKであればpdbファイルがちゃんと読み込まれていると思われます。
下の方に!analyze -v
を実行せよとあり、それをクリックすると実行してくれます。
真ん中くらいに発生した例外の情報があります。
今回はAccess violation
、メモリアクセス違反のようです。
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 00007ffc93372c1e (GameAssembly!U3CLoadImageAndOptimizeAsyncU3Ed__2_MoveNext_m96E89B2FAEEBE20E4FBCDFB489B9673973C0D1C5+0x000000000000059e)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000001
Parameter[1]: 00000168f367a7d4
さらに下の方に、クラッシュが起きた該当部分の情報があります。
今回はRawTextureUtil.cpp
の1580行目のようでした。
FAULTING_SOURCE_FILE: C:\actions-runner\_work\xambr-unity\xambr-unity\Unity\Library\Bee\artifacts\WinPlayerBuildProgram\il2cppOutput\cpp\RawTextureUtil.cpp
FAULTING_SOURCE_LINE_NUMBER: 1580
これはUnityがビルド時に生成したcppファイルであり、ビルドしたマシンの該当パスに残っています。
cppファイルを見る
実際に該当ファイルを見てみると以下の部分でした。
なんと元のcsファイルの該当行をコメントで残してくれているので、RawTextureUtil.cs
の144行目であるということが分かりました。
処理内容から元のcsコードを推測する必要があると思っていたので、うれしい誤算でしたね。
そしてcsファイルの該当箇所を確認したところ、今回はNativeArray
への書き込み時に書き込み先が消えてしまっていたのが原因だと特定できました!
まとめ
このようにして、クラッシュの原因をdmpファイルの解析で特定できました。
不具合に対抗する手段が増えたので良かったです。
似たような問題に悩んでいる方の助けになれば幸いです…!
Discussion