Unity の機能を利用して、Windows でのゲームや、エディタープロセスのフォレンジックやライブのデバッグ作業を簡単に行うことができます。
まず、デバッギングに関して説明します。Unity には 2種類のデバッギングがあります。Native C++ デバッギングと C# Managed デバッギングです。IL2CPP をサポートするプラットフォームに関しては、Native デバッギングしかありません。ただし、Managed デバッギングも、エディターの高速反復の目的で使用されます。
Native デバッギングでは、連携するバイナリ ファイル (exe か dll) にシンボル (pdb ファイル) を使用できます。
Windows では、標準 .NET が管理するシンボルが pdb ファイルに保管されています。ただし、Mono を使用する際は、mdb ファイルが必要です。
Unity は、シンボル ストア http://symbolserver.unity3d.com/ を提供しています。このサーバー URL は、windbg か VS2012 以降で自動シンボル解決とダウンロードに使用できます (Microsoft のシンボル ストアに類似)。
.sympath コマンドを使用すると、簡単に windbg にシンボル ストアを加えることができます。
.sympath+ SRV*c:\\symbols-cache*http://symbolserver.unity3d.com/
細かく見てみましょう。
.sympath+
プラス (+) は既存のシンボルパスを保持し、シンボルストアを追加します。
SRV*c:\symbols-cache
*http://symbolserver.unity3d.com/
フェッチ元のシンボル ストアのパスです。
VS2010 以前のバージョンは、http サーバー シンボル ストアと互換性がないので、注意してください。 1. Tools -> Options を選択します 2. デバッギング セクションを広げ、Symbols を選択します 3. キャッシュ ディレクトリを指定します (指定されていない場合) 4. Symbol file (.pdb) location に http://symbolserver.unity3d.com/ を入力します
Live デバッギングは、デバッガーを正常作動している処理や、発生した例外の処理に接続して行います。デバッガ―が状態を把握するために、シンボルがビルド内に含まれている必要があります。前出の手順はそのためのものです。ゲームの実行ファイル名は、ゲーム名に基づいています。そのため、もし、名前の変更をした実行ファイルにアクセスできない場合、正しい pdb を見つけられない場合があることに注意してください。
Windows では、アプリケーション キャッシュが自動的に Microsoft に報告される Dr Watson/Error Reporting が Microsoft によって設定されています。ただし、Visual Studio か windbg がインストールされている場合は、かわりに、Microsoft が精通した開発者のために提供したクラッシュのデバッギングを選択できます。 インストールを簡単にするために、こちらのレジストリ ファイルをインストールしてください。
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug]
"Auto"="1"
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug]
"Auto"="1"
エディター デバッギングのちょっとしたおまけ
Unity.exe -dbgbreak
自動クラッシュ処理が設定されている場合、上記は Unity を起動して、即座にデバッガーを接続します。
Windows にはクラッシュ ダンプ ファイル (.dmp か .mdmp) を検証する機能があります。クラッシュ ダンプのタイプによって、単なるスタック情報やプロセス全体のメモリである場合もあります。内容によって、何がクラッシュの原因となったかを見るとさまざまな可能性があります。通常の場合は、少なくともスタックを検証することができます(有効なスタックである場合)。
ダンプ ファイルを検証するには、Visual Studio か windbg を通じてオプションを起動します。Visual Studio のほうが容易に使えますが、パワーに関しては、windbg よりも少し限られています。
NullReferenceException は、しばしば以下のように表示されます。
\\tmono.dll!mono_jit_runtime_invoke(_MonoMethod * method=0x242bf8b0, void * obj=0x065c3960, void ** params=0x0018cba4, MonoObject * * exc=0x0018cb8c) Line 4889 + 0xc bytes\\tC
これは、malloc のクラッシュでも mono のクラッシュでもありません。 - 以下の内、いずれかの NullReferenceException です。 * VS デバッガ―で発生した NullReferenceException * ユーザー プレイヤーでハンドルされなかったため、プレイヤーが終了する原因となった NullReferenceException
前出の例を再度見てみましょう。
\\tmono.dll!mono_jit_runtime_invoke(_MonoMethod * method=0x242bf8b0, void * obj=0x065c3960, void ** params=0x0018cba4, MonoObject * * exc=0x0018cb8c) Line 4889 + 0xc bytes\\tC
何も情報がない行は、Managed フレームです。ただし、Managed スタック情報を取得する方法があります。mono にはmono_pmip というビルトイン機能があります。これは、スタックフレームのアドレスを受領し、情報とともに char* を返します。 mono_pmip は Visual Studio のイミディエイトウィンドウで呼び出すことができます。
?(char*)mono_pmip((void*)0x1b45558c)
0x26a296c0 “ Tiles:OnPostRender () + 0x1e4 (1B4553A8 1B4555DC) [065C6BD0 - Unity Child Domain]”`
注意 この方法は、mono.dll シンボルが適切に起動されている場合にのみ有効です。
時々アプリケーションはデバッガーがアタッチしているとクラッシュしないケースがあります。もしくはリモートデバイス上でアプリケーションがクラッシュしている場合などでは、デバッガーが使用できません。そのような状況でももしダンプファイルを取得できるなら有用な情報が取得できます。簡単なやり方を見てみましょう。
注意: 以下の手順は、Windows のスタンドアロン、Windows Store Apps、(Desktop で実行している)Windows Universal Apps で動作します。