使用调试器

免责声明: 这不是 Zed 中计划的调试器支持 的文档。 相反,它旨在提供关于在开发 Zed 本身时如何使用外部调试器的信息,面向 Zed 员工和外部贡献者。 一旦调试器支持被实现,本节将更新以提供关于如何使用内置调试器作为 Zed 开发一部分的信息。

构建配置注意事项

默认情况下,使用 dev 和 release 配置文件的构建(release 是用于生产构建的配置文件,即 nightly、preview 和 stable)包含有限的调试信息。

这是通过将根 Cargo.toml 文件中的 profile.(release|dev).debug 字段设置为 "limited" 来完成的。

有关 debug 字段的官方文档可以在 这里 找到。但简单的说,"limited" 会剥离类型和变量级别的调试信息。

在 release 构建中,这样做是为了减小二进制文件的大小,因为类型和变量级别的调试信息不是必需的,并且不会影响生成的堆栈跟踪的可用性。

在 debug 构建中,这样做是为了减少编译时间(尤其是增量编译时间)。

然而,虽然类型和变量级别的调试信息对于良好的堆栈跟踪不是必需的,但对于使用调试器的良好体验非常重要,因为如果没有类型和变量级别的调试信息,调试器就无法解析局部变量,检查它们,使用漂亮的打印机格式化它们等等。

因此,为了充分利用调试器,您必须编译一个新的 Zed 二进制文件,其中包含完整的调试信息。

最简单的方法是使用 --config 标志来覆盖运行 cargo runcargo build 时根 Cargo.toml 文件中的 debug 字段,如下所示

cargo run --config 'profile.dev.debug="full"'
cargo build --config 'profile.dev.debug="full"'

如果您希望避免在每次调用 cargo 时都传递 --config 标志。您也可以更改 Cargo.toml 中的部分

[profile.dev]
debug = "limited"

[profile.dev]
debug = "full"

这将确保每次调用 cargo runcargo build 都将使用完整的调试信息进行编译。

警告: 确保避免提交这些更改!

GDB/LLDB

背景

通过 rustup 安装 rust 时(在开发 Zed 时推荐这样做,请参阅 此处 有关在您的平台上开始使用的文档),会安装一些额外的脚本并将其放在您的路径上,以帮助调试用 rust 编译的二进制文件。

分别是 rust-gdbrust-lldb

如果您有兴趣,可以在 此处 阅读有关这些脚本及其用途的更多信息。

然而,总结来说,它们是简单的 shell 脚本,封装了标准的 gdblldb 命令,注入相关的命令和标志以启用额外的 rust 特定功能,例如漂亮打印机和类型信息。

因此,为了使用 rust-gdbrust-lldb,您必须在系统上安装 gdblldb。如果您没有安装它们,您需要以适合您平台的方式安装它们。

根据 之前链接的文章,“最低支持的调试器版本是 GDB 7.7 和 LLDB 310。然而,一般的规则是:越新越好。” 因此,建议尽可能安装最新版本的 gdblldb

注意:默认情况下,Windows 上不安装 rust-gdb,因为 Windows 上的 gdb 支持不是很稳定。建议在 Windows 上使用 lldbrust-lldb

如果您不熟悉 gdblldb,您可以在 这里这里 分别了解更多关于它们的信息。

与 Zed 一起使用

使用调试器运行 Zed

在按照上述步骤操作以在编译 Zed 时包含完整调试信息后,您可以在使用 cargo build 构建 Zed 二进制文件后,运行 rust-gdbrust-lldb,方法是运行以下命令之一

rust-gdb target/debug/zed
rust-lldb target/debug/zed

或者,您可以通过运行以下命令之一来附加到正在运行的 Zed 实例(例如使用 cargo run 启动的 Zed 实例)

rust-gdb -p <pid>
rust-lldb -p <pid>

其中 <pid> 是您要附加到的 Zed 实例的进程 ID。

要获取正在运行的 Zed 实例的进程 ID,您可以使用系统的进程管理工具,例如 Windows 上的 任务管理器 或 MacOS 上的 活动监视器

或者,您可以在 MacOS 和 Linux 上运行 ps aux | grep zed 命令,或者在 Windows 上的 PowerShell 实例中运行 Get-Process | Select-Object Id, ProcessName

调试 Panic 和崩溃

调试器可以成为调试所有程序(包括 Zed)中 panic 和崩溃原因的绝佳工具。

默认情况下,当 gdblldb 附加到的进程遇到异常(例如 panic)时,调试器将自动停止在 panic 点,并允许您检查程序的状态。

最有可能的是,调试器停止的点将位于 rust 标准库 panic 或异常处理代码的深处,因此您需要向上导航堆栈跟踪才能找到 panic 的实际原因。

这可以通过在 lldb 中使用 backtrace 命令结合 frame select 命令来完成,在 gdb 中也可以使用类似的命令。

一旦程序停止,您将无法像在发生异常之前那样继续执行。 但是,您可以跳转到不同的堆栈帧,并检查每个帧中变量和表达式的值,这对于识别崩溃的根本原因非常有用。

您可以在 此处 找到有关调试 Zed 崩溃的其他信息。