debugger.md

  1# Debugger
  2
  3Zed uses the [Debug Adapter Protocol (DAP)](https://microsoft.github.io/debug-adapter-protocol/) to provide debugging functionality across multiple programming languages.
  4DAP is a standardized protocol that defines how debuggers, editors, and IDEs communicate with each other.
  5It allows Zed to support various debuggers without needing to implement language-specific debugging logic.
  6Zed implements the client side of the protocol, and various _debug adapters_ implement the server side.
  7
  8This protocol enables features like setting breakpoints, stepping through code, inspecting variables,
  9and more, in a consistent manner across different programming languages and runtime environments.
 10
 11> We currently offer onboarding support for users. We are eager to hear from you if you encounter any issues or have suggestions for improvement for our debugging experience.
 12> You can schedule a call via [Cal.com](https://cal.com/team/zed-research/debugger)
 13
 14## Supported Languages
 15
 16To debug code written in a specific language, Zed needs to find a debug adapter for that language. Some debug adapters are provided by Zed without additional setup, and some are provided by [language extensions](./extensions/debugger-extensions.md). The following languages currently have debug adapters available:
 17
 18<!-- keep this sorted -->
 19
 20- [C](./languages/c.md#debugging) (built-in)
 21- [C++](./languages/cpp.md#debugging) (built-in)
 22- [Go](./languages/go.md#debugging) (built-in)
 23- [JavaScript](./languages/javascript.md#debugging) (built-in)
 24- [PHP](./languages/php.md#debugging) (built-in)
 25- [Python](./languages/python.md#debugging) (built-in)
 26- [Ruby](./languages/ruby.md#debugging) (provided by extension)
 27- [Rust](./languages/rust.md#debugging) (built-in)
 28- [Swift](./languages/swift.md#debugging) (provided by extension)
 29- [TypeScript](./languages/typescript.md#debugging) (built-in)
 30
 31> If your language isn't listed, you can contribute by adding a debug adapter for it. Check out our [debugger extensions](./extensions/debugger-extensions.md) documentation for more information.
 32
 33Follow those links for language- and adapter-specific information and examples, or read on for more about Zed's general debugging features that apply to all adapters.
 34
 35## Getting Started
 36
 37For most languages, the fastest way to get started is to run {#action debugger::Start} ({#kb debugger::Start}). This opens the _new process modal_, which shows you a contextual list of preconfigured debug tasks for the current project. Debug tasks are created from tests, entry points (like a `main` function), and from other sources — consult the documentation for your language for full information about what's supported.
 38
 39You can open the same modal by clicking the "plus" button at the top right of the debug panel.
 40
 41For languages that don't provide preconfigured debug tasks (this includes C, C++, and some extension-supported languages), you can define debug configurations in the `.zed/debug.json` file in your project root. This file should be an array of configuration objects:
 42
 43```json
 44[
 45  {
 46    "adapter": "CodeLLDB",
 47    "label": "First configuration"
 48    // ...
 49  },
 50  {
 51    "adapter": "Debugpy",
 52    "label": "Second configuration"
 53    // ...
 54  }
 55]
 56```
 57
 58Check the documentation for your language for example configurations covering typical use-cases. Once you've added configurations to `.zed/debug.json`, they'll appear in the list in the new process modal.
 59
 60Zed will also load debug configurations from `.vscode/launch.json`, and show them in the new process modal if no configurations are found in `.zed/debug.json`.
 61
 62### Launching & Attaching
 63
 64Zed debugger offers two ways to debug your program; you can either _launch_ a new instance of your program or _attach_ to an existing process.
 65Which one you choose depends on what you are trying to achieve.
 66
 67When launching a new instance, Zed (and the underlying debug adapter) can often do a better job at picking up the debug information compared to attaching to an existing process, since it controls the lifetime of a whole program.
 68Running unit tests or a debug build of your application is a good use case for launching.
 69
 70Compared to launching, attaching to an existing process might seem inferior, but that's far from truth; there are cases where you cannot afford to restart your program, because for example, the bug is not reproducible outside of a production environment or some other circumstances.
 71
 72## Configuration
 73
 74While configuration fields are debug adapter-dependent, most adapters support the following fields:
 75
 76```json
 77[
 78  {
 79    // The label for the debug configuration and used to identify the debug session inside the debug panel & new process modal
 80    "label": "Example Start debugger config",
 81    // The debug adapter that Zed should use to debug the program
 82    "adapter": "Example adapter name",
 83    // Request:
 84    //  - launch: Zed will launch the program if specified or shows a debug terminal with the right configuration
 85    //  - attach: Zed will attach to a running program to debug it or when the process_id is not specified we will show a process picker (only supported for node currently)
 86    "request": "launch",
 87    // program: The program that you want to debug
 88    // This field supports path resolution with ~ or . symbols
 89    "program": "path_to_program",
 90    // cwd: defaults to the current working directory of your project ($ZED_WORKTREE_ROOT)
 91    "cwd": "$ZED_WORKTREE_ROOT"
 92  }
 93]
 94```
 95
 96All configuration fields support [task variables](./tasks.md#variables).
 97
 98### Build tasks
 99
100Zed also allows embedding a Zed task in a `build` field that is run before the debugger starts. This is useful for setting up the environment or running any necessary setup steps before the debugger starts.
101
102```json
103[
104  {
105    "label": "Build Binary",
106    "adapter": "CodeLLDB",
107    "program": "path_to_program",
108    "request": "launch",
109    "build": {
110      "command": "make",
111      "args": ["build", "-j8"]
112    }
113  }
114]
115```
116
117Build tasks can also refer to the existing tasks by unsubstituted label:
118
119```json
120[
121  {
122    "label": "Build Binary",
123    "adapter": "CodeLLDB",
124    "program": "path_to_program",
125    "request": "launch",
126    "build": "my build task" // Or "my build task for $ZED_FILE"
127  }
128]
129```
130
131### Automatic scenario creation
132
133Given a Zed task, Zed can automatically create a scenario for you. Automatic scenario creation also powers our scenario creation from gutter.
134Automatic scenario creation is currently supported for Rust, Go, Python, JavaScript, and TypeScript.
135
136## Breakpoints
137
138To set a breakpoint, simply click next to the line number in the editor gutter.
139Breakpoints can be tweaked depending on your needs; to access additional options of a given breakpoint, right-click on the breakpoint icon in the gutter and select the desired option.
140At present, you can:
141
142- Add a log to a breakpoint, which will output a log message whenever that breakpoint is hit.
143- Make the breakpoint conditional, which will only stop at the breakpoint when the condition is met. The syntax for conditions is adapter-specific.
144- Add a hit count to a breakpoint, which will only stop at the breakpoint after it's hit a certain number of times.
145- Disable a breakpoint, which will prevent it from being hit while leaving it visible in the gutter.
146
147Some debug adapters (e.g. CodeLLDB and JavaScript) will also _verify_ whether your breakpoints can be hit; breakpoints that cannot be hit are surfaced more prominently in the UI.
148
149All breakpoints enabled for a given project are also listed in "Breakpoints" item in your debugging session UI. From "Breakpoints" item in your UI you can also manage exception breakpoints.
150The debug adapter will then stop whenever an exception of a given kind occurs. Which exception types are supported depends on the debug adapter.
151
152## Settings
153
154- `dock`: Determines the position of the debug panel in the UI.
155- `stepping_granularity`: Determines the stepping granularity.
156- `save_breakpoints`: Whether the breakpoints should be reused across Zed sessions.
157- `button`: Whether to show the debug button in the status bar.
158- `timeout`: Time in milliseconds until timeout error when connecting to a TCP debug adapter.
159- `log_dap_communications`: Whether to log messages between active debug adapters and Zed.
160- `format_dap_log_messages`: Whether to format DAP messages when adding them to the debug adapter logger.
161
162### Dock
163
164- Description: The position of the debug panel in the UI.
165- Default: `bottom`
166- Setting: debugger.dock
167
168**Options**
169
1701. `left` - The debug panel will be docked to the left side of the UI.
1712. `right` - The debug panel will be docked to the right side of the UI.
1723. `bottom` - The debug panel will be docked to the bottom of the UI.
173
174```json
175"debugger": {
176  "dock": "bottom"
177},
178```
179
180### Stepping granularity
181
182- Description: The Step granularity that the debugger will use
183- Default: line
184- Setting: debugger.stepping_granularity
185
186**Options**
187
1881. Statement - The step should allow the program to run until the current statement has finished executing.
189   The meaning of a statement is determined by the adapter and it may be considered equivalent to a line.
190   For example 'for(int i = 0; i < 10; i++)' could be considered to have 3 statements 'int i = 0', 'i < 10', and 'i++'.
191
192```json
193{
194  "debugger": {
195    "stepping_granularity": "statement"
196  }
197}
198```
199
2002. Line - The step should allow the program to run until the current source line has executed.
201
202```json
203{
204  "debugger": {
205    "stepping_granularity": "line"
206  }
207}
208```
209
2103. Instruction - The step should allow one instruction to execute (e.g. one x86 instruction).
211
212```json
213{
214  "debugger": {
215    "stepping_granularity": "instruction"
216  }
217}
218```
219
220### Save Breakpoints
221
222- Description: Whether the breakpoints should be saved across Zed sessions.
223- Default: true
224- Setting: debugger.save_breakpoints
225
226**Options**
227
228`boolean` values
229
230```json
231{
232  "debugger": {
233    "save_breakpoints": true
234  }
235}
236```
237
238### Button
239
240- Description: Whether the button should be displayed in the debugger toolbar.
241- Default: true
242- Setting: debugger.show_button
243
244**Options**
245
246`boolean` values
247
248```json
249{
250  "debugger": {
251    "show_button": true
252  }
253}
254```
255
256### Timeout
257
258- Description: Time in milliseconds until timeout error when connecting to a TCP debug adapter.
259- Default: 2000
260- Setting: debugger.timeout
261
262**Options**
263
264`integer` values
265
266```json
267{
268  "debugger": {
269    "timeout": 3000
270  }
271}
272```
273
274### Log Dap Communications
275
276- Description: Whether to log messages between active debug adapters and Zed. (Used for DAP development)
277- Default: false
278- Setting: debugger.log_dap_communications
279
280**Options**
281
282`boolean` values
283
284```json
285{
286  "debugger": {
287    "log_dap_communications": true
288  }
289}
290```
291
292### Format Dap Log Messages
293
294- Description: Whether to format DAP messages when adding them to the debug adapter logger. (Used for DAP development)
295- Default: false
296- Setting: debugger.format_dap_log_messages
297
298**Options**
299
300`boolean` values
301
302```json
303{
304  "debugger": {
305    "format_dap_log_messages": true
306  }
307}
308```
309
310### Customizing Debug Adapters
311
312- Description: Custom program path and arguments to override how Zed launches a specific debug adapter.
313- Default: Adapter-specific
314- Setting: `dap.$ADAPTER.binary` and `dap.$ADAPTER.args`
315
316You can pass `binary`, `args`, or both. `binary` should be a path to a _debug adapter_ (like `lldb-dap`) not a _debugger_ (like `lldb` itself). The `args` setting overrides any arguments that Zed would otherwise pass to the adapter.
317
318```json
319{
320  "dap": {
321    "CodeLLDB": {
322      "binary": "/Users/name/bin/lldb-dap",
323      "args": ["--wait-for-debugger"]
324    }
325  }
326}
327```
328
329## Theme
330
331The Debugger supports the following theme options:
332
333- `debugger.accent`: Color used to accent breakpoint & breakpoint-related symbols
334- `editor.debugger_active_line.background`: Background color of active debug line
335
336## Troubleshooting
337
338If you're running into problems with the debugger, please [open a GitHub issue](https://github.com/zed-industries/zed/issues/new?template=04_bug_debugger.yml) or [schedule an onboarding call](https://cal.com/team/zed-research/debugger) with us so we can help understand and fix your issue.
339
340There are also some features you can use to gather more information about the problem:
341
342- When you have a session running in the debug panel, you can run the {#action dev::CopyDebugAdapterArguments} action to copy a JSON blob to the clipboard that describes how Zed initialized the session. This is especially useful when the session failed to start, and is great context to add if you open a GitHub issue.
343- You can also use the {#action dev::OpenDebugAdapterLogs} action to see a trace of all of Zed's communications with debug adapters during the most recent debug sessions.