service/dap: limit the number of goroutines to return from a threads request (#2595)

This adds a cap and a log message if there are many goroutines. This will help
prevent the debugger from freezing, but does not yet address making sure the
interesting goroutines are the ones that are returned.

Updates golang/vscode-go#129
This commit is contained in:
Suzy Mueller 2021-07-21 10:26:40 -05:00 committed by GitHub
parent 658d36cb19
commit 3941af1d02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -191,6 +191,8 @@ const (
// what is presented. A common use case of a call injection is to // what is presented. A common use case of a call injection is to
// stringify complex data conveniently. // stringify complex data conveniently.
maxStringLenInCallRetVars = 1 << 10 // 1024 maxStringLenInCallRetVars = 1 << 10 // 1024
// Max number of goroutines that we will return.
maxGoroutines = 1 << 10
) )
// NewServer creates a new DAP Server. It takes an opened Listener // NewServer creates a new DAP Server. It takes an opened Listener
@ -1456,7 +1458,7 @@ func (s *Server) onThreadsRequest(request *dap.ThreadsRequest) {
return return
} }
gs, _, err := s.debugger.Goroutines(0, 0) gs, next, err := s.debugger.Goroutines(0, maxGoroutines)
if err != nil { if err != nil {
switch err.(type) { switch err.(type) {
case proc.ErrProcessExited: case proc.ErrProcessExited:
@ -1469,6 +1471,10 @@ func (s *Server) onThreadsRequest(request *dap.ThreadsRequest) {
return return
} }
if next >= 0 {
s.logToConsole(fmt.Sprintf("too many goroutines, only loaded %d", len(gs)))
}
threads := make([]dap.Thread, len(gs)) threads := make([]dap.Thread, len(gs))
if len(threads) == 0 { if len(threads) == 0 {
// Depending on the debug session stage, goroutines information // Depending on the debug session stage, goroutines information