debugger.md

  1# Debugger (Beta)
  2
  3Zed uses the Debug Adapter Protocol (DAP) 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.
  6This protocol enables features like setting breakpoints, stepping through code, inspecting variables,
  7and more, in a consistent manner across different programming languages and runtime environments.
  8
  9> 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.
 10> You can schedule a call via [Cal.com](https://cal.com/team/zed-research/debugger)
 11
 12## Supported Debug Adapters
 13
 14Zed supports a variety of debug adapters for different programming languages out of the box:
 15
 16- JavaScript ([vscode-js-debug](https://github.com/microsoft/vscode-js-debug.git)): Enables debugging of Node.js applications, including setting breakpoints, stepping through code, and inspecting variables in JavaScript.
 17
 18- Python ([debugpy](https://github.com/microsoft/debugpy.git)): Provides debugging capabilities for Python applications, supporting features like remote debugging, multi-threaded debugging, and Django/Flask application debugging.
 19
 20- LLDB ([CodeLLDB](https://github.com/vadimcn/codelldb.git)): A powerful debugger for C, C++, Objective-C, and Swift, offering low-level debugging features and support for Apple platforms.
 21
 22- GDB ([GDB](https://sourceware.org/gdb/)): The GNU Debugger, which supports debugging for multiple programming languages including C, C++, Go, and Rust, across various platforms.
 23
 24- Go ([Delve](https://github.com/go-delve/delve)): Delve, a debugger for the Go programming language, offering both local and remote debugging capabilities with full support for Go's runtime and standard library.
 25
 26- PHP ([Xdebug](https://xdebug.org/)): Provides debugging and profiling capabilities for PHP applications, including remote debugging and code coverage analysis.
 27
 28- Ruby ([rdbg](https://github.com/ruby/debug)): Provides debugging for Ruby.
 29
 30These adapters enable Zed to provide a consistent debugging experience across multiple languages while leveraging the specific features and capabilities of each debugger.
 31
 32## Getting Started
 33
 34For basic debugging, you can set up a new configuration by opening the `New Session Modal` either via the `debugger: start` (default: f4) or by clicking the plus icon at the top right of the debug panel.
 35
 36For more advanced use cases, you can create debug configurations by directly editing the `.zed/debug.json` file in your project root directory.
 37
 38You can then use the `New Session Modal` to select a configuration and start debugging.
 39
 40### Launching & Attaching
 41
 42Zed debugger offers two ways to debug your program; you can either _launch_ a new instance of your program or _attach_ to an existing process.
 43Which one you choose depends on what you are trying to achieve.
 44
 45When 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. Running unit tests or a debug build of your application is a good use case for launching.
 46
 47Compared 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 e.g. the bug is not reproducible outside of a production environment or some other circumstances.
 48
 49## Configuration
 50
 51While configuration fields are debug adapter-dependent, most adapters support the following fields:
 52
 53```json
 54[
 55  {
 56    // The label for the debug configuration and used to identify the debug session inside the debug panel & new session modal
 57    "label": "Example Start debugger config",
 58    // The debug adapter that Zed should use to debug the program
 59    "adapter": "Example adapter name",
 60    // Request:
 61    //  - launch: Zed will launch the program if specified or shows a debug terminal with the right configuration
 62    //  - 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)
 63    "request": "launch",
 64    // program: The program that you want to debug
 65    // This field supports path resolution with ~ or . symbols
 66    "program": "path_to_program",
 67    // cwd: defaults to the current working directory of your project ($ZED_WORKTREE_ROOT)
 68    "cwd": "$ZED_WORKTREE_ROOT"
 69  }
 70]
 71```
 72
 73All configuration fields support task variables. See [Tasks Variables](./tasks.md#variables)
 74
 75### Build tasks
 76
 77Zed 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.
 78
 79```json
 80[
 81  {
 82    "label": "Build Binary",
 83    "adapter": "CodeLLDB",
 84    "program": "path_to_program",
 85    "request": "launch",
 86    "build": {
 87      "command": "make",
 88      "args": ["build", "-j8"]
 89    }
 90  }
 91]
 92```
 93
 94Build tasks can also refer to the existing tasks by unsubstituted label:
 95
 96```json
 97[
 98  {
 99    "label": "Build Binary",
100    "adapter": "CodeLLDB",
101    "program": "path_to_program",
102    "request": "launch",
103    "build": "my build task" // Or "my build task for $ZED_FILE"
104  }
105]
106```
107
108### Automatic scenario creation
109
110Given a Zed task, Zed can automatically create a scenario for you. Automatic scenario creation also powers our scenario creation from gutter.
111Automatic scenario creation is currently supported for Rust, Go and Python. Javascript/TypeScript support being worked on.
112
113### Example Configurations
114
115#### Go
116
117```json
118[
119  {
120    "label": "Go (Delve)",
121    "adapter": "Delve",
122    "program": "$ZED_FILE",
123    "request": "launch",
124    "mode": "debug"
125  }
126]
127```
128
129#### JavaScript
130
131##### Debug Active File
132
133```json
134[
135  {
136    "label": "Debug with node",
137    "adapter": "JavaScript",
138    "program": "$ZED_FILE",
139    "request": "launch",
140    "console": "integratedTerminal",
141    "type": "pwa-node"
142  }
143]
144```
145
146##### Attach debugger to a server running in web browser (`npx serve`)
147
148Given an externally-ran web server (e.g. with `npx serve` or `npx live-server`) one can attach to it and open it with a browser.
149
150```json
151[
152  {
153    "label": "Inspect ",
154    "adapter": "JavaScript",
155    "type": "pwa-chrome",
156    "request": "launch",
157    "url": "http://localhost:5500", // Fill your URL here.
158    "program": "$ZED_FILE",
159    "webRoot": "${ZED_WORKTREE_ROOT}"
160  }
161]
162```
163
164#### Python
165
166##### Debug Active File
167
168```json
169[
170  {
171    "label": "Python Active File",
172    "adapter": "Debugpy",
173    "program": "$ZED_FILE",
174    "request": "launch"
175  }
176]
177```
178
179##### Flask App
180
181For a common Flask Application with a file structure similar to the following:
182
183```
184.venv/
185app/
186  init.py
187  main.py
188  routes.py
189templates/
190  index.html
191static/
192  style.css
193requirements.txt
194```
195
196the following configuration can be used:
197
198```json
199[
200  {
201    "label": "Python: Flask",
202    "adapter": "Debugpy",
203    "request": "launch",
204    "module": "app",
205    "cwd": "$ZED_WORKTREE_ROOT",
206    "env": {
207      "FLASK_APP": "app",
208      "FLASK_DEBUG": "1"
209    },
210    "args": [
211      "run",
212      "--reload", // Enables Flask reloader that watches for file changes
213      "--debugger" // Enables Flask debugger
214    ],
215    "autoReload": {
216      "enable": true
217    },
218    "jinja": true,
219    "justMyCode": true
220  }
221]
222```
223
224#### Rust/C++/C
225
226##### Using pre-built binary
227
228```json
229[
230  {
231    "label": "Debug native binary",
232    "program": "$ZED_WORKTREE_ROOT/build/binary",
233    "request": "launch",
234    "adapter": "CodeLLDB" // GDB is available on non arm macs as well as linux
235  }
236]
237```
238
239##### Build binary then debug
240
241```json
242[
243  {
244    "label": "Build & Debug native binary",
245    "build": {
246      "command": "cargo",
247      "args": ["build"]
248    },
249    "program": "$ZED_WORKTREE_ROOT/target/debug/binary",
250    "request": "launch",
251    "adapter": "CodeLLDB" // GDB is available on non arm macs as well as linux
252  }
253]
254```
255
256#### TypeScript
257
258##### Attach debugger to a server running in web browser (`npx serve`)
259
260Given an externally-ran web server (e.g. with `npx serve` or `npx live-server`) one can attach to it and open it with a browser.
261
262```json
263[
264  {
265    "label": "Launch Chromee (TypeScript)",
266    "adapter": "JavaScript",
267    "type": "pwa-chrome",
268    "request": "launch",
269    "url": "http://localhost:5500",
270    "program": "$ZED_FILE",
271    "webRoot": "${ZED_WORKTREE_ROOT}",
272    "sourceMaps": true,
273    "build": {
274      "command": "npx",
275      "args": ["tsc"]
276    }
277  }
278]
279```
280
281#### Go
282
283Zed uses [delve](https://github.com/go-delve/delve?tab=readme-ov-file) to debug Go applications. Zed will automatically create debug scenarios for `func main` in your main packages, and also
284for any tests, so you can use the Play button in the gutter to debug these without configuration. We do not yet support attaching to an existing running copy of delve.
285
286##### Debug Go Packages
287
288To debug a specific package, you can do so by setting the Delve mode to "debug". In this case "program" should be set to the package name.
289
290```json
291[
292  {
293    "label": "Run server",
294    "adapter": "Delve",
295    "request": "launch",
296    "mode": "debug",
297    // For Delve, the program is the package name
298    "program": "./cmd/server"
299    // "args": [],
300    // "buildFlags": [],
301  }
302]
303```
304
305##### Debug Go Tests
306
307To debug the tests for a package, set the Delve mode to "test". The "program" is still the package name, and you can use the "buildFlags" to do things like set tags, and the "args" to set args on the test binary. (See `go help testflags` for more information on doing that).
308
309```json
310[
311  {
312    "label": "Run integration tests",
313    "adapter": "Delve",
314    "request": "launch",
315    "mode": "test",
316    "program": ".",
317    "buildFlags": ["-tags", "integration"]
318    // To filter down to just the test your cursor is in:
319    // "args": ["-test.run", "$ZED_SYMBOL"]
320  }
321]
322```
323
324##### Build and debug separately
325
326If you need to build your application with a specific command, you can use the "exec" mode of Delve. In this case "program" should point to an executable,
327and the "build" command should build that.
328
329```json
330{
331  "label": "Debug Prebuilt Unit Tests",
332  "adapter": "Delve",
333  "request": "launch",
334  "mode": "exec",
335  "program": "${ZED_WORKTREE_ROOT}/__debug_unit",
336  "args": ["-test.v", "-test.run=${ZED_SYMBOL}"],
337  "build": {
338    "command": "go",
339    "args": [
340      "test",
341      "-c",
342      "-tags",
343      "unit",
344      "-gcflags\"all=-N -l\"",
345      "-o",
346      "__debug_unit",
347      "./pkg/..."
348    ]
349  }
350}
351```
352
353### Ruby
354
355To run a ruby task in the debugger, you will need to configure it in the `.zed/debug.json` file in your project. We don't yet have automatic detection of ruby tasks, nor do we support connecting to an existing process.
356
357The configuration should look like this:
358
359```json
360{
361  {
362    "adapter": "Ruby",
363    "label": "Run CLI",
364    "script": "cli.rb"
365    // If you want to customize how the script is run (for example using bundle exec)
366    // use "command" instead.
367    // "command": "bundle exec cli.rb"
368    //
369    // "args": []
370    // "env": {}
371    // "cwd": ""
372  }
373}
374```
375
376## Breakpoints
377
378To set a breakpoint, simply click next to the line number in the editor gutter.
379Breakpoints 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.
380At present, you can:
381
382- Add a log to a breakpoint, which will output a log message whenever that breakpoint is hit.
383- Make the breakpoint conditional, which will only stop at the breakpoint when the condition is met. The syntax for conditions is adapter-specific.
384- Add a hit count to a breakpoint, which will only stop at the breakpoint after it's hit a certain number of times.
385- Disable a breakpoint, which will prevent it from being hit while leaving it visible in the gutter.
386
387Some 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.
388
389All 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.
390The debug adapter will then stop whenever an exception of a given kind occurs. Which exception types are supported depends on the debug adapter.
391
392## Settings
393
394- `dock`: Determines the position of the debug panel in the UI.
395- `stepping_granularity`: Determines the stepping granularity.
396- `save_breakpoints`: Whether the breakpoints should be reused across Zed sessions.
397- `button`: Whether to show the debug button in the status bar.
398- `timeout`: Time in milliseconds until timeout error when connecting to a TCP debug adapter.
399- `log_dap_communications`: Whether to log messages between active debug adapters and Zed.
400- `format_dap_log_messages`: Whether to format DAP messages when adding them to the debug adapter logger.
401
402### Dock
403
404- Description: The position of the debug panel in the UI.
405- Default: `bottom`
406- Setting: debugger.dock
407
408**Options**
409
4101. `left` - The debug panel will be docked to the left side of the UI.
4112. `right` - The debug panel will be docked to the right side of the UI.
4123. `bottom` - The debug panel will be docked to the bottom of the UI.
413
414```json
415"debugger": {
416  "dock": "bottom"
417},
418```
419
420### Stepping granularity
421
422- Description: The Step granularity that the debugger will use
423- Default: line
424- Setting: debugger.stepping_granularity
425
426**Options**
427
4281. Statement - The step should allow the program to run until the current statement has finished executing.
429   The meaning of a statement is determined by the adapter and it may be considered equivalent to a line.
430   For example 'for(int i = 0; i < 10; i++)' could be considered to have 3 statements 'int i = 0', 'i < 10', and 'i++'.
431
432```json
433{
434  "debugger": {
435    "stepping_granularity": "statement"
436  }
437}
438```
439
4402. Line - The step should allow the program to run until the current source line has executed.
441
442```json
443{
444  "debugger": {
445    "stepping_granularity": "line"
446  }
447}
448```
449
4503. Instruction - The step should allow one instruction to execute (e.g. one x86 instruction).
451
452```json
453{
454  "debugger": {
455    "stepping_granularity": "instruction"
456  }
457}
458```
459
460### Save Breakpoints
461
462- Description: Whether the breakpoints should be saved across Zed sessions.
463- Default: true
464- Setting: debugger.save_breakpoints
465
466**Options**
467
468`boolean` values
469
470```json
471{
472  "debugger": {
473    "save_breakpoints": true
474  }
475}
476```
477
478### Button
479
480- Description: Whether the button should be displayed in the debugger toolbar.
481- Default: true
482- Setting: debugger.show_button
483
484**Options**
485
486`boolean` values
487
488```json
489{
490  "debugger": {
491    "show_button": true
492  }
493}
494```
495
496### Timeout
497
498- Description: Time in milliseconds until timeout error when connecting to a TCP debug adapter.
499- Default: 2000
500- Setting: debugger.timeout
501
502**Options**
503
504`integer` values
505
506```json
507{
508  "debugger": {
509    "timeout": 3000
510  }
511}
512```
513
514### Log Dap Communications
515
516- Description: Whether to log messages between active debug adapters and Zed. (Used for DAP development)
517- Default: false
518- Setting: debugger.log_dap_communications
519
520**Options**
521
522`boolean` values
523
524```json
525{
526  "debugger": {
527    "log_dap_communications": true
528  }
529}
530```
531
532### Format Dap Log Messages
533
534- Description: Whether to format DAP messages when adding them to the debug adapter logger. (Used for DAP development)
535- Default: false
536- Setting: debugger.format_dap_log_messages
537
538**Options**
539
540`boolean` values
541
542```json
543{
544  "debugger": {
545    "format_dap_log_messages": true
546  }
547}
548```
549
550## Theme
551
552The Debugger supports the following theme options:
553
554**debugger.accent**: Color used to accent breakpoint & breakpoint-related symbols
555**editor.debugger_active_line.background**: Background color of active debug line