GDB

概要

Xamarin.Android 4.10 では、_Gdb MSBuild ターゲットを使用することによる gdb の使用の部分的なサポートが導入されました。

Note

gdb のサポートには、Android NDK のインストールが必要になります。

gdb を使用する場合、次の 3 つの方法があります。

  1. 高速展開を有効にしたデバッグ ビルド
  2. 高速展開を無効にしたデバッグ ビルド
  3. リリース ビルド

問題が発生した場合は、「トラブルシューティング」セクションを参照してください。

高速展開を使用するデバッグ ビルド

高速展開を有効にし、デバッグ ビルドをビルドして展開する場合、_Gdb MSBuild ターゲットを使用して、gdb をアタッチすることができます。

まず、アプリをインストールします。 これは、IDE、またはコマンド ラインを使用して行うことができます。

$ /Library/Frameworks/Mono.framework/Commands/xbuild /t:Install *.csproj

次に、_Gdb ターゲットを実行します。 実行の最後に、次のように gdb コマンド ラインが出力されます。

$ /Library/Frameworks/Mono.framework/Commands/xbuild /t:_Gdb *.csproj
...
    Target _Gdb:
        "/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
...

_Gdb ターゲットは、AndroidManifest.xml ファイル内で宣言された任意の起動ツール アクティビティを起動します。 実行するアクティビティを明示的に指定するには、RunActivity MSBuild プロパティを使用します。 サービスとその他の Android コンストラクトの開始は、現時点ではサポートされていません。

_Gdb ターゲットは gdb-symbols ディレクトリを作成し、ターゲットの /system/lib および $APPDIR/lib ディレクトリの内容をそこにコピーします。

Note

gdb-symbols ディレクトリの内容は、展開された Android ターゲットに関連付けられており、ターゲットを変更した場合、自動的に置き換えられません (これをバグと見なします)。Android ターゲット デバイスを変更する場合は、このディレクトリを手動で削除する必要があります。

最後に、生成された gdb コマンドをコピーし、シェルで実行します。

$ "/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
GNU gdb (GDB) 7.3.1-gg2
...
(gdb) bt
#0  0x40082e84 in nanosleep () from /Users/jon/Development/Projects/Scratch.HelloXamarin20/gdb-symbols/libc.so
#1  0x4008ffe6 in sleep () from /Users/jon/Development/Projects/Scratch.HelloXamarin20/gdb-symbols/libc.so
#2  0x74e46240 in ?? ()
#3  0x74e46240 in ?? ()
(gdb) c

高速展開を使用しないデバッグ ビルド

高速展開を使用するデバッグ ビルドは、Android NDK の gdbserver プログラムを高速展開の .__override__ ディレクトリにコピーすることで機能します。 高速展開を無効にした場合、このディレクトリが存在しない可能性があります。

次の 2 つの回避策があります。

  • .__override__ ディレクトリが作成されるように、debug.mono.log システム プロパティを設定します。
  • .apk 内に gdbserver を含めます。

debug.mono.log システム プロパティの設定

debug.mono.log システム プロパティを設定するには、adb コマンドを使用します。

$ adb shell setprop debug.mono.log gc

システム プロパティが設定されたら、高速展開を使用するデバッグ ビルド構成の場合と同じように、_Gdb ターゲットと出力された gdb コマンドを実行します。

$ /Library/Frameworks/Mono.framework/Commands/xbuild /t:_Gdb *.csproj
  ...
    Target _Gdb:
        "/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
  ...
$ "/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
GNU gdb (GDB) 7.3.1-gg2
...
(gdb) c

アプリに gdbserver を含める

アプリ内に gdbserver を含めるには、次のようにします。

  1. Android NDK 内で gdbserver ($ANDROID_NDK_PATH/prebuilt/android-arm/gdbserver/gdbserver にあります) を見つけ、それを Project ディレクトリにコピーします。

  2. gdbserver の名前を libs/armeabi-v7a/libgdbserver.so に変更します。

  3. AndroidNativeLibraryビルド アクションを使用して、Project に libs/armeabi-v7a/libgdbserver.so を追加します。

  4. アプリケーションをリビルドし、再インストールします。

アプリが再インストールされたら、高速展開を使用するデバッグ ビルド構成の場合と同じように、_Gdb ターゲットと出力された gdb コマンドを実行します。

$ /Library/Frameworks/Mono.framework/Commands/xbuild /t:_Gdb *.csproj
  ...
    Target _Gdb:
        "/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
  ...
$ "/opt/android/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gdb" -x "/Users/jon/Development/Projects/Scratch.HelloXamarin20//gdb-symbols/gdb.env"
GNU gdb (GDB) 7.3.1-gg2
...
(gdb) c

リリース ビルド

gdb のサポートには次の 3 つが必要になります。

  1. INTERNET アクセス許可。
  2. 有効なアプリ デバッグ。
  3. アクセス可能な gdbserver

アプリ デバッグでは INTERNET アクセス許可は既定で有効になります。 アプリケーションにまだ存在しない場合は、Properties/AndroidManifest.xml を編集するか、[プロジェクトのプロパティ] を編集して追加することができます。

アプリ デバッグは、ApplicationAttribute.Debugging カスタム属性プロパティを true に設定するか、次のように Properties/AndroidManifest.xml を編集して //application/@android:debuggable 属性を true に設定することで有効にすることできます。

<application android:label="Example.Name.Here" android:debuggable="true">

アクセス可能な gdbserver は、「高速展開を使用しないデバッグ ビルド」セクションに従って指定できます。

問題: _Gdb MSBuild ターゲットは既に実行されているアプリ インスタンスをすべて強制終了します。 Android v4.0 より前のバージョンのターゲットではこのようなことはありません。

トラブルシューティング

mono_pmip が機能しない

mono_pmip 関数 (マネージド スタック フレームを取得する場合に役立つ) が (現在、_Gdb ターゲットがプルダウンしていない) libmonosgen-2.0.so からエクスポートされます (この問題は今後のリリースで修正される予定です)。

libmonosgen-2.0.so にある関数の呼び出しを有効にするには、次のようにターゲット デバイスから gdb-symbols ディレクトリにコピーします。

$ adb pull /data/data/Mono.Android.DebugRuntime/lib/libmonosgen-2.0.so Project/gdb-symbols

次に、デバッグ セッションを再開します。

gdb コマンドの実行時のバス エラー: 10

gdb コマンドが "Bus error: 10" のエラーで終了した場合は、Android デバイスを再起動します。

$ "/path/to/arm-linux-androideabi-gdb" -x "Project/gdb-symbols/gdb.env"
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
...
Bus error: 10
$

アタッチ後のスタック トレースがない

$ "/path/to/arm-linux-androideabi-gdb" -x "Project/gdb-symbols/gdb.env"
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
...
(gdb) bt
No stack.

これは通常、gdb-symbols ディレクトリの内容が Android ターゲットと同期されていないことを示しています (Android ターゲットを変更しましたか?)。

gdb-symbols ディレクトリを削除して、再試行してください。