vscode-go
vscode-go copied to clipboard
debug: support stopOnEntry status/commands the same as the dlv terminal
What version of Go, VS Code & VS Code Go extension are you using?
Version Information
- Run
go version
to get version of Go from the VS Code integrated terminal.- go version go1.12 linux/amd64
- Run
gopls -v version
to get version of Gopls from the VS Code integrated terminal.
Build info
----------
golang.org/x/tools/gopls v0.7.1
golang.org/x/tools/[email protected] h1:Mh3Z8Xcoq3Zy7ksSlwDV/nzQSbjFf06A+L+F8YHq55U=
github.com/google/[email protected] h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/sergi/[email protected] h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
golang.org/x/[email protected] h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/[email protected] h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/[email protected] h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
golang.org/x/[email protected] h1:ZC/gVBZl8poJyKzWLxxlsmhayVGosF4mohR35szD5Bg=
golang.org/x/[email protected] h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
mvdan.cc/[email protected] h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA=
mvdan.cc/xurls/[email protected] h1:NSZPykBXJFCetGZykLAxaL6SIpvbVy/UFEniIfHAa8A=
- Run
code -v
orcode-insiders -v
to get version of VS Code or VS Code Insiders.- 1.60.2 7f6ab5485bbc008386c4386d08766667e155244e x64
- Check your installed extensions to get the version of the VS Code Go extension
- v0.28.1
- Run Ctrl+Shift+P (Cmd+Shift+P on Mac OS) >
Go: Locate Configured Go Tools
command.
Checking configured tools....
GOBIN: undefined
toolsGopath:
gopath: /home/pi/go
GOROOT: /usr/local/go
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin:/home/pi/go/bin:/usr/local/go/bin:/home/pi/go/bin
go: /usr/local/go/bin/go: go version go1.12 linux/amd64
gopkgs: /home/pi/go/bin/gopkgs: go version -m failed: Error: Command failed: /usr/local/go/bin/go version -m /home/pi/go/bin/gopkgs
flag provided but not defined: -m
usage: go version
Run 'go help version' for details.
go-outline: /home/pi/go/bin/go-outline: go version -m failed: Error: Command failed: /usr/local/go/bin/go version -m /home/pi/go/bin/go-outline
flag provided but not defined: -m
usage: go version
Run 'go help version' for details.
gotests: /home/pi/go/bin/gotests: go version -m failed: Error: Command failed: /usr/local/go/bin/go version -m /home/pi/go/bin/gotests
flag provided but not defined: -m
usage: go version
Run 'go help version' for details.
gomodifytags: /home/pi/go/bin/gomodifytags: go version -m failed: Error: Command failed: /usr/local/go/bin/go version -m /home/pi/go/bin/gomodifytags
flag provided but not defined: -m
usage: go version
Run 'go help version' for details.
impl: /home/pi/go/bin/impl: go version -m failed: Error: Command failed: /usr/local/go/bin/go version -m /home/pi/go/bin/impl
flag provided but not defined: -m
usage: go version
Run 'go help version' for details.
goplay: /home/pi/go/bin/goplay: go version -m failed: Error: Command failed: /usr/local/go/bin/go version -m /home/pi/go/bin/goplay
flag provided but not defined: -m
usage: go version
Run 'go help version' for details.
dlv: /home/pi/go/bin/dlv: go version -m failed: Error: Command failed: /usr/local/go/bin/go version -m /home/pi/go/bin/dlv
flag provided but not defined: -m
usage: go version
Run 'go help version' for details.
dlv-dap: /home/pi/go/bin/dlv-dap: go version -m failed: Error: Command failed: /usr/local/go/bin/go version -m /home/pi/go/bin/dlv-dap
flag provided but not defined: -m
usage: go version
Run 'go help version' for details.
staticcheck: not installed
gopls: /home/pi/go/bin/gopls: go version -m failed: Error: Command failed: /usr/local/go/bin/go version -m /home/pi/go/bin/gopls
flag provided but not defined: -m
usage: go version
Run 'go help version' for details.
go env
Workspace Folder (demo): /home/pi/github.com/xujintao/gousage/demo
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/pi/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/pi/go"
GOPROXY="https://goproxy.io"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build544247226=/tmp/go-build -gno-record-gcc-switches"
Share the Go related settings you have added/edited
Run Preferences: Open Settings (JSON)
command to open your settings.json file.
{
"go.formatTool": "goimports"
}
Describe the bug
Launching program with stopOnEntry true in launch.json has no effect but leave "Unable to produce stack trace: unknown goroutine1" in CALL STACK section at "Run and Debug".
When set stopOnEntry as true, F5's behave should keep consistent with dlv-dap cmd e.g. stop on entry and show the entry point code.
Steps to reproduce the behavior:
1, main.go and launch.json
package main
func main() {
println(1)
}
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"stopOnEntry": true,
"mode": "auto",
"program": "${fileDirname}"
}
]
}
2, cd to workspace and run dlv
pi@dev:demo$ dlv-dap debug --check-go-version=false main.go
Type 'help' for list of commands.
(dlv) ls
> _rt0_amd64_linux() /usr/local/go/src/runtime/rt0_linux_amd64.s:8 (PC: 0x450f00)
Warning: debugging optimized function
3: // license that can be found in the LICENSE file.
4:
5: #include "textflag.h"
6:
7: TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
=> 8: JMP _rt0_amd64(SB)
9:
10: TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0
11: JMP _rt0_amd64_lib(SB)
(dlv)
3, Open another shell and use readelf inspect the entry point of the tmp debug file built by dlv
pi@dev:demo$ readelf -h __debug_bin | grep Entry
Entry point address: 0x450f00
pi@dev:demo$
4, Quit dlv and return back to vscode, press F5, there is nothing.
Thanks for the report @xujintao
It looks like Delve handled stopOnEntry
(see the stopped
event after configurationDone message. So, we can see the debug toolbox shows "continue" button") but the target is stopped before go runtime is initialized. So there is no 'goroutine' to return for Threads request and dlv dap returns a Dummy thread (thread 1). This Dummy thread causes the subsequent stackTrace request etc. to fail "Unable to produce stack trace: unknown goroutine 1". And without the stackTrace and the frame info, the VS Code fails to present exactly where the target is in.
The legacy adapter exhibits the same issue.
- How do we want to represent the stack trace before the runtime is initialized?
- How does this functionality work when https://github.com/golang/vscode-go/issues/1797 is implemented?
- Or how about making the debugger stop stop at
main.main
instead?
cc @polinasok @suzmue
My dlv-dap
version is: v1.7.3-0.20211002134430-6a282112cce8
VSCode version is: 1.60.2
[Verbose - 10:32:12.843] Config: {"name":"Launch Package","type":"go","request":"launch","stopOnEntry":true,"mode":"debug","trace":"verbose","logOutput":"debugger,dap","showLog":true,"program":".","__configurationTarget":5,"packagePathToGoModPathMap":{"/Users/hakim/projects/google/w":"/Users/hakim/projects/google/w"},"debugAdapter":"dlv-dap","apiVersion":2,"dlvLoadConfig":{"followPointers":true,"maxVariableRecurse":1,"maxStringLen":64,"maxArrayValues":64,"maxStructFields":-1},"showGlobalVariables":false,"substitutePath":[],"dlvToolPath":"/Users/hakim/go/bin/dlv-dap","env":{},"__buildDir":"/Users/hakim/projects/google/w"}
[Verbose - 10:32:12.844] session ff2cc822-3c21-4cba-a360-77588f74910a will start with {"name":"Launch Package","type":"go","request":"launch","stopOnEntry":true,"mode":"debug","trace":"verbose","logOutput":"debugger,dap","showLog":true,"program":".","__configurationTarget":5,"packagePathToGoModPathMap":{"/Users/hakim/projects/google/w":"/Users/hakim/projects/google/w"},"debugAdapter":"dlv-dap","apiVersion":2,"dlvLoadConfig":{"followPointers":true,"maxVariableRecurse":1,"maxStringLen":64,"maxArrayValues":64,"maxStructFields":-1},"showGlobalVariables":false,"substitutePath":[],"dlvToolPath":"/Users/hakim/go/bin/dlv-dap","env":{},"__buildDir":"/Users/hakim/projects/google/w"}
[Trace - 10:32:12.844] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"Starting: /Users/hakim/go/bin/dlv-dap dap --check-go-version=false --listen=127.0.0.1:56109 --log=true --log-output=debugger,dap --log-dest=3 from /Users/hakim/projects/google/w\n"}}
[Info - 10:32:12.845] Starting: /Users/hakim/go/bin/dlv-dap dap --check-go-version=false --listen=127.0.0.1:56109 --log=true --log-output=debugger,dap --log-dest=3 from /Users/hakim/projects/google/w
[Trace - 10:32:12.848] client -> {"command":"initialize","arguments":{"clientID":"vscode","clientName":"Visual Studio Code","adapterID":"go","pathFormat":"path","linesStartAt1":true,"columnsStartAt1":true,"supportsVariableType":true,"supportsVariablePaging":true,"supportsRunInTerminalRequest":true,"locale":"en-us","supportsProgressReporting":true,"supportsInvalidatedEvent":true,"supportsMemoryReferences":true},"type":"request","seq":1}
[Trace - 10:32:12.870] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"DAP server listening at: 127.0.0.1:56109\n2021-10-04T10:32:12-04:00 debug layer=dap DAP server pid = 80066\n"}}
[Info - 10:32:12.870] DAP server listening at: 127.0.0.1:56109
2021-10-04T10:32:12-04:00 debug layer=dap DAP server pid = 80066
[Verbose - 10:32:12.871] Running dlv dap server: port=56109 pid=80066
[Trace - 10:32:12.872] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:12-04:00 debug layer=dap [<- from client]{\"seq\":1,\"type\":\"request\",\"command\":\"initialize\",\"arguments\":{\"clientID\":\"vscode\",\"clientName\":\"Visual Studio Code\",\"adapterID\":\"go\",\"locale\":\"en-us\",\"linesStartAt1\":true,\"columnsStartAt1\":true,\"pathFormat\":\"path\",\"supportsVariableType\":true,\"supportsVariablePaging\":true,\"supportsRunInTerminalRequest\":true,\"supportsMemoryReferences\":true,\"supportsProgressReporting\":true,\"supportsInvalidatedEvent\":true}}\n2021-10-04T10:32:12-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"response\",\"request_seq\":1,\"success\":true,\"command\":\"initialize\",\"body\":{\"supportsConfigurationDoneRequest\":true,\"supportsFunctionBreakpoints\":true,\"supportsConditionalBreakpoints\":true,\"supportsEvaluateForHovers\":true,\"supportsSetVariable\":true,\"supportsExceptionInfoRequest\":true,\"supportTerminateDebuggee\":true,\"supportsDelayedStackTraceLoading\":true,\"supportsLogPoints\":true,\"supportsClipboardContext\":true}}\n"}}
[Info - 10:32:12.872] 2021-10-04T10:32:12-04:00 debug layer=dap [<- from client]{"seq":1,"type":"request","command":"initialize","arguments":{"clientID":"vscode","clientName":"Visual Studio Code","adapterID":"go","locale":"en-us","linesStartAt1":true,"columnsStartAt1":true,"pathFormat":"path","supportsVariableType":true,"supportsVariablePaging":true,"supportsRunInTerminalRequest":true,"supportsMemoryReferences":true,"supportsProgressReporting":true,"supportsInvalidatedEvent":true}}
2021-10-04T10:32:12-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":1,"success":true,"command":"initialize","body":{"supportsConfigurationDoneRequest":true,"supportsFunctionBreakpoints":true,"supportsConditionalBreakpoints":true,"supportsEvaluateForHovers":true,"supportsSetVariable":true,"supportsExceptionInfoRequest":true,"supportTerminateDebuggee":true,"supportsDelayedStackTraceLoading":true,"supportsLogPoints":true,"supportsClipboardContext":true}}
[Trace - 10:32:12.872] client <- {"seq":0,"type":"response","request_seq":1,"success":true,"command":"initialize","body":{"supportsConfigurationDoneRequest":true,"supportsFunctionBreakpoints":true,"supportsConditionalBreakpoints":true,"supportsEvaluateForHovers":true,"supportsSetVariable":true,"supportsExceptionInfoRequest":true,"supportTerminateDebuggee":true,"supportsDelayedStackTraceLoading":true,"supportsLogPoints":true,"supportsClipboardContext":true}}
[Trace - 10:32:12.876] client -> {"command":"launch","arguments":{"name":"Launch Package","type":"go","request":"launch","stopOnEntry":true,"mode":"debug","trace":"verbose","logOutput":"debugger,dap","showLog":true,"program":".","__configurationTarget":5,"packagePathToGoModPathMap":{"/Users/hakim/projects/google/w":"/Users/hakim/projects/google/w"},"debugAdapter":"dlv-dap","apiVersion":2,"dlvLoadConfig":{"followPointers":true,"maxVariableRecurse":1,"maxStringLen":64,"maxArrayValues":64,"maxStructFields":-1},"showGlobalVariables":false,"substitutePath":[],"dlvToolPath":"/Users/hakim/go/bin/dlv-dap","env":{},"__buildDir":"/Users/hakim/projects/google/w","__sessionId":"ff2cc822-3c21-4cba-a360-77588f74910a"},"type":"request","seq":2}
[Trace - 10:32:12.877] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:12-04:00 debug layer=dap [<- from client]{\"seq\":2,\"type\":\"request\",\"command\":\"launch\",\"arguments\":{\"name\":\"Launch Package\",\"type\":\"go\",\"request\":\"launch\",\"stopOnEntry\":true,\"mode\":\"debug\",\"trace\":\"verbose\",\"logOutput\":\"debugger,dap\",\"showLog\":true,\"program\":\".\",\"__configurationTarget\":5,\"packagePathToGoModPathMap\":{\"/Users/hakim/projects/google/w\":\"/Users/hakim/projects/google/w\"},\"debugAdapter\":\"dlv-dap\",\"apiVersion\":2,\"dlvLoadConfig\":{\"followPointers\":true,\"maxVariableRecurse\":1,\"maxStringLen\":64,\"maxArrayValues\":64,\"maxStructFields\":-1},\"showGlobalVariables\":false,\"substitutePath\":[],\"dlvToolPath\":\"/Users/hakim/go/bin/dlv-dap\",\"env\":{},\"__buildDir\":\"/Users/hakim/projects/google/w\",\"__sessionId\":\"ff2cc822-3c21-4cba-a360-77588f74910a\"}}\n"}}
[Info - 10:32:12.878] 2021-10-04T10:32:12-04:00 debug layer=dap [<- from client]{"seq":2,"type":"request","command":"launch","arguments":{"name":"Launch Package","type":"go","request":"launch","stopOnEntry":true,"mode":"debug","trace":"verbose","logOutput":"debugger,dap","showLog":true,"program":".","__configurationTarget":5,"packagePathToGoModPathMap":{"/Users/hakim/projects/google/w":"/Users/hakim/projects/google/w"},"debugAdapter":"dlv-dap","apiVersion":2,"dlvLoadConfig":{"followPointers":true,"maxVariableRecurse":1,"maxStringLen":64,"maxArrayValues":64,"maxStructFields":-1},"showGlobalVariables":false,"substitutePath":[],"dlvToolPath":"/Users/hakim/go/bin/dlv-dap","env":{},"__buildDir":"/Users/hakim/projects/google/w","__sessionId":"ff2cc822-3c21-4cba-a360-77588f74910a"}}
[Trace - 10:32:12.878] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:12-04:00 debug layer=dap debug backend is 'default'\n2021-10-04T10:32:12-04:00 debug layer=dap building program '.' in '/Users/hakim/projects/google/w' with flags ''\n"}}
[Info - 10:32:12.878] 2021-10-04T10:32:12-04:00 debug layer=dap debug backend is 'default'
2021-10-04T10:32:12-04:00 debug layer=dap building program '.' in '/Users/hakim/projects/google/w' with flags ''
[Trace - 10:32:13.234] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap running binary '/Users/hakim/projects/google/w/__debug_bin' in '/Users/hakim/projects/google/w'\n2021-10-04T10:32:13-04:00 info layer=debugger launching process with args: [/Users/hakim/projects/google/w/__debug_bin]\n"}}
[Info - 10:32:13.234] 2021-10-04T10:32:13-04:00 debug layer=dap running binary '/Users/hakim/projects/google/w/__debug_bin' in '/Users/hakim/projects/google/w'
2021-10-04T10:32:13-04:00 info layer=debugger launching process with args: [/Users/hakim/projects/google/w/__debug_bin]
[Trace - 10:32:13.495] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"event\",\"event\":\"initialized\"}\n"}}
[Info - 10:32:13.495] 2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{"seq":0,"type":"event","event":"initialized"}
[Trace - 10:32:13.496] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"response\",\"request_seq\":2,\"success\":true,\"command\":\"launch\"}\n"}}
[Info - 10:32:13.496] 2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":2,"success":true,"command":"launch"}
[Trace - 10:32:13.496] client <- {"seq":0,"type":"event","event":"initialized"}
[Trace - 10:32:13.496] client <- {"seq":0,"type":"response","request_seq":2,"success":true,"command":"launch"}
[Trace - 10:32:13.498] client -> {"command":"setFunctionBreakpoints","arguments":{"breakpoints":[]},"type":"request","seq":3}
[Trace - 10:32:13.499] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{\"seq\":3,\"type\":\"request\",\"command\":\"setFunctionBreakpoints\",\"arguments\":{\"breakpoints\":[]}}\n2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"response\",\"request_seq\":3,\"success\":true,\"command\":\"setFunctionBreakpoints\",\"body\":{\"breakpoints\":[]}}\n"}}
[Info - 10:32:13.500] 2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{"seq":3,"type":"request","command":"setFunctionBreakpoints","arguments":{"breakpoints":[]}}
2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":3,"success":true,"command":"setFunctionBreakpoints","body":{"breakpoints":[]}}
[Trace - 10:32:13.500] client <- {"seq":0,"type":"response","request_seq":3,"success":true,"command":"setFunctionBreakpoints","body":{"breakpoints":[]}}
[Trace - 10:32:13.508] client -> {"command":"configurationDone","type":"request","seq":4}
[Trace - 10:32:13.509] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{\"seq\":4,\"type\":\"request\",\"command\":\"configurationDone\",\"arguments\":{}}\n2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"event\",\"event\":\"stopped\",\"body\":{\"reason\":\"entry\",\"threadId\":1,\"allThreadsStopped\":true}}\n2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"response\",\"request_seq\":4,\"success\":true,\"command\":\"configurationDone\"}\n"}}
[Info - 10:32:13.509] 2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{"seq":4,"type":"request","command":"configurationDone","arguments":{}}
2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{"seq":0,"type":"event","event":"stopped","body":{"reason":"entry","threadId":1,"allThreadsStopped":true}}
2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":4,"success":true,"command":"configurationDone"}
[Trace - 10:32:13.509] client <- {"seq":0,"type":"event","event":"stopped","body":{"reason":"entry","threadId":1,"allThreadsStopped":true}}
[Trace - 10:32:13.510] client <- {"seq":0,"type":"response","request_seq":4,"success":true,"command":"configurationDone"}
[Trace - 10:32:13.515] client -> {"command":"threads","type":"request","seq":5}
[Trace - 10:32:13.515] client -> {"command":"threads","type":"request","seq":6}
[Trace - 10:32:13.517] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{\"seq\":5,\"type\":\"request\",\"command\":\"threads\"}\n"}}
[Info - 10:32:13.517] 2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{"seq":5,"type":"request","command":"threads"}
[Trace - 10:32:13.521] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"response\",\"request_seq\":5,\"success\":true,\"command\":\"threads\",\"body\":{\"threads\":[{\"id\":1,\"name\":\"Dummy\"}]}}\n2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{\"seq\":6,\"type\":\"request\",\"command\":\"threads\"}\n"}}
[Info - 10:32:13.521] 2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":5,"success":true,"command":"threads","body":{"threads":[{"id":1,"name":"Dummy"}]}}
2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{"seq":6,"type":"request","command":"threads"}
[Trace - 10:32:13.522] client <- {"seq":0,"type":"response","request_seq":5,"success":true,"command":"threads","body":{"threads":[{"id":1,"name":"Dummy"}]}}
[Trace - 10:32:13.524] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"response\",\"request_seq\":6,\"success\":true,\"command\":\"threads\",\"body\":{\"threads\":[{\"id\":1,\"name\":\"Dummy\"}]}}\n"}}
[Info - 10:32:13.524] 2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":6,"success":true,"command":"threads","body":{"threads":[{"id":1,"name":"Dummy"}]}}
[Trace - 10:32:13.524] client <- {"seq":0,"type":"response","request_seq":6,"success":true,"command":"threads","body":{"threads":[{"id":1,"name":"Dummy"}]}}
[Trace - 10:32:13.534] client -> {"command":"stackTrace","arguments":{"threadId":1,"startFrame":0,"levels":1},"type":"request","seq":7}
[Trace - 10:32:13.544] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{\"seq\":7,\"type\":\"request\",\"command\":\"stackTrace\",\"arguments\":{\"threadId\":1,\"levels\":1,\"format\":{}}}\n"}}
[Info - 10:32:13.544] 2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{"seq":7,"type":"request","command":"stackTrace","arguments":{"threadId":1,"levels":1,"format":{}}}
[Trace - 10:32:13.545] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap Unable to produce stack trace: unknown goroutine 1\n"}}
[Info - 10:32:13.545] 2021-10-04T10:32:13-04:00 debug layer=dap Unable to produce stack trace: unknown goroutine 1
[Trace - 10:32:13.546] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"response\",\"request_seq\":7,\"success\":false,\"command\":\"stackTrace\",\"message\":\"Unable to produce stack trace\",\"body\":{\"error\":{\"id\":2004,\"format\":\"Unable to produce stack trace: unknown goroutine 1\",\"showUser\":false}}}\n"}}
[Info - 10:32:13.546] 2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":7,"success":false,"command":"stackTrace","message":"Unable to produce stack trace","body":{"error":{"id":2004,"format":"Unable to produce stack trace: unknown goroutine 1","showUser":false}}}
[Trace - 10:32:13.546] client <- {"seq":0,"type":"response","request_seq":7,"success":false,"command":"stackTrace","message":"Unable to produce stack trace","body":{"error":{"id":2004,"format":"Unable to produce stack trace: unknown goroutine 1","showUser":false}}}
[Trace - 10:32:13.620] client -> {"command":"stackTrace","arguments":{"threadId":1,"startFrame":0,"levels":20},"type":"request","seq":8}
[Trace - 10:32:13.620] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{\"seq\":8,\"type\":\"request\",\"command\":\"stackTrace\",\"arguments\":{\"threadId\":1,\"levels\":20,\"format\":{}}}\n"}}
[Info - 10:32:13.621] 2021-10-04T10:32:13-04:00 debug layer=dap [<- from client]{"seq":8,"type":"request","command":"stackTrace","arguments":{"threadId":1,"levels":20,"format":{}}}
[Trace - 10:32:13.621] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:13-04:00 debug layer=dap Unable to produce stack trace: unknown goroutine 1\n2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"response\",\"request_seq\":8,\"success\":false,\"command\":\"stackTrace\",\"message\":\"Unable to produce stack trace\",\"body\":{\"error\":{\"id\":2004,\"format\":\"Unable to produce stack trace: unknown goroutine 1\",\"showUser\":false}}}\n"}}
[Info - 10:32:13.621] 2021-10-04T10:32:13-04:00 debug layer=dap Unable to produce stack trace: unknown goroutine 1
2021-10-04T10:32:13-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":8,"success":false,"command":"stackTrace","message":"Unable to produce stack trace","body":{"error":{"id":2004,"format":"Unable to produce stack trace: unknown goroutine 1","showUser":false}}}
[Trace - 10:32:13.622] client <- {"seq":0,"type":"response","request_seq":8,"success":false,"command":"stackTrace","message":"Unable to produce stack trace","body":{"error":{"id":2004,"format":"Unable to produce stack trace: unknown goroutine 1","showUser":false}}}
[Trace - 10:32:14.27] client -> {"command":"stackTrace","arguments":{"threadId":1,"startFrame":0,"levels":19},"type":"request","seq":9}
[Trace - 10:32:14.28] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:14-04:00 debug layer=dap [<- from client]{\"seq\":9,\"type\":\"request\",\"command\":\"stackTrace\",\"arguments\":{\"threadId\":1,\"levels\":19,\"format\":{}}}\n"}}
[Info - 10:32:14.28] 2021-10-04T10:32:14-04:00 debug layer=dap [<- from client]{"seq":9,"type":"request","command":"stackTrace","arguments":{"threadId":1,"levels":19,"format":{}}}
[Trace - 10:32:14.29] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:14-04:00 debug layer=dap Unable to produce stack trace: unknown goroutine 1\n"}}
[Info - 10:32:14.29] 2021-10-04T10:32:14-04:00 debug layer=dap Unable to produce stack trace: unknown goroutine 1
[Trace - 10:32:14.29] client <- {"seq":0,"type":"event","event":"output","body":{"category":"console","output":"2021-10-04T10:32:14-04:00 debug layer=dap [-> to client]{\"seq\":0,\"type\":\"response\",\"request_seq\":9,\"success\":false,\"command\":\"stackTrace\",\"message\":\"Unable to produce stack trace\",\"body\":{\"error\":{\"id\":2004,\"format\":\"Unable to produce stack trace: unknown goroutine 1\",\"showUser\":false}}}\n"}}
[Info - 10:32:14.30] 2021-10-04T10:32:14-04:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":9,"success":false,"command":"stackTrace","message":"Unable to produce stack trace","body":{"error":{"id":2004,"format":"Unable to produce stack trace: unknown goroutine 1","showUser":false}}}
[Trace - 10:32:14.30] client <- {"seq":0,"type":"response","request_seq":9,"success":false,"command":"stackTrace","message":"Unable to produce stack trace","body":{"error":{"id":2004,"format":"Unable to produce stack trace: unknown goroutine 1","showUser":false}}}
I rephrased the title because stopOnEntry
actually worked but UX needs to be improved.
Discussed with @polinasok and @suzmue.
Stopping at main.main
would have other side-effect and cause confusion, so not ideal.
We can instead extend @polinasok's idea to mark this condition explicit (https://github.com/polinasok/delve/pull/19) and @suzmue's idea to handle the stacktrace specially to clearly communicate it's stopped but there is no goroutine (or is it not possible to create a bogus frame that includes the program entry - platform-specific assembly file - as the stop point in case of launch+stopOnEntry
?)
Came here thinking stopOnEntry
was broken somehow, now I understand better what's going on. But I'm left wondering what the utility of the current form of stopOnEntry
is, if the only thing you can do is continue? Step in, over, and out all produce errors.
The obvious answer would be "place breakpoints", but I can do that before I start just as well.
Am I missing something?
Yes, the only thing users can do currently is to place breakpoints if she forgot to do, or to continue.
stopOnEntry
is modeled after dlv debug
or dlv test
behavior where you cannot do step in/over/out until the debugger is started.
% dlv debug
Type 'help' for list of commands.
(dlv) si
Stopped at: 0xf154001
=> 1: no source available
(dlv) n
Stopped at: 0xf154001
=> 1: no source available
Command failed: no source for PC 0xf154001
@xujintao @mgabeler-lee-6rs what did you expect to see when stopOnEntry
is true?
In other languages, stopOnEntry typically stops on the first line of code (static initializers if there are any, which I think there always will be in Go just from stdlib), or the first line of "main".
Conceptually, I think of it as if you put a breakpoint in every possible source location, stopOnEntry would stop on the first one of those that would get hit.
@mgabeler-lee-6rs
So what would be a useful "first line of code" be in a Go program? When you used a non-default true stopOnEntry value, what was your intention?
The obvious answer would be "place breakpoints", but I can do that before I start just as well.
Technically the breakpoints you set cannot be verified until your debug session starts and code is loaded. So there is a difference between setting them before the session and on entry. Or you could set them before the session, but then stop on entry to validate in the side bar that they all registered correctly. If they don't the marker will turn grey and will have a hover error message.
This option is also a way to stop on entry when attaching to a running process, where you will have goroutines and stack.
Originally, i want to debug the startup code or some code preparing for language specified, golang here is _rt0_amd64_linux / _rt0_amd64 / rt0_go. The only way to debug that is to set stopOnEntry as true for we can not set breakpoint there directlly.
In fact, several days ago, i have found an alternative tool to debug the entry point of golang, which is lldb(vscode-lldb). launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "dlv",
"type": "go",
"request": "launch",
// "stopOnEntry": true,
"mode": "auto",
"program": "${fileDirname}"
},
{
"name": "lldb",
"type": "lldb",
"request": "launch",
"initCommands": ["settings set target.x86-disassembly-flavor intel"],
"program": "${workspaceFolder}/build/${fileBasenameNoExtension}",
"preRunCommands": [
"breakpoint set -n runtime.main",
"breakpoint set -n main.main",
"breakpoint list"
],
"stopOnEntry": true,
"args": [],
"cwd": "${workspaceFolder}",
"postRunCommands": [],
"exitCommands": [],
"preLaunchTask": "Build Go"
}
]
}
tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Build Go",
"type": "shell",
"command": "go",
"args": [
"build",
"-gcflags='-l -N'",
// "-ldflags='-s -w'",
// "-ldflags='-w'",
"-o",
"${workspaceFolder}/build/${fileBasenameNoExtension}",
"${file}"
]
}
]
}
Although vscode-lldb can be stopped by stopOnEntry, it can not support golang well yet currently, for example, variables show.
@xujintao Do I understand correctly is that the issue is not so much that it is not obvious that the code hit stopOnEntry (as the title currently indicates), but more that the current point where the code stops is not very useful? And in particular, you would like to use that option to debug runtime initialization code? Is dlv's command-line functionality sufficient for that? While on a Mac, one gets "no source available", on Linux it looks like we can use step-instruction
, print regs
and vars
at the specified location.
So what would be a useful "first line of code" be in a Go program? When you used a non-default true stopOnEntry value, what was your intention?
On the day I posted here, I was wanting to stop at the start of main()
, but at other times I've also wanted to debug static initializers. Both are clearly valid use cases, so I'd imagine for this to be helpful, it would need to provide the user some way to select which they intended in the end.
Another option I could see that would still be useful would be to allow "step in" from the current state to step to the first initializer. Whether abusing the metaphors to have "step over" instead step to the first line of main()
might be getting too clever :)
This option is also a way to stop on entry when attaching to a running process, where you will have goroutines and stack.
Hadn't thought of that one, that's also a good use case.
@polinasok
Do I understand correctly is that the issue is not so much that it is not obvious that the code hit stopOnEntry (as the title currently indicates), but more that the current point where the code stops is not very useful?
What i understand is that the stopOnEntry should stop on entry, but now it leaves me nothing. If it leaves me some code,which maybe either the entry point address of ELF or main.main, we can talk about whether it is useful.
And in particular, you would like to use that option to debug runtime initialization code?
Yes, i would like to use that option to debug runtime initialization code.
Is dlv's command-line functionality sufficient for that?
Yes, dlv's command-line is sufficient for that, so does gdb, lldb, and vscode-lldb.
While on a Mac, one gets "no source available", on Linux it looks like we can use step-instruction, print regs and vars at the specified location.
If you are talking about the stopOnEntry, my ubuntu leaves me nothing when debugging.
To stop at main.main
, you can set a function breakpoint in the Breakpoints viewlet.
Yes, dlv's command-line is sufficient for that, so does gdb, lldb, and vscode-lldb.
While on a Mac, one gets "no source available", on Linux it looks like we can use step-instruction, print regs and vars at the specified location.
If you are talking about the stopOnEntry, my ubuntu leaves me nothing when debugging.
What I meant is that on entry on Linux dlv itself supports code location and other commands as they can be used from the terminal client. Vscode-go currently does not, but it is just a matter of proxying the requests correctly to the dlv backend.
In general, if dlv supports something with its terminal client that vscode-go doesn't support, we can likely support that in vscode-go. But beyond that vscode-go is limited by what dlv supports. For example, when you click stepIn
, it is translated into dlv's step
and stepOver
into next
. If using step
and next
when stopped on entry in the dlv terminal client is what you expect, we can add support for that from vscode-go. If you want to redefine the meaning of those commands, the change must happen in dlv.
If you would like richer support in dlv for debugging initializers, you need to file a feature request in the delve repo.
We do not use other backends such as gdb.
@polinasok
In general, if dlv supports something with its terminal client that vscode-go doesn't support, we can likely support that in vscode-go.
Yes, it is all what i am concerned about that dlv terminal client now supports stopOnEntry while vscode-go doesn't. If vscode-go hasn't support stopOnEntry, it should make an annotation in document. For example, add a "haven't yet support" tips on stopOnEntry in launch.json.