GDB

概述

Xamarin.Android 4.10 通过使用 _Gdb MSBuild 目标引入了对使用 gdb 的部分支持。

注意

gdb 支持要求安装 Android NDK。

有三种使用 gdb 的方法:

  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 目录的内容复制到那里。

注意

gdb-symbols 目录的内容绑定到你部署到的 Android 目标,如果你更改目标,则不会自动替换。 (请注意这个 bug。)如果你更改 Android 目标设备,则需要手动删除此目录。

最后,复制生成的 gdb 命令并在你的 shell 中执行它:

$ "/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__ 目录。 快速部署禁用时,此目录可能不存在。

有两种解决方法:

  • 设置 debug.mono.log 系统属性,以便创建 .__override__ 目录。
  • gdbserver 包含在你的 .apk 中。

设置 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 的“生成操作”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 支持需要三项内容:

  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 不起作用

libmonosgen-2.0.so 导出 mono_pmip 函数(用于获取托管堆栈帧),_Gdb 目标目前不会下拉。 (未来版本会修复此问题。)

要启用位于 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 目录并重试。