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## Supported Debug Adapters
 10
 11Zed supports a variety of debug adapters for different programming languages:
 12
 13- JavaScript (node): Enables debugging of Node.js applications, including setting breakpoints, stepping through code, and inspecting variables in JavaScript.
 14
 15- Python (debugpy): Provides debugging capabilities for Python applications, supporting features like remote debugging, multi-threaded debugging, and Django/Flask application debugging.
 16
 17- LLDB: A powerful debugger for C, C++, Objective-C, and Swift, offering low-level debugging features and support for Apple platforms.
 18
 19- GDB: The GNU Debugger, which supports debugging for multiple programming languages including C, C++, Go, and Rust, across various platforms.
 20
 21- Go (dlv): 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.
 22
 23- PHP (xdebug): Provides debugging and profiling capabilities for PHP applications, including remote debugging and code coverage analysis.
 24
 25These adapters enable Zed to provide a consistent debugging experience across multiple languages while leveraging the specific features and capabilities of each debugger.
 26
 27Additionally, Ruby support (via rdbg) is being actively worked on.
 28
 29## Getting Started
 30
 31For 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.
 32
 33For more advanced use cases, you can create debug configurations by directly editing the `.zed/debug.json` file in your project root directory.
 34
 35You can then use the `New Session Modal` to select a configuration and start debugging.
 36
 37### Launching & Attaching
 38
 39Zed debugger offers two ways to debug your program; you can either _launch_ a new instance of your program or _attach_ to an existing process.
 40Which one you choose depends on what you are trying to achieve.
 41
 42When 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.
 43
 44Compared 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.
 45
 46## Configuration
 47
 48While configuration fields are debug adapter-dependent, most adapters support the following fields:
 49
 50```json
 51[
 52  {
 53    // The label for the debug configuration and used to identify the debug session inside the debug panel & new session modal
 54    "label": "Example Start debugger config",
 55    // The debug adapter that Zed should use to debug the program
 56    "adapter": "Example adapter name",
 57    // Request:
 58    //  - launch: Zed will launch the program if specified or shows a debug terminal with the right configuration
 59    //  - 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)
 60    "request": "launch",
 61    // program: The program that you want to debug
 62    // This field supports path resolution with ~ or . symbols
 63    "program": "path_to_program",
 64    // cwd: defaults to the current working directory of your project ($ZED_WORKTREE_ROOT)
 65    "cwd": "$ZED_WORKTREE_ROOT"
 66  }
 67]
 68```
 69
 70All configuration fields support task variables. See [Tasks Variables](./tasks.md#variables)
 71
 72### Build tasks
 73
 74Zed 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.
 75
 76```json
 77[
 78  {
 79    "label": "Build Binary",
 80    "adapter": "CodeLLDB",
 81    "program": "path_to_program",
 82    "request": "launch",
 83    "build": {
 84      "command": "make",
 85      "args": ["build", "-j8"]
 86    }
 87  }
 88]
 89```
 90
 91Build tasks can also refer to the existing tasks by unsubstituted label:
 92
 93```json
 94[
 95  {
 96    "label": "Build Binary",
 97    "adapter": "CodeLLDB",
 98    "program": "path_to_program",
 99    "request": "launch",
100    "build": "my build task" // Or "my build task for $ZED_FILE"
101  }
102]
103```
104
105### Automatic scenario creation
106
107Given a Zed task, Zed can automatically create a scenario for you. Automatic scenario creation also powers our scenario creation from gutter.
108Automatic scenario creation is currently supported for Rust, Go and Python. Javascript/TypeScript support being worked on.
109
110### Example Configurations
111
112#### JavaScript
113
114##### Debug Active File
115
116```json
117[
118  {
119    "label": "Debug with node",
120    "adapter": "JavaScript",
121    "program": "$ZED_FILE",
122    "request": "launch",
123    "console": "integratedTerminal",
124    "type": "pwa-node"
125  }
126]
127```
128
129##### Attach debugger to a server running in web browser (`npx serve`)
130
131Given 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.
132
133```json
134[
135  {
136    "label": "Inspect ",
137    "adapter": "JavaScript",
138    "type": "pwa-chrome",
139    "request": "launch",
140    "url": "http://localhost:5500", // Fill your URL here.
141    "program": "$ZED_FILE",
142    "webRoot": "${ZED_WORKTREE_ROOT}"
143  }
144]
145```
146
147#### Python
148
149##### Debug Active File
150
151```json
152[
153  {
154    "label": "Python Active File",
155    "adapter": "Debugpy",
156    "program": "$ZED_FILE",
157    "request": "launch"
158  }
159]
160```
161
162##### Flask App
163
164For a common Flask Application with a file structure similar to the following:
165
166```
167.venv/
168app/
169  init.py
170  main.py
171  routes.py
172templates/
173  index.html
174static/
175  style.css
176requirements.txt
177```
178
179the following configuration can be used:
180
181```json
182[
183  {
184    "label": "Python: Flask",
185    "adapter": "Debugpy",
186    "request": "launch",
187    "module": "app",
188    "cwd": "$ZED_WORKTREE_ROOT",
189    "env": {
190      "FLASK_APP": "app",
191      "FLASK_DEBUG": "1"
192    },
193    "args": [
194      "run",
195      "--reload", // Enables Flask reloader that watches for file changes
196      "--debugger" // Enables Flask debugger
197    ],
198    "autoReload": {
199      "enable": true
200    },
201    "jinja": true,
202    "justMyCode": true
203  }
204]
205```
206
207#### Rust/C++/C
208
209##### Using pre-built binary
210
211```json
212[
213  {
214    "label": "Debug native binary",
215    "program": "$ZED_WORKTREE_ROOT/build/binary",
216    "request": "launch",
217    "adapter": "CodeLLDB" // GDB is available on non arm macs as well as linux
218  }
219]
220```
221
222##### Build binary then debug
223
224```json
225[
226  {
227    "label": "Build & Debug native binary",
228    "build": {
229      "command": "cargo",
230      "args": ["build"]
231    },
232    "program": "$ZED_WORKTREE_ROOT/target/debug/binary",
233    "request": "launch",
234    "adapter": "CodeLLDB" // GDB is available on non arm macs as well as linux
235  }
236]
237```
238
239#### TypeScript
240
241##### Attach debugger to a server running in web browser (`npx serve`)
242
243Given 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.
244
245```json
246[
247  {
248    "label": "Launch Chromee (TypeScript)",
249    "adapter": "JavaScript",
250    "type": "pwa-chrome",
251    "request": "launch",
252    "url": "http://localhost:5500",
253    "program": "$ZED_FILE",
254    "webRoot": "${ZED_WORKTREE_ROOT}",
255    "sourceMaps": true,
256    "build": {
257      "command": "npx",
258      "args": ["tsc"]
259    }
260  }
261]
262```
263
264## Breakpoints
265
266To set a breakpoint, simply click next to the line number in the editor gutter.
267Breakpoints 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.
268At present, you can:
269
270- Add a log to a breakpoint, which will output a log message whenever that breakpoint is hit.
271- Make the breakpoint conditional, which will only stop at the breakpoint when the condition is met. The syntax for conditions is adapter-specific.
272- Add a hit count to a breakpoint, which will only stop at the breakpoint after it's hit a certain number of times.
273- Disable a breakpoint, which will prevent it from being hit while leaving it visible in the gutter.
274
275Some 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.
276
277All 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.
278The debug adapter will then stop whenever an exception of a given kind occurs. Which exception types are supported depends on the debug adapter.
279
280## Settings
281
282- `dock`: Determines the position of the debug panel in the UI.
283- `stepping_granularity`: Determines the stepping granularity.
284- `save_breakpoints`: Whether the breakpoints should be reused across Zed sessions.
285- `button`: Whether to show the debug button in the status bar.
286- `timeout`: Time in milliseconds until timeout error when connecting to a TCP debug adapter.
287- `log_dap_communications`: Whether to log messages between active debug adapters and Zed.
288- `format_dap_log_messages`: Whether to format DAP messages when adding them to the debug adapter logger.
289
290### Dock
291
292- Description: The position of the debug panel in the UI.
293- Default: `bottom`
294- Setting: debugger.dock
295
296**Options**
297
2981. `left` - The debug panel will be docked to the left side of the UI.
2992. `right` - The debug panel will be docked to the right side of the UI.
3003. `bottom` - The debug panel will be docked to the bottom of the UI.
301
302```json
303"debugger": {
304  "dock": "bottom"
305},
306```
307
308### Stepping granularity
309
310- Description: The Step granularity that the debugger will use
311- Default: line
312- Setting: debugger.stepping_granularity
313
314**Options**
315
3161. Statement - The step should allow the program to run until the current statement has finished executing.
317   The meaning of a statement is determined by the adapter and it may be considered equivalent to a line.
318   For example 'for(int i = 0; i < 10; i++)' could be considered to have 3 statements 'int i = 0', 'i < 10', and 'i++'.
319
320```json
321{
322  "debugger": {
323    "stepping_granularity": "statement"
324  }
325}
326```
327
3282. Line - The step should allow the program to run until the current source line has executed.
329
330```json
331{
332  "debugger": {
333    "stepping_granularity": "line"
334  }
335}
336```
337
3383. Instruction - The step should allow one instruction to execute (e.g. one x86 instruction).
339
340```json
341{
342  "debugger": {
343    "stepping_granularity": "instruction"
344  }
345}
346```
347
348### Save Breakpoints
349
350- Description: Whether the breakpoints should be saved across Zed sessions.
351- Default: true
352- Setting: debugger.save_breakpoints
353
354**Options**
355
356`boolean` values
357
358```json
359{
360  "debugger": {
361    "save_breakpoints": true
362  }
363}
364```
365
366### Button
367
368- Description: Whether the button should be displayed in the debugger toolbar.
369- Default: true
370- Setting: debugger.show_button
371
372**Options**
373
374`boolean` values
375
376```json
377{
378  "debugger": {
379    "show_button": true
380  }
381}
382```
383
384### Timeout
385
386- Description: Time in milliseconds until timeout error when connecting to a TCP debug adapter.
387- Default: 2000
388- Setting: debugger.timeout
389
390**Options**
391
392`integer` values
393
394```json
395{
396  "debugger": {
397    "timeout": 3000
398  }
399}
400```
401
402### Log Dap Communications
403
404- Description: Whether to log messages between active debug adapters and Zed. (Used for DAP development)
405- Default: false
406- Setting: debugger.log_dap_communications
407
408**Options**
409
410`boolean` values
411
412```json
413{
414  "debugger": {
415    "log_dap_communications": true
416  }
417}
418```
419
420### Format Dap Log Messages
421
422- Description: Whether to format DAP messages when adding them to the debug adapter logger. (Used for DAP development)
423- Default: false
424- Setting: debugger.format_dap_log_messages
425
426**Options**
427
428`boolean` values
429
430```json
431{
432  "debugger": {
433    "format_dap_log_messages": true
434  }
435}
436```
437
438## Theme
439
440The Debugger supports the following theme options:
441
442**debugger.accent**: Color used to accent breakpoint & breakpoint-related symbols
443**editor.debugger_active_line.background**: Background color of active debug line