1---
2title: Debugger - Zed
3description: Debug code in Zed with the Debug Adapter Protocol (DAP). Breakpoints, stepping, variable inspection across multiple languages.
4---
5
6# Debugger
7
8Zed uses the [Debug Adapter Protocol (DAP)](https://microsoft.github.io/debug-adapter-protocol/) to provide debugging functionality across multiple programming languages.
9DAP is a standardized protocol that defines how debuggers, editors, and IDEs communicate with each other.
10It allows Zed to support various debuggers without needing to implement language-specific debugging logic.
11Zed implements the client side of the protocol, and various _debug adapters_ implement the server side.
12
13This protocol enables features like setting breakpoints, stepping through code, inspecting variables,
14and more, in a consistent manner across different programming languages and runtime environments.
15
16## Supported Languages
17
18To 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:
19
20<!-- keep this sorted -->
21
22- [C](./languages/c.md#debugging) (built-in)
23- [C++](./languages/cpp.md#debugging) (built-in)
24- [Go](./languages/go.md#debugging) (built-in)
25- [Java](./languages/java.md#debugging) (provided by extension)
26- [JavaScript](./languages/javascript.md#debugging) (built-in)
27- [PHP](./languages/php.md#debugging) (built-in)
28- [Python](./languages/python.md#debugging) (built-in)
29- [Ruby](./languages/ruby.md#debugging) (provided by extension)
30- [Rust](./languages/rust.md#debugging) (built-in)
31- [Swift](./languages/swift.md#debugging) (provided by extension)
32- [TypeScript](./languages/typescript.md#debugging) (built-in)
33
34> 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.
35
36Follow 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.
37
38## Getting Started
39
40For 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.
41
42You can open the same modal by clicking the "plus" button at the top right of the debug panel.
43
44For 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:
45
46```json [debug]
47[
48 {
49 "adapter": "CodeLLDB",
50 "label": "First configuration"
51 // ...
52 },
53 {
54 "adapter": "Debugpy",
55 "label": "Second configuration"
56 // ...
57 }
58]
59```
60
61Check 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.
62
63Zed 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`.
64
65#### Global debug configurations
66
67If you run the same launch profiles across multiple projects, you can store them once in your user configuration. Invoke {#action zed::OpenDebugTasks} from the command palette to open the global `debug.json` file; Zed creates it next to your user `settings.json` and keeps it in sync with the debugger UI. The file lives at:
68
69- **macOS:** `~/Library/Application Support/Zed/debug.json`
70- **Linux/BSD:** `$XDG_CONFIG_HOME/zed/debug.json` (falls back to `~/.config/zed/debug.json`)
71- **Windows:** `%APPDATA%\Zed\debug.json`
72
73Populate this file with the same array of objects you would place in `.zed/debug.json`. Any scenarios defined there are merged into every workspace, so your favorite launch presets appear automatically in the "New Debug Session" dialog.
74
75### Launching & Attaching
76
77Zed debugger offers two ways to debug your program; you can either _launch_ a new instance of your program or _attach_ to an existing process.
78Which one you choose depends on what you are trying to achieve.
79
80When 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.
81Running unit tests or a debug build of your application is a good use case for launching.
82
83Compared 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.
84
85## Configuration
86
87Zed requires the `adapter` and `label` fields for all debug tasks. In addition, Zed will use the `build` field to run any necessary setup steps before the debugger starts [(see below)](#build-tasks), and can accept a `tcp_connection` field to connect to an existing process.
88
89All other fields are provided by the debug adapter and can contain [task variables](./tasks.md#variables). Most adapters support `request`, `program`, and `cwd`:
90
91```json [debug]
92[
93 {
94 // The label for the debug configuration and used to identify the debug session inside the debug panel & new process modal
95 "label": "Example Start debugger config",
96 // The debug adapter that Zed should use to debug the program
97 "adapter": "Example adapter name",
98 // Request:
99 // - launch: Zed will launch the program if specified, or show a debug terminal with the right configuration
100 // - attach: Zed will attach to a running program to debug it, or when the process_id is not specified, will show a process picker (only supported for node currently)
101 "request": "launch",
102 // The program to debug. This field supports path resolution with ~ or . symbols.
103 "program": "path_to_program",
104 // cwd: defaults to the current working directory of your project ($ZED_WORKTREE_ROOT)
105 "cwd": "$ZED_WORKTREE_ROOT"
106 }
107]
108```
109
110Check your debug adapter's documentation for more information on the fields it supports.
111
112### Build tasks
113
114Zed allows embedding a Zed task in the `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.
115
116```json [debug]
117[
118 {
119 "label": "Build Binary",
120 "adapter": "CodeLLDB",
121 "program": "path_to_program",
122 "request": "launch",
123 "build": {
124 "command": "make",
125 "args": ["build", "-j8"]
126 }
127 }
128]
129```
130
131Build tasks can also refer to the existing tasks by unsubstituted label:
132
133```json [debug]
134[
135 {
136 "label": "Build Binary",
137 "adapter": "CodeLLDB",
138 "program": "path_to_program",
139 "request": "launch",
140 "build": "my build task" // Or "my build task for $ZED_FILE"
141 }
142]
143```
144
145### Automatic scenario creation
146
147Given a Zed task, Zed can automatically create a scenario for you. Automatic scenario creation also powers our scenario creation from gutter.
148Automatic scenario creation is currently supported for Rust, Go, Python, JavaScript, and TypeScript.
149
150## Breakpoints
151
152To set a breakpoint, simply click next to the line number in the editor gutter.
153Breakpoints 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.
154At present, you can:
155
156- Add a log to a breakpoint, which will output a log message whenever that breakpoint is hit.
157- Make the breakpoint conditional, which will only stop at the breakpoint when the condition is met. The syntax for conditions is adapter-specific.
158- Add a hit count to a breakpoint, which will only stop at the breakpoint after it's hit a certain number of times.
159- Disable a breakpoint, which will prevent it from being hit while leaving it visible in the gutter.
160
161Some 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.
162
163All 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.
164The debug adapter will then stop whenever an exception of a given kind occurs. Which exception types are supported depends on the debug adapter.
165
166## Working with Split Panes
167
168> **Changed in Preview (v0.225).** See [release notes](/releases#0.225).
169
170When debugging with multiple split panes open, Zed shows the active debug line in one pane and preserves your layout in others. If you have the same file open in multiple panes, the debugger picks a pane where the file is already the active tabβit won't switch tabs in panes where the file is inactive.
171
172Once the debugger picks a pane, it continues using that pane for subsequent breakpoints during the session. If you drag the tab with the active debug line to a different split, the debugger tracks the move and uses the new pane.
173
174This ensures the debugger doesn't disrupt your workflow when stepping through code across different files.
175
176## Settings
177
178The settings for the debugger are grouped under the `debugger` key in `settings.json`:
179
180- `dock`: Determines the position of the debug panel in the UI.
181- `stepping_granularity`: Determines the stepping granularity.
182- `save_breakpoints`: Whether the breakpoints should be reused across Zed sessions.
183- `button`: Whether to show the debug button in the status bar.
184- `timeout`: Time in milliseconds until timeout error when connecting to a TCP debug adapter.
185- `log_dap_communications`: Whether to log messages between active debug adapters and Zed.
186- `format_dap_log_messages`: Whether to format DAP messages when adding them to the debug adapter logger.
187
188### Dock
189
190- Description: The position of the debug panel in the UI.
191- Default: `bottom`
192- Setting: debugger.dock
193
194**Options**
195
1961. `left` - The debug panel will be docked to the left side of the UI.
1972. `right` - The debug panel will be docked to the right side of the UI.
1983. `bottom` - The debug panel will be docked to the bottom of the UI.
199
200```json [settings]
201"debugger": {
202 "dock": "bottom"
203},
204```
205
206### Stepping granularity
207
208- Description: The Step granularity that the debugger will use
209- Default: `line`
210- Setting: `debugger.stepping_granularity`
211
212**Options**
213
2141. Statement - The step should allow the program to run until the current statement has finished executing.
215 The meaning of a statement is determined by the adapter and it may be considered equivalent to a line.
216 For example `for(int i = 0; i < 10; i++)` could be considered to have 3 statements `int i = 0`, `i < 10`, and `i++`.
217
218```json [settings]
219{
220 "debugger": {
221 "stepping_granularity": "statement"
222 }
223}
224```
225
2262. Line - The step should allow the program to run until the current source line has executed.
227
228```json [settings]
229{
230 "debugger": {
231 "stepping_granularity": "line"
232 }
233}
234```
235
2363. Instruction - The step should allow one instruction to execute (e.g. one x86 instruction).
237
238```json [settings]
239{
240 "debugger": {
241 "stepping_granularity": "instruction"
242 }
243}
244```
245
246### Save Breakpoints
247
248- Description: Whether the breakpoints should be saved across Zed sessions.
249- Default: `true`
250- Setting: `debugger.save_breakpoints`
251
252**Options**
253
254`boolean` values
255
256```json [settings]
257{
258 "debugger": {
259 "save_breakpoints": true
260 }
261}
262```
263
264### Button
265
266- Description: Whether the button should be displayed in the debugger toolbar.
267- Default: `true`
268- Setting: `debugger.button`
269
270**Options**
271
272`boolean` values
273
274```json [settings]
275{
276 "debugger": {
277 "button": true
278 }
279}
280```
281
282### Timeout
283
284- Description: Time in milliseconds until timeout error when connecting to a TCP debug adapter.
285- Default: `2000`
286- Setting: `debugger.timeout`
287
288**Options**
289
290`integer` values
291
292```json [settings]
293{
294 "debugger": {
295 "timeout": 3000
296 }
297}
298```
299
300### Inline Values
301
302- Description: Whether to enable editor inlay hints showing the values of variables in your code during debugging sessions.
303- Default: `true`
304- Setting: `inlay_hints.show_value_hints`
305
306**Options**
307
308```json [settings]
309{
310 "inlay_hints": {
311 "show_value_hints": false
312 }
313}
314```
315
316Inline value hints can also be toggled from the Editor Controls menu in the editor toolbar.
317
318### Log Dap Communications
319
320- Description: Whether to log messages between active debug adapters and Zed. (Used for DAP development)
321- Default: false
322- Setting: debugger.log_dap_communications
323
324**Options**
325
326`boolean` values
327
328```json [settings]
329{
330 "debugger": {
331 "log_dap_communications": true
332 }
333}
334```
335
336### Format Dap Log Messages
337
338- Description: Whether to format DAP messages when adding them to the debug adapter logger. (Used for DAP development)
339- Default: false
340- Setting: debugger.format_dap_log_messages
341
342**Options**
343
344`boolean` values
345
346```json [settings]
347{
348 "debugger": {
349 "format_dap_log_messages": true
350 }
351}
352```
353
354### Customizing Debug Adapters
355
356- Description: Custom program path and arguments to override how Zed launches a specific debug adapter.
357- Default: Adapter-specific
358- Setting: `dap.$ADAPTER.binary` and `dap.$ADAPTER.args`
359
360You 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.
361
362```json [settings]
363{
364 "dap": {
365 "CodeLLDB": {
366 "binary": "/Users/name/bin/lldb-dap",
367 "args": ["--wait-for-debugger"]
368 }
369 }
370}
371```
372
373## Theme
374
375The Debugger supports the following theme options:
376
377- `debugger.accent`: Color used to accent breakpoint & breakpoint-related symbols
378- `editor.debugger_active_line.background`: Background color of active debug line
379
380## Troubleshooting
381
382If 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), providing as much context as possible. There are also some features you can use to gather more information about the problem:
383
384- 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.
385- 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.