调试原生代码¶
目录¶
在 Android Studio 中调试原生代码。¶
如果您想处理为 GeckoView 提供动力的 C++ 代码,您需要能够在 Android Studio 中执行原生调试。本文将指导您完成操作方法。
如果您需要首次设置 GeckoView,请遵循快速入门指南。
执行 Gecko 的调试构建。¶
编辑您的
mozconfig
文件并添加以下行。这将确保构建包含调试检查和符号。
ac_add_options --enable-debug
如果存在,请确保在您的
mozconfig
文件中注释掉以下行。./mach configure
在生成调试构建时不允许启用工件构建。
# ac_add_options --enable-artifact-builds
为了绝对确保 Android Studio 将拾取您的调试符号,第一次执行调试构建时,最好清除您的
MOZ_OBJDIR
。后续构建不需要此步骤。
./mach clobber
照常构建。因为这是一个调试构建,并且因为您已清除
MOZ_OBJDIR
,所以这将花费很长时间。后续构建将是增量的并且花费更少的时间,所以给自己倒一杯您最喜欢的饮料。
./mach build
设置 lldb 以查找您的符号¶
编辑您的~/.lldbinit
文件(如果不存在则创建一个)并添加以下行。
第一行告诉 LLDB 启用内联断点 - 如果您想使用可视化断点,Android Studio 将需要此功能。
下一行告诉 LLDB 在哪里查找用于调试的符号。
settings set target.inline-breakpoint-strategy always
settings append target.exec-search-paths <PATH>/objdir-android-opt/dist/bin
设置 Android Studio 以执行原生调试。¶
通过单击
Run -> Edit Configurations...
并从结果窗口左侧的选项中选择正确的配置来编辑您要调试的配置。选择
Debugger
选项卡。从
Debug type
选择框中选择Dual
。Dual 允许在同一会话中调试原生代码和 Java 代码。可以使用Native
,但它仅允许调试原生代码,并且通常需要中断配置 Gecko 和子进程的 Java 代码才能在正确的时间附加调试器。在
Symbol Directories
下,添加一个指向<PATH>/objdir-android-opt/dist/bin
的新路径,该路径与您输入.lldbinit
文件中的路径相同。选择
Apply
和OK
关闭窗口。
在 Android Studio 中调试原生代码¶
第一次为您的应用程序运行调试会话时,最好从完全干净的构建开始。单击
Build -> Rebuild Project
以清理和重建。您也可以选择从您的模拟器中删除任何现有的构建以确保完全安全,但这可能不是必需的。如果使用 Android Studio 可视化断点,请在您的原生代码中设置断点。
照常以调试模式运行应用程序。
调试 Fennec 或 geckoview_example 时,您几乎会立即在
ElfLoader.cpp
中遇到断点。这是预期的。如果您不使用 Android Studio 可视化断点,则可以在此断点命中后使用现在可用的 lldb 控制台设置断点。要设置断点,请从调试窗口中选择应用程序选项卡(如果运行 Dual,还会有一个<app> java
选项卡),然后选择lldb
控制台选项卡。在控制台中输入以下内容
b <file>.cpp:<line number>
设置断点后,单击继续执行按钮以移至
ElfLoader
断点之外,并且应命中您新设置的原生断点。照常调试。
将调试器附加到内容和其他子进程¶
在内部,GeckoView 具有多进程架构。主要的 Gecko 进程位于主 Android 进程中,但内容渲染和其他一些功能位于子进程中。这平衡了负载,确保了某些关键的安全属性,并允许 GeckoView 在内容进程无响应或崩溃时恢复。但是,调试子进程通常很复杂,因为它们会不断出现和消失。
通常的方法是在您要调试的子进程中的 Java 代码启动时等待 Java 调试器,然后从 Android Studio UI 手动连接此类 Java 调试器。
Bug 1522318 添加了使 GeckoView 等待 Java 调试器附加的环境变量,使此调试过程对开发人员更加友好。有关如何设置配置 GeckoView 运行时环境的环境变量的说明,请参阅配置 GeckoView 以进行自动化。
使进程等待 Java 调试器¶
set-debug-app
命令将使 Android 在运行应用程序或服务之前等待调试器。例如,要使 GeckoViewExample 等待,请运行以下命令
adb shell am set-debug-app -w --persistent org.mozilla.geckoview_example
上述命令也适用于子进程,例如,要使 GPU 进程等待调试器,请运行
adb shell am set-debug-app -w --persistent org.mozilla.geckoview_example:gpu
将 Java 调试器附加到等待的子进程¶
这是标准操作:遵循Android Studio 说明。您必须附加 Java 调试器,因此您几乎肯定需要附加Dual
调试器,并且绝对不能仅附加Native
调试器。
确定要附加到的正确进程有点棘手,因为进程 ID (pid) 到进程名称的映射并不总是很清楚。Gecko 内容子进程此时后缀为:tab
。
如果将Dual
调试器附加到主进程和内容子进程,您将有四个 (4!) 个调试选项卡需要在 Android Studio 中管理,这很麻烦。Android Studio 似乎没有以与配置连接到已启动的运行配置的调试器相同的方式配置附加的调试器,因此您可能需要手动配置搜索路径 - 即,您可能需要在相应的lldb
控制台中手动调用lldbinit
文件的内容,使用类似command source /absolute/path/to/topobjdir/lldbinit
的调用。
Android Studio 似乎也不支持从 UI(例如,从点击代码行号处的间隙)将断点定位到特定的调试选项卡,因此您可能还需要在相应的lldb
控制台中手动设置断点。
管理更多调试选项卡可能需要不同的方法。
调试原生内存分配¶
Android Studio 包含一个原生内存分析器,该分析器适用于运行 Android 10 及更高版本的物理设备。为了正确跟踪分配,必须禁用jemalloc
构建 Gecko。此外,原生内存分析器似乎仅适用于aarch64
构建。因此,您的mozconfig
文件中必须存在以下内容
ac_add_options --target=aarch64
ac_add_options --disable-jemalloc
在调试构建中,生成的配置文件符号化正确,但是,您可能更喜欢在分析时使用发布构建。不幸的是,尚未找到使用开发机器上的本地符号进行符号化的方法,因此为了使配置文件符号化,您必须防止在构建过程中剥离符号。为此,请将以下内容添加到您的mozconfig
中
ac_add_options STRIP_FLAGS=--strip-debug
并将以下内容添加到mobile/android/geckoview/build.gradle
中,以及如果分析 GeckoView 示例,则添加到mobile/android/geckoview_example/build.gradle
中,或者如果分析 Fenix,则添加到app/build.gradle
中,例如。
android {
packagingOptions {
doNotStrip "**/*.so"
}
}
在 Windows 上使用 Android Studio¶
您现在可以在MozillaBuild 环境上使用工件构建模式,即使您没有使用 WSL。如果您想在 Windows 上使用 Android Studio 调试 GeckoView,则必须通过控制面板设置一个额外的环境变量来运行 gradle 脚本。mach
命令会自动设置这些变量,但 Android Studio 无法设置。
如果您将 MozillaBuild 工具安装到C:\mozilla-build
(默认安装路径),则必须设置MOZILLABUILD
环境变量以识别 MozillaBuild 安装路径。
要在 Windows 10 上设置环境变量,请从Windows System
打开Control Panel
,然后选择System and Security
- System
- Advanced system settings
- Environment Variables ...
。
要设置MOZILLABUILD
变量,在User variables for
中点击New...
,然后将Variable name:
设置为MOZILLABUILD
,Variable value:
设置为C:\mozilla-build
。
您还需要将一些工具路径添加到Path
环境变量中。
要将变量添加到PATH,在User Variables for
中双击Path
,然后点击New
。并将以下变量添加到Path
中。
%MOZILLABUILD%\msys\bin
%MOZILLABUILD%\bin