1---
2title: Using a debugger
3description: "Guide to using a debugger for Zed development."
4---
5
6# Using a debugger
7
8> This page is not about [configuring Zed's debugger](../debugger.md).
9> It covers how to use a debugger while developing Zed itself.
10
11## Using Zed's built-in debugger
12
13While the Zed project is open you can open the `New Process Modal` and select the `Debug` tab. There you can see two debug configurations to debug Zed with, one for GDB and one for LLDB. Select the configuration you want and Zed will build and launch the binary.
14
15GDB is not supported on Apple Silicon Macs.
16
17## Release build profile considerations
18
19By default, builds using the release profile (the profile used for nightly, preview, and stable) include limited debug info.
20
21This is done by setting the `profile.(release).debug` field in the root `Cargo.toml` field to `"limited"`.
22
23The official documentation for the `debug` field is [here](https://doc.rust-lang.org/cargo/reference/profiles.html#debug).
24In short, `"limited"` strips type-level and variable-level debug info.
25
26In release builds, this reduces binary size. Type-level and variable-level debug info is not required for useful stack traces.
27
28However, this data matters when you are actively debugging. Without it, debuggers cannot resolve local variables, inspect values, or format output with pretty-printers.
29
30To get the full debugger experience on a release build, compile a Zed binary with full debug info.
31
32The simplest way is to use `--config` to override the `debug` field in the root `Cargo.toml` when running `cargo run` or `cargo build`:
33
34```sh
35cargo run --config 'profile.release.debug="full"'
36cargo build --config 'profile.release.debug="full"'
37```
38
39> If you do not want to pass `--config` on every `cargo` command, you can also change the section in the [root `Cargo.toml`](https://github.com/zed-industries/zed/blob/main/Cargo.toml)
40>
41> from
42>
43> ```toml
44> [profile.release]
45> debug = "limited"
46> ```
47>
48> to
49>
50> ```toml
51> [profile.release]
52> debug = "full"
53> ```
54>
55> This makes all invocations of `cargo run --release` or `cargo build --release` compile with full debug info.
56>
57> **Warning:** Do not commit these changes.
58
59## Running Zed with a shell debugger GDB/LLDB
60
61### Background
62
63When you install Rust through rustup (the recommended setup for Zed development; see your platform guide [here](../development.md)), rustup also installs helper scripts for debugging Rust binaries.
64
65These scripts are `rust-gdb` and `rust-lldb`.
66
67You can read more about these scripts [here](https://michaelwoerister.github.io/2015/03/27/rust-xxdb.html).
68
69They are wrapper scripts around `gdb` and `lldb` that inject commands and flags for Rust-specific features such as pretty-printers and type info.
70
71To use `rust-gdb` or `rust-lldb`, install `gdb` or `lldb` on your system.
72
73The [linked article](https://michaelwoerister.github.io/2015/03/27/rust-xxdb.html) notes that the minimum supported versions are GDB 7.7 and LLDB 310. In practice, newer versions are usually better.
74
75> **Note**: `rust-gdb` is not installed by default on Windows because `gdb` support there is unstable. Use `rust-lldb` instead.
76
77If you are new to these tools, see the `gdb` docs [here](https://www.gnu.org/software/gdb/) and the `lldb` docs [here](https://lldb.llvm.org/).
78
79### Usage with Zed
80
81After enabling full debug info and building with `cargo build`, run `rust-gdb` or `rust-lldb` against the compiled Zed binary:
82
83```
84rust-gdb target/debug/zed
85rust-lldb target/debug/zed
86```
87
88You can also attach to a running Zed process (for example, one started with `cargo run`):
89
90```
91rust-gdb -p <pid>
92rust-lldb -p <pid>
93```
94
95`<pid>` is the process ID of the Zed instance you want to attach to.
96
97To find the PID, use your system's process tools, such as Task Manager on Windows or Activity Monitor on macOS.
98
99You can also run `ps aux | grep zed` on macOS and Linux, or `Get-Process | Select-Object Id, ProcessName` in PowerShell on Windows.
100
101#### Debugging Panics and Crashes
102
103Debuggers are useful for finding the cause of panics and crashes, including in Zed.
104
105By default, when a process attached to `gdb` or `lldb` hits an exception such as a panic, the debugger stops at that point so you can inspect program state.
106
107The initial stop point is often in Rust standard library panic or exception handling code, so you usually need to walk up the stack to find the root cause.
108
109In `lldb`, use `backtrace` with `frame select`. `gdb` provides equivalent commands.
110
111After the program stops on the exception, you usually cannot continue normal execution. You can still move between stack frames and inspect variables and expressions, which is often enough to identify the crash cause.
112
113You can find additional information on debugging Zed crashes [here](./debugging-crashes.md).