Debugging
The Go extension allows you to launch or attach to Go programs for debugging. You can inspect variables and stacks, setting breakpoints, and do other debugging activities using VS Code’s Debugging UI.
legacyDelve
dlv-dap
"remote"
dlv-dap
Getting Started
package mainRun and DebugStart Debugging (F5)
.vscode/launch.json
.vscode/launch.json
❗ When you start debugging in `dlv-dap` mode for the first time, the extension will ask to install Delve built from head (`dlv-dap`). Please follow the instructions to install, and then start the debugging session again (i.e. selecting the source file, pressing F5 or click the codelens).
Please review the Features section that provides an overview of the debug UI and available features.
Staying Up-To-Date
dlvdlv-dap
dlv-dap"Go: Install/Update Tools"dlv-dapdlv-dap
dlv-dapgo.toolsManagement.autoUpdatedlv-dap
dlv-dap
Switching to legacy debug adapter
legacy
Note that the extension still uses the legacy debug adapter for remote debugging.
"go.delveConfig": {
"debugAdapter": "legacy",
}
legacydebugAdapter"dlv-dap""legacy"
If you chose to switch to legacy because of bugs or limitations in the new debug adapter,
please open an issue
to help us improve the new debug adapter.
Features
For general debugging features such as inspecting variables, setting breakpoints, and other activities that aren’t language-dependent, review VS Code debugging.
Configure
launch.json
launch.jsonOpen launch.json
launch.json
There are many configuration attributes (see the Launch.json attributes section). IntelliSense in VS Code’s launch.json editor will help you navigate available options and documentation.
Launch
noDebuglaunchprogram
debugtestexec-gcflags=all="-N -l"autodebugtest
Attach
attachattachdlv-dap
processIdprocessId0processId
When you end the debug session, the debug UI allows you to choose to either
- Disconnect: detach and leave the process running. (default)
- Terminate: terminate the attached process.
Debug Actions
Once a debug session starts, the Debug toolbar will appear on the top of the editor.
nextstepstepout
Breakpoints
See VS Code’s Debug Documentation on Breakpoints to get familiar with VS Code’s UI. The Go debugger supports multiple ways to configure breakpoints.
- Breakpoints: you can set breakpoints by clicking on the editor margin or using F9 on the current line. If the breakpoints can’t be set by Delve, VS Code will show the failure reason and grey out the dot.
condition>>=<<===!=% nn
- Logpoint (WIP)
Data Inspection
You can inspect variables in the VARIABLES section of the Run view or by hovering over their source in the editor. Variable values and expression evaluation are relative to the selected stack frame in the CALL section.
showGlobalVariableslaunch.jsongo.delveConfig
When you select a variable and right click from the VARIABLES section, the context menu will present shortcuts to features such as:
Set ValueCopy ValueCopy as ExpressionAdd to Watch
()
dlv-dap
You can inspect variables and evaluate expressions from the DEBUG CONSOLE panel too. Acceptable expressions are either
call
Variables and expressions accepted in DEBUG CONSOLE can be also registered in the Run view’s WATCH section, so they can be evaluated automatically as you debug. The “Add to Watch” feature from the VARIABLES section is convenient when you want to register interesting variables.
⚠️ Function call feature is highly EXPERIMENTAL due to the limitation in Go runtime. Registering function calls in the WATCH section can often be problematic. Pause, stop, and disconnect will not work while a function call is running.
Hover over variables in editors during debugging shows the value of the variable. For this feature, VS Code extracts the variable expression and makes a request to the debugger to evaluate the expression. Delve evaluates the expression relative to the highlighted stack frame chosen in the CALL STACK. By default, that is the current top-most frame.
⚠️ Limitation
- VS Code heuristically determines the variable expression without full understanding of the scope & the currently selected frame. Delve tries to evaluate the provided expression in the selected frame. As a result, hover over variables outside the selected frame’s function may present incorrect information.
Call Stack
You can inspect all goroutines and their stacks in the CALL STACK section. The CALL STACK section UI allows switching between goroutines or selecting a different stack frame. As a different stack frame or different goroutine is selected, the scope shown in the VARIABLE section will be updated for the newly selected stack frame, and the expressions in the WATCH section will be automatically reevaluated relative to the newly selected stack frame.
*
When the program stops due to exception, panic, or bad access error, the CALL STACK shows the stop reason and the editor highlights the source location with more details.
Configuration
Launch.json Attributes
There are many attributes that you can adjust in the launch and attach debug configuration. The following general attributes are mandatory for all launch configurations.
nametype"go"requestlaunchattach
Here is the list of attributes specific to Go debugging.
argsbackenddlv--backend"default""native""lldb""rr"buildFlags--build-flags""coreFilePath""cwdprogramcwd"""${workspaceFolder}"debugAdapter"legacy""dlv-dap"dlv-dapdlvFlagsdlvdlv help--log-output--log--log-dest--api-version--output--backend--listen--headlessdlvFlagsenvenvFile${workspaceFolder}/.envhideSystemGoroutinesfalsehost"127.0.0.1"logDest--log-destdlv logdlv-dap--log-destdlv logdlv-daplogOutput--log-outputdlv log"debugger""gdbwire""lldbout""debuglineerr""rpc""dap""debugger"modeautodebugtestexecreplaycoreautodebugtest"auto""debug""test""exec""replay""core"autodlv attachconnectremotedlv-daphostport"local""remote"localoutput"debug"port2345processId"${command:pickProcess}""${command:pickGoProcess}"0programdebugtestexec"${workspaceFolder}"remotePathsubstitutePath""showGlobalVariablesfalseshowLog--logfalseshowRegistersfalsestackTraceDepth50stopOnEntryfalsefalsesubstitutePath"from""""to"""remotePath"from""""to"""tracelegacyerror"verbose""trace""log""info""warn""error""error"traceDirPath""
dlv-daplaunch.jsondlv-dap${workspaceFolder}dlv-dap
Debugging symlink directories
debugAdapter/path/to/actual/helloWorld/path/to/hello/path/to/hello
{
"name": "Launch remote",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "/path/to/actual/helloWorld",
"substitutePath": [
{
"from": "/path/to/hello",
"to": "/path/to/actual/helloWorld",
},
],
}
Settings
go.delveConfiglaunch.jsonDebug Test
go.delveConfigdebugAdapterlegacyshowGlobalVariablesfalsesubstitutePath[]
dlvLoadConfigdlvLoadConfigdlv-dapdlv-dap
Advanced Topics
Go Debug Extension Architecture Overview
VS Code implements a generic, language-agnostic debugger UI based on Debug Adapter Protocol (DAP), an abstract protocol for communicating with debugger backend. Previously, the Go extension used an intermediary typescript program (legacy debug adapter) to launch Delve and adapt Delve to DAP. With the new, native DAP implementation in Delve, the intermediary program is no longer necessary, and efficient and tight integration with Delve becomes possible.
For information on debugging using the legacy debug adapter, please see the old Debugging Documentation. Note that many new or enhanced features discussed in this document may not be available with the legacy debug adapter.
dlv-dap
dlv-dap
dlv-dap${GOPATH}/bin${GOBIN}${PATH}Pathdlv-dapGo: Locate Configured Go Tools
dlv-dap~/go/bin/
If your Go version is 1.16 or newer:
$ GOBIN=/tmp/ go install github.com/go-delve/delve/cmd/dlv@master
$ mv /tmp/dlv $GOPATH/bin/dlv-dap
If your Go version is older than 1.16:
$ cd $(mktemp -d)
$ GO111MODULE=on GOBIN=/tmp/ go get github.com/go-delve/delve/cmd/dlv@master
$ mv /tmp/dlv $GOPATH/bin/dlv-dap
go.alternateTools
"go.alternateTools": {
"dlv-dap": "<absolute path to your dlv binary>"
}
Remote Debugging
Remote debugging is the debug mode intended to work with a debugger and target running on a different machine or a container. Support for remote debugging using Delve’s native DAP implementation is still a work-in-progress. This section describes a current temporary workaround and its limitations. If the following workaround is not working for your case, please file an issue and help us understand remote debugging use cases better.
dlv --headless
$ dlv-dap dap --listen=:12345
launchdlv-dap-gcflags='all=-N -l'
{
"name": "Connect to server (DAP)",
"type": "go",
"debugAdapter": "dlv-dap",
"request": "launch",
"port": 12345,
"host": "127.0.0.1",
"mode": "exec",
"program": "/absolute/path/to/remote/workspace/program/executable",
"substitutePath": [
{ "from": ${workspaceFolder}, "to": "/path/to/remote/workspace" },
...
]
}
Or have the binary compiled by dlv-dap by modifying the above configuration to use:
"mode": "debug",
"program": "/absolute/path/to/remote/workspace/package",
"port"host:portprogramsubstitutePath
⚠️ Limitations
dlv --headlessdap"attach"processId--allow-multiclient--continuedebugtestlaunchdlvdlv-dapdlv-dapgo buildgo test
Running Debugee Externally
console
Reporting Issues
dlv-dapdlv-dap
Please report issues in our issue tracker with the following information.
go versiongo version -m code --versionlaunch.json
Collecting Logs
{
"name": "Launch file",
"type": "go",
"trace": "verbose",
"showLog": true,
"logOutput": "dap",
...
}
logOutputshowLoglaunch.jsontrace
Go Debug
Developing
Code location
service/dap
src/goDebugFactory.tstest/integration/goDebug.test.ts
Testing
"go.alternateTools"
"go.alternateTools": {
"dlv-dap": <path_to_your_delve>
}
If you are having issues with seeing logs and/or suspect problems in the extension's integration, you can start the Delve DAP server from a separate terminal and configure the extension to directly connect to it. Please remember to [file an issue](https://github.com/golang/vscode-go/issues/new) if you encounter any logging-related problems.
$ dlv-dap dap --listen=:12345 --log --log-output=dap
{
"name": "Launch file",
"type": "go",
"request": "launch",
"debugAdapter": "dlv-dap",
...
"port": 12345
}
FAQs
Why does my debug session stop when I set breakpoints?
To support being able to set breakpoints while the program is running, the debug adapter needs to stop the program. Due to the extra synchronization required to correctly resume the program, the debug adapter currently sends a stopped event. This means that if you are editing breakpoints while the program is running, you will need to hit continue to continue your debug session. We plan to change the behavior of the debug adapter for more seamless editing of breakpoints. You can track the progress here.
dlvLoadConfigmaxStringLen
dlvLoadConfig
Copy as ExpressionCopy Value
Please open an issue if this is not sufficient for your use case or if you have any additional feedback.
invalid command
When stepping through a program on a particular goroutine, the debugger will make sure that the step is completed, even when interrupted by events on a different goroutine. If a breakpoint is hit on a different goroutine, the debug adapter will stop the program execution to allow you to inspect the state, even though the step request is still active.
invalid command
Continue
Breakpoints