Xcode
iOS
Unity

UnityからIL2CPPビルドしたXcodeプロジェクトにブレイクポイントを貼ってデバッグしたい

More than 1 year has passed since last update.

◆準備

まずは空っぽのプロジェクトを作り、CanvasとButtonを追加してQiitaというシーンを作る。

QiitaTest.csという簡単なクラスを作成して、クリックしたらbool値を変えるだけのメソッドと
Startに使わない初期化を追加。

QiitaTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class QiitaTest : MonoBehaviour {

    // Use this for initialization
    void Start () {
        bool isTest = false;
        int i = 0;
        long j = 0;
        float k = 0.1f;
        double l = 0.2d;
        string str1 = "a";
        string str2 = "あ";
        string str3 = "亜";

    }

    // Update is called once per frame
    void Update () {

    }

    /// <summary>
    /// ボタンクリック
    /// </summary>
    public void OnClick()
    {
        bool testFlg = false;

        testFlg = true;

        Debug.Log("testFlg=" + testFlg.ToString());
    }
}

QiitaTest.csをCanvasにアタッチしておいて、ButtonのClickイベントによってOnClickメソッドが呼ばれるようにしておく。

こんな感じ
スクリーンショット 2017-12-16 13.39.51.png

◆ビルド

バンドルID等はよしなにしてもらって、メニュバーのFile->Build Settrings にて
シーンの追加、「Run in Xcode as」をDebugビルドにする、Development Build にチェック

いよいよBuildボタンをクリック

スクリーンショット 2017-12-16 13.53.32.png

◆Xcode

 
 Xcodeを開く-->該当の場所を探す。どうやって??

 ビルドされたものは、Unity-iPhone --> Classes --> Unity --> Native の中にあります。

 だけど、下図のように意味不明な*.cppクラスが多くて探せません。
スクリーンショット 2017-12-16 14.03.30.png

そんな時はクラス名でgrepしましょう。(Mac苦手なんでもっと良い方法あったら教えて)
Command+Shift+F --> "QiitaTest" と入力

おおーたくさんヒットしましたよー!!
スクリーンショット 2017-12-16 14.19.15.png

この中から、Bulk_Assembly-CSharp_0.cpp の// System.Void QiitaTest::Start()のあたりを
見てみましょう。

元クラスに近いものが展開されていますね。

// System.Void QiitaTest::Start()
extern "C"  void QiitaTest_Start_m2584326649 (QiitaTest_t4127663154 * __this, const MethodInfo* method)
{
    static bool s_Il2CppMethodInitialized;
    if (!s_Il2CppMethodInitialized)
    {
        il2cpp_codegen_initialize_method (QiitaTest_Start_m2584326649_MetadataUsageId);
        s_Il2CppMethodInitialized = true;
    }
    bool V_0 = false;
    int32_t V_1 = 0;
    int64_t V_2 = 0;
    float V_3 = 0.0f;
    double V_4 = 0.0;
    String_t* V_5 = NULL;
    String_t* V_6 = NULL;
    String_t* V_7 = NULL;
    {
        // bool isTest = false;
        V_0 = (bool)0;
        // int i = 0;
        V_1 = 0;
        // long j = 0;
        V_2 = (((int64_t)((int64_t)0)));
        // float k = 0.1f;
        V_3 = (0.1f);
        // double l = 0.2d;
        V_4 = (0.2);
        // string str1 = "a";
        V_5 = _stringLiteral372029373;
        // string str2 = "あ";
        V_6 = _stringLiteral372017120;
        // string str3 = "亜";
        V_7 = _stringLiteral372047154;
        // }
        return;
    }
}

そしてその下の方にある、 // System.Void QiitaTest::OnClick() 見てみましょう。

おおー、1行のデバッグログの為に5行分必要ですね。

// System.Void QiitaTest::OnClick()
extern "C"  void QiitaTest_OnClick_m3510876654 (QiitaTest_t4127663154 * __this, const MethodInfo* method)
{
    static bool s_Il2CppMethodInitialized;
    if (!s_Il2CppMethodInitialized)
    {
        il2cpp_codegen_initialize_method (QiitaTest_OnClick_m3510876654_MetadataUsageId);
        s_Il2CppMethodInitialized = true;
    }
    bool V_0 = false;
    {
        // bool testFlg = false;
        V_0 = (bool)0;
        // testFlg = true;
        V_0 = (bool)1;
        // Debug.Log("testFlg=" + testFlg.ToString());
        // Debug.Log("testFlg=" + testFlg.ToString());
        String_t* L_0 = Boolean_ToString_m1253164328((&V_0), /*hidden argument*/NULL);
        IL2CPP_RUNTIME_CLASS_INIT(String_t_il2cpp_TypeInfo_var);
        String_t* L_1 = String_Concat_m2596409543(NULL /*static, unused*/, _stringLiteral115563068, L_0, /*hidden argument*/NULL);
        // Debug.Log("testFlg=" + testFlg.ToString());
        IL2CPP_RUNTIME_CLASS_INIT(Debug_t1368543263_il2cpp_TypeInfo_var);
        Debug_Log_m920475918(NULL /*static, unused*/, L_1, /*hidden argument*/NULL);
        // }
        return;
    }
}

◆デバッグ
 実際にブレークポイントが止まるのか?というのが問題です。

 実機を繋いでRUNしてみましょう。

まずはスタート側
止まりました、V_XX のあたりをみると C言語系の挙動が見えます
マネージドな言語と違って変数は初期値を入れるまでは初期化されません。

スクリーンショット 2017-12-16 14.35.36.png

では、return されるところまでステップオーバーしてみましょう。
V_3とV_4の最後の1が怖いですね(有効桁数の匂いがします。)
スクリーンショット 2017-12-16 14.37.59.png

V_5〜V_7の値はアドレスのようなきがするので、watchエリアに指定の変数で▶︎を開いて確認。
もし詳細を確認したければ、指定の変数で右クリックしてメモリアドレスを確認しましょう。
スクリーンショット 2017-12-16 14.49.28.png

スクリーンショット 2017-12-16 14.52.45.png


 次にクリックイベントにブレークポイントを貼って確認してみましょう。
 止まりましたね

スクリーンショット 2017-12-16 14.56.47.png

では次にリターンまで進めて更新されるか見てみましょう。
ちゃんと更新されてTrueになりました。

スクリーンショット 2017-12-16 15.00.42.png

◆開発環境 

 Unity5.6.3p1
 Xcode9.1

◆今後

 ・UnityObjectの中身はどのようになっているのか?
 ・クラスのList、Dictionaryも追ってみたい。
 ・アセットバンドルや購入したアセットもこんな感じで終えるか試したい(よく落ちるので)