delve
delve copied to clipboard
Non-stop mode debugging
dellve: 0.12.1 go:1.7.4 os: macos sierra 10.12.3
background: when i debugging a websocket program, the goroutine who should pong the server's ping request in backgrond but it's pause automatically when breakpoint hit in other functionality, so the websocket connection will close after timeout. So i want that goroutine keep running. example:
func main(){
go handleWS()
print("abc") //<- breakpoint set here
}
func handleWS(){
//handle websocket ping pong
.....
}
It's possible to implement this but very complicated.
@aarzilli Thanks for your reply, it's really helpful for us when debugging web applications
+1 to this. Now I understand why I see all the goroutines with state "PAUSED ON BREAKPOINT" in VSCODE. I believe that letting all other threads/goroutines run until they reach a breakpoint is pretty common in debuggers, right? Shouldn't delve just pause any goroutine when it hits a breakpoint?
And what should happen when a second breakpoint is hit in the background?
@au-phiware when a breakpoint is hit in the background, then that goroutine is paused on that breakpoint, that's what happens while debugging java, for example.
To make things clear: say we have 3 goroutines, 2 share the same code (let's call codeA
). When you put a breakpoint in codeA
and that breakpoint is hit by these 2 goroutines, then only these 2 goroutines should pause at the breakpoint, the other one should be left running. Also goroutines sharing same code (and hence the same breakpoint) doesn't necessarily mean that they will both stop at the same point.
I'm not trying to say it's an easy feature to implement, though I think it's the desired behavior and also probably many other debuggers work that way.
This feature would help tremendously when debugging multithreaded code with event listeners, endpoint handlers, and other background GoRoutines running in a Kubernetes cluster. For instance, I have an application that listens for HTTP requests and is deployed to Kubernetes. If, while I am stepping through a request on one endpoint, a sufficient number of requests come in on the endpoint configured as the liveness probe, Kubernetes will kill the pod in the middle of my debugging session. If I can specify that the breakpoint should only halt the current GoRoutine and not the entire application, then the liveness probe endpoint can successfully handle the request(s), keeping Kubernetes happy and preventing the killing of the pod being debugged.
For reference, the term "non-stop mode" comes from GDB, where it means that the debugger stops one thread* of the target program, while other threads continue to run.
In Go, the unit of concurrent work is a goroutine, not a thread. Go's runtime has its own scheduler, which may schedule more than one goroutine per thread. Therefore, stopping a single thread is not enough to provide a "non-stop mode" experience equivalent to that in GDB.
For example, let's say you have a program with two goroutines, A and B. You want to stop A, and allow B to continue to run. At the time you want to stop A, both A and B are scheduled to run on the same thread. If you stop that thread, both A and B stop.
If I understand it correctly, support for "non-stop mode" depends on the ability to stop a single goroutine, tracked by https://github.com/go-delve/delve/issues/1529. That ability depends on Go runtime support. The relevant runtime issue is https://github.com/golang/go/issues/31132. The issue was discussed at the go runtime meeting in September 2022.
* thread throughout means operating system thread.