ユニバーサル Windows プラットフォーム: IL2CPP スクリプティングバックエンドのプラグイン
FAQ

ユニバーサル Windows プラットフォーム: IL2CPP スクリプティングバックエンドのデバッグ

Debugging C# code

To debug C# code with IL2CPP, enable Script Debugging in the Build Settings before building the Project, and enable the InternetClient, InternetClientServer and PrivateNetworkClientServer capabilities in the Player settings or the manifest. The manifest is not overwrriten when you build on top of a previous build, so if you want to change the capabilities, you need to do it from Visual Studio manifest editor.

The debugging procedure is the same as any other Unity platform. For more information, see Debugging C# code in Unity.

Debugging generated C++ code

In addition to debugging C# code, you can debug generated C++ code using Visual Studio.

生成された C++ コードのクラスとメソッドの名前

IL2CPP のクラスは <ClassName>_t#number のようになります。<ClassName> はクラスの名前で、#number は一意の型番号になります。 #number はいくつかの基本的な型にはありません。以下はその例です。

String_t
Object_t
Type_t
Char_t34
StringBuilder_t26
GuidParser_t1539

IL2CPP のメソッドは <ClassName>_<MethodName>_m#number のようになります。<ClassName> はメソッドの宣言型のクラス名、<MethodName> はメソッド名、#number は一意のメソッド番号です。以下はその例です。

GuidParser_ParseHex_m10003
ConfigurationSection_DoDeserializeSection_m1275
String_Format_m4102
Mathf_Sqrt_m289
Thing_Start_m1

static フィールド構造体は <ClassName>_t#number_StaticFields のようになります。構造名の最初の部分は宣言型と同じです。以下はその例です。

StringBuilder_t26_StaticFields
Thing_t24_StaticFields

また、それぞれのクラス/メソッドの定義の上に完全なクラス/メソッド名が C++ のコメントとして付加されています。以下はその例です。

// System.String
struct String_t : public Object_t
{
    // System.Int32 System.String::length
    int32_t _length_0;
    // System.Char System.String::start_char
    uint16_t _start_char_1;
};

// System.Text.StringBuilder
struct StringBuilder_t26  : public Object_t
{
    // System.Int32 System.Text.StringBuilder::_length
    int32_t length_1;
    // System.String System.Text.StringBuilder::_str
    String_t* str_2;
    // System.String System.Text.StringBuilder::_cached_str
    String_t* cached_str_3;
    // System.Int32 System.Text.StringBuilder::_maxCapacity
    int32_t maxCapacity_4;
};

// System.Void MyData::.ctor()
extern "C" void MyData_ctor_m0 (MyData_t2 * this, const MethodInfo* method)
{
    ...
}

// Thing
struct Thing_t24 : public MonoBehaviour_t25
{
    // MyData Thing::m_Data
    MyData_t2 * _m_Data_2;
    // System.Text.StringBuilder Thing::m_Builder
    StringBuilder_t26 * _m_Builder_3;
};
struct Thing_t24_StaticFields
{
    // System.Int32 Thing::s_SomeStaticField
    int32_t _s_SomeStaticField_4;
};

変数の値を監視する

デバッグでは、さまざまな変数の値を監視することがとても重要です。 Visual Studio では、変数をマウスオーバーするか、ウォッチウインドウに変数を追加することで、比較的簡単に確認ができます。

静的なフィールドを監視するのは少し難しくなります。IL2CPPでは、静的フィールドは Il2CppClass インスタンス自体に格納されます。したがって、静的フィールドを監視するためには、まずその型の Il2CppClass 構造体へのポインターが必要です。これらのポインターは、それらを使用するメソッドのスコープ内にありますが、一回それを観察した後は、アプリケーション実行の間、同じメモリアドレスにとどまります。Il2CppClass 構造体は、“static_fields” フィールドを持っています。“static_fields” フィールドは、その特定の型の静的フィールドを含むメモリブロックへのポインターです。 実際の値を表示するには、このポインターを各型がそれぞれ持つ適切な静的フィールド構造体にキャストする必要があります。 以下の例は、クラス Thing_t24 の静的フィールドを監視しています。

例外の検証

IL2CPP では、ネイティブ C++ 例外を使用し、.NET 例外を実装します。例外を発生させる必要があるとき、IL2CPP は Il2CppExceptionWrapper オブジェクトを投げます。それは、以下のように定義されます。

struct Il2CppExceptionWrapper
{
    Il2CppException* ex;

    Il2CppExceptionWrapper (Il2CppException* ex) : ex (ex) {}
};

これらの例外オブジェクトは、簡単に Watch ウィンドウで確認できます。

最後に、例外処理でデバッガーのブレークを設けておくと便利です。そうすると、例外のソースを、その場で捕らえることができます。そのためには、Visual Studio で CTRL+ALT+E を押し、開いたウィンドウで、C++ Exceptions のチェックボックスがチェックされているのを確認します。

設定が終了すると、Visual Studio は例外が発生するといつでも、自動的に実行を止めます。


ユニバーサル Windows プラットフォーム: IL2CPP スクリプティングバックエンドのプラグイン
FAQ