使用调试器

本页详细介绍了如何使用 LLDB 进行操作系统开发。对于应用开发,请参阅调试您的应用,其中介绍了如何使用 Android Studio GUI(基于 LLDB)。

GDB 不再受支持或提供。如果您从 GDB 切换到 LLDB,您应该首先阅读 LLDB 教程。如果您是 GDB 专家用户,那么 GDB 到 LLDB 命令映射 在过渡期间非常有用。

前提条件

使用调试程序

  • 使用常用的 envsetup.sh 命令设置构建环境。
  • 运行构建时使用的相同 lunch 命令。请注意,lunch 项应与您调试的设备完全匹配。如果 lunch 项与连接的设备不匹配,您将收到如下错误信息:You used the wrong lunch: TARGET_PRODUCT (aosp_arm64) does not match attached device (xyzabc)
  • 将您的设备连接到计算机。

如需有关设置环境的更多帮助,请参阅设置环境

调试二进制文件

要调试在您的机器上构建的二进制文件,首先您必须将二进制文件复制到设备,然后启动调试程序。例如

adb push test.exe /data/local/tmp/test.exe
lldbclient.py --port 5038 -r /data/local/tmp/test.exe

调试正在运行的应用或进程

要连接到正在运行的应用或原生守护程序,请将 lldbclient.py 与 PID 一起使用。例如,要调试 PID 为 1234 的进程,请在主机上运行以下命令

lldbclient.py -p 1234

该脚本设置端口转发,在设备上启动适当的远程调试存根,在主机上启动调试程序,配置它以查找符号,并将其连接到远程调试存根。

调试原生进程启动

要在进程启动时对其进行调试,请将 lldbclient.py-r 选项一起使用。例如,要调试 ls /bin,请在主机上运行以下命令

lldbclient.py -r /system/bin/ls /bin

然后,在调试程序的提示符下输入 continue

调试应用启动

有时您想在应用启动时对其进行调试,例如当发生崩溃并且您想单步调试代码以查看崩溃之前发生了什么时。附加在某些情况下有效,但在其他情况下则不可能,因为应用在您可以附加之前崩溃。logwrapper 方法(用于 strace)并不总是有效,因为应用可能没有权限打开端口,并且 lldbserver 继承了该限制。

要调试应用启动,请使用“设置”中的开发者选项来指示应用等待 Java 调试程序附加

  1. 转到设置 > 开发者选项 > 选择调试应用,然后从列表中选择您的应用,再点击等待调试程序
  2. 启动应用,可以从启动器启动,也可以使用命令行运行
    adb shell am start -a android.intent.action.MAIN -n APP_NAME/.APP_ACTIVITY
    
  3. 等待应用加载,并出现一个对话框,告知您应用正在等待调试程序。
  4. 正常附加 lldbserver/lldbclient,设置断点,然后继续进程。

要让应用运行,请附加 Java 调试线协议 (JDWP) 调试程序,例如 Java 调试器 (jdb)

adb forward tcp:12345 jdwp:XXX  # (Where XXX is the PID
of the debugged process.)
jdb -attach localhost:12345

调试崩溃的应用或进程

如果您希望 debuggerd 挂起崩溃的进程,以便您可以附加调试程序,请设置相应的属性

  • Android 11 以上
    adb shell setprop debug.debuggerd.wait_for_debugger true
    
  • Android 11 及以下
    adb shell setprop debug.debuggerd.wait_for_gdb true
    
  • Android 6.0 Marshmallow 及以下
    adb shell setprop debug.db.uid 999999
    

在通常的崩溃输出的末尾,debuggerd 在 logcat 中提供复制和粘贴说明,说明如何将调试程序连接到崩溃的进程。

使用 VS Code 调试

LLDB 支持在 Visual Studio Code 上调试平台代码。您可以使用 VS Code 调试程序前端而不是 LLDB CLI 界面来控制和调试在设备上运行的原生代码。

在使用 VS Code 进行调试之前,请安装 CodeLLDB 扩展

使用 VS Code 调试代码

  1. 确保存在运行 lldbclient.pylldbclient.py 所需的所有构建工件(例如符号)。
  2. 在 VS Code 中,按 Ctrl+Shift+P 运行命令,搜索调试: 添加配置...,然后选择 LLDB。这将打开一个 launch.json 文件,并将一个新的 JSON 对象添加到列表中。
  3. 将新添加的调试程序配置替换为两行注释 - // #lldbclient-generated-begin// #lldbclient-generated-end,以便您的配置列表如下所示
    "configurations": [
        // #lldbclient-generated-begin
        // #lldbclient-generated-end
    ]

    lldbclient.py 使用这些注释来检测在哪里写入配置。如果列表中还有其他项,请在其他配置之后的末尾添加注释行。

  4. 在您运行 envsetup.shlunch 的终端中运行以下命令
    lldbclient.py --setup-forwarding vscode-lldb \
          --vscode-launch-file LAUNCH_JSON_PATH \
          ANY_OTHER_FLAGS -p pid | -n proc-name | -r ...

    lldbclient.py 将生成的配置写入 launch.json 并继续运行。这是预期行为;不要终止 lldbclient.py 程序。如果您省略 --vscode-launch-file,该脚本将打印 JSON 代码段,您需要手动复制并粘贴到 launch.json 中。

    如果存在 -r 标志,则该标志必须是最后一个标志,因为工具解析标志的方式如此。

  5. 打开“运行和调试”侧边栏 - 新配置应出现在调试程序列表中。按“开始调试 (F5)”。调试程序应在 10 到 30 秒后连接。

    如果新配置未出现在“运行和调试”视图中,请重新加载窗口以刷新调试程序列表 - 按 Ctrl+Shift+P 并键入 reload window

  6. 调试完成后,转到运行 lldbclient.py 的终端,然后按 Enter 键结束 lldbclient.py 程序。脚本的后续运行将生成 #lldbclient-generated 注释之间的配置并替换旧内容,您无需手动删除它们。

要将自定义属性添加到生成的启动配置,您可以使用 --vscode-launch-props 标志。例如

lldbclient.py --setup-forwarding vscode-lldb \
    --vscode-launch-props \
    '{"initCommands" : ["script print(\"Hello\")"], "preLaunchTask" : "Build"}' \
    ...
示例属性将使 VS Code 在调试之前运行名为 Build 的任务,并将新的调试初始化步骤附加到脚本生成的步骤。您可以在 VS Code 文档CodeLLDB 扩展的用户手册中找到可用属性的概述。