-
Notifications
You must be signed in to change notification settings - Fork 645
Debugging Go code using VS Code
There are 2 ways to install delve
- Run the command
Go: Install/Update Tools
, selectdlv
, pressOk
to install/update delve - Or install it manually install delve as per the Installation Instructions.
The below settings are used by the debugger. You may not need to add/change any of them to have debugging working in simple cases, but do give them a read sometime
-
go.gopath
. See GOPATH in VS Code -
go.inferGopath
. See GOPATH in VS Code -
go.delveConfig
-
apiVersion
: Controls the version of delve apis to be used when launching the delve headless server. Default is 2. -
dlvLoadConfig
: Not applicable whenapiVersion
is 1. The configuration passed to delve. Controls various features of delve that affects the variables shown in the debug pane.-
maxStringLen
: maximum number of bytes read from a string -
maxArrayValues
: maximum number of elements read from an array, a slice or a map -
maxStructFields
: maximum number of fields read from a struct, -1 will read all fields -
maxVariableRecurse
: how far to recurse when evaluating nested types -
followPointers
: requests pointers to be automatically dereferenced
-
-
Some common cases where you might want to tweak the configurations passed to delve
- Change the default cap of 64 on string and array length when inspecting variables in the debug viewlet.
- Evaluate variables that are nested when inspecting them in the debug viewlet.
Once delve is installed and is available in your $PATH, run the command Debug: Open launch.json
. If you didnt already have a launch.json file, this will create one with the below default configuration.
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}",
"env": {},
"args": []
}
]
}
The program
option is mandatory and takes path to a folder or file.
- This can refer to a package folder to debug, or a file within that folder.
- This should be a full path and not relative.
- Use
${workspaceFolder}
to debug package at the root of the workspace that is opened in VS Code - Use
${file}
to debug the current file. - Use
${fileDirname}
to debug the package to which the current file belongs to.
The mode
parameter can be set to:
-
debug
to compile the contents of the program folder and launch under the debugger. [default] -
test
to debug tests in the program folder. To debug a single test, pass-test.run
and the Test name as args. Additionally, you can pass-test.v
to get verbose output as well. -
auto
to automatically detect whether to usedebug
ortest
based in the current file that is open. -
exec
to run a pre-built binary specified in program, for example"program":"${workspaceRoot}/mybin"
. -
remote
to attach to a remote headless Delve server. You must manually run Delve on the remote machine, and provide the additionalremotePath
,host
andport
debug configuration options pointing at the remote machine.
If your build needs build tags (e.g. go build -tags=whatever_tag
), then add the parameter buildFlags
with the content "-tags=whatever_tag"
. Multiple tags are supported, by enclosing them in single quotes within the double quotes like so: "-tags='first_tag second_tag third_tag'"
.
In version 0.6.66 or lesser of the Go extension, the debugger cannot read your settings. It figures out the GOPATH from either the environment variables or from the path provided in the program
option. If you have set multiple GOPATHs in the go.gopath
setting, pass the same in the env
option of the launch.json
as an environment variable.
As of 0.6.67 version, the debugger will inherit the GOPATH from settings. Run Go: Current GOPATH
command to see the GOPATH being used by the Go extension and the debugger.
As of 0.6.54 version of the Go extension, you can now make use of snippets while editing the launch.json file. Type "Go" and you will get debug configuration snippets for debugging current file/package, a test function etc.
Set showLog
attribute in your debug configuration to true
. You will see logs in the debug console from delve.
Set trace
attribute in your debug configuration to verbose
. You will see logs in the debug console from the Go extension's debug adapter. These logs will be saved to a file whose path will be printed at the beginning in the debug console.
Set logOutput
attribute in your debug configuration to rpc
. You will see logs corresponding to the RPC messages going back and forth between VS Code and delve. Note that this first requires to set showLog
to true
.
The logOutput
attribute corresponds to the --log-output
flag used by delve and can be a comma separated list of components that should produce debug output.
If you want to dig deeper and debug the debugger using source code of this extension, see building-and-debugging-the-extension
To remote debug using VS Code, you must first run a headless Delve server on the target machine. For example:
$ dlv debug --headless --listen=:2345 --log
Any arguments that you want to pass to the program you are debugging must be passed to this Delve server that runs on the target machine. For example:
$ dlv debug --headless --listen=:2345 --log -- -myArg=123
Note: Do not pass the flag
–api-version=2
to dlv. The Go extension doesn't support v2 of delve APIs yet.
Then, create a remote debug configuration in VS Code launch.json
.
{
"name": "Remote",
"type": "go",
"request": "launch",
"mode": "remote",
"remotePath": "${workspaceRoot}",
"port": 2345,
"host": "127.0.0.1",
"program": "${workspaceRoot}",
"env": {}
}
Note:
remotePath
must be correct otherwise breakpoints will silently fail
When you launch the debugger with this new Remote
target selected, VS Code will send debugging
commands to the dlv
server you started previously instead of launching it's own dlv
instance against your app.
The above example runs both the headless dlv
server and the VS Code debugger locally on the same machine. For an
example of running these on different hosts, see the example of debugging a process running in a docker host at https://github.com/lukehoban/webapp-go/tree/debugging.
Breakpoints can be added either before starting a debug session or when another breakpoint is hit. This is a limitation from delve which doesn't allow interacting with the target process without pausing/stopping it.
The feature to pause the debugging program is being tracked in issue number 978.
Like the error message says, the extension cannot find dlv
. Remember, the debug adapter cannot read the VS Code settings.
Solution: Add the location where dlv is installed to your PATH. You can find this location by running which dlv
or where dlv
The debugger is not using the right GOPATH. This shouldn't happen, if it does, log a bug.
Solution: Until the bug you logged is resolved, the work around is to add the GOPATH as an env var in the env
property in the launch.json
file.
You have dlv
running just fine from command line, but VS Code gives this access related error.
This can happen if the extension is trying to run the dlv
binary from a wrong location.
The Go extension first tries to find dlv
in your $GOPATH/bin and then in your $PATH.
Solution: Run which dlv
in the command line. If this doesn't match your GOPATH/bin
, then delete the dlv
file in
your GOPATH/bin
You may see this in the debug console, while trying to run in the test
mode. This happens when the program
attribute points to a folder with no test files.
Solution: Ensure that the program
attribute points to the folder that contains the test files you want to run.
This usually happens in OSX due to signing issues. See the discussions in please see #717, #269 and derekparker/delve/357
Solution: You may have to uninstall dlv and install it manually as per instructions
Docker has security settings preventing ptrace(2) operations by default within the container.
Solution: To run your container insecurely, pass --security-opt=seccomp:unconfined
to docker run when starting. Reference: derekparker/delve/515
This error can show up for Mac users using delve of version 0.12.2 or above. Not sure why, but doing a xcode-select --install
has solved the problem for users who have seen this issue.
Check the version of delve api being used in the remote delve process i.e check the value for the flag –api-version
. This needs to match the version used by the Go extension which uses version 2 by default. You can change the api version being used by the extension by editing the debug configuration in the launch.json file.
Add "trace": "verbose"
to your debug configuration and debug in VS Code. This will send logs to the debug console where you can see the actual call being made to dlv. You can copy that and run it in your terminal