Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

service/dap: Add panic guard to DAP handlers #1895

Merged
merged 8 commits into from
Feb 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.11
require (
github.com/cosiner/argv v0.0.0-20170225145430-13bacc38a0a5
github.com/cpuguy83/go-md2man v1.0.8 // indirect
github.com/google/go-dap v0.1.0
github.com/google/go-dap v0.2.0
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/mattn/go-colorable v0.0.0-20170327083344-ded68f7a9561
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-dap v0.1.0 h1:UzVzngq6yBR+bJVnTM8mjcdKrQnYR7m7U7JpNSnEo48=
github.com/google/go-dap v0.1.0/go.mod h1:5q8aYQFnHOAZEMP+6vmq25HKYAEwE+LF5yh7JKrrhSQ=
github.com/google/go-dap v0.2.0 h1:whjIGQRumwbR40qRU7CEKuFLmePUUc2s4Nt9DoXXxWk=
github.com/google/go-dap v0.2.0/go.mod h1:5q8aYQFnHOAZEMP+6vmq25HKYAEwE+LF5yh7JKrrhSQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
Expand Down
8 changes: 0 additions & 8 deletions service/dap/daptest/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,6 @@ func (c *Client) UnkownRequest() {
c.send(request)
}

// UnkownProtocolMessage triggers dap.DecodeProtocolMessageFieldError.
func (c *Client) UnkownProtocolMessage() {
m := &dap.ProtocolMessage{}
m.Seq = -1
m.Type = "unknown"
c.send(m)
}

// UnknownEvent triggers dap.DecodeProtocolMessageFieldError.
func (c *Client) UnknownEvent() {
event := &dap.Event{}
Expand Down
1 change: 1 addition & 0 deletions service/dap/error_ids.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dap
// Unique identifiers for messages returned for errors from requests.
const (
UnsupportedCommand int = 9999
InternalError int = 8888

// The values below come from the vscode-go debug adaptor.
// Although the spec says they should be unique, the adaptor
Expand Down
35 changes: 26 additions & 9 deletions service/dap/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ import (
"github.com/go-delve/delve/service"
"github.com/go-delve/delve/service/api"
"github.com/go-delve/delve/service/debugger"
"github.com/google/go-dap" // dap
"github.com/google/go-dap"
"github.com/sirupsen/logrus"
)


// Server implements a DAP server that can accept a single client for
// a single debug session. It does not support restarting.
// The server operates via two goroutines:
Expand Down Expand Up @@ -161,13 +160,19 @@ func (s *Server) serveDAPCodec() {
}
return
}
// TODO(polina) Add a panic guard,
// so we do not kill user's process when delve panics.
s.handleRequest(request)
}
}

func (s *Server) handleRequest(request dap.Message) {
defer func() {
// In case a handler panics, we catch the panic and send an error response
// back to the client.
if ierr := recover(); ierr != nil {
s.sendInternalErrorResponse(request.GetSeq(), fmt.Sprintf("%v", ierr))
}
}()

jsonmsg, _ := json.Marshal(request)
s.log.Debug("[<- from client]", string(jsonmsg))

Expand Down Expand Up @@ -253,11 +258,8 @@ func (s *Server) handleRequest(request dap.Message) {
default:
// This is a DAP message that go-dap has a struct for, so
// decoding succeeded, but this function does not know how
// to handle. We should be sending an ErrorResponse, but
// we cannot get to Seq and other fields from dap.Message.
// TODO(polina): figure out how to handle this better.
// Consider adding GetSeq() method to dap.Message interface.
s.log.Errorf("Unable to process %#v\n", request)
// to handle.
s.sendInternalErrorResponse(request.GetSeq(), fmt.Sprintf("Unable to process %#v\n", request))
}
}

Expand Down Expand Up @@ -410,6 +412,21 @@ func (s *Server) sendErrorResponse(request dap.Request, id int, summary string,
s.send(er)
}

// sendInternalErrorResponse sends an "internal error" response back to the client.
// We only take a seq here because we don't want to make assumptions about the
// kind of message received by the server that this error is a reply to.
func (s *Server) sendInternalErrorResponse(seq int, details string) {
er := &dap.ErrorResponse{}
er.Type = "response"
er.RequestSeq = seq
er.Success = false
er.Message = "Internal Error"
er.Body.Error.Id = InternalError
er.Body.Error.Format = fmt.Sprintf("%s: %s", er.Message, details)
s.log.Error(er.Body.Error.Format)
s.send(er)
}

func (s *Server) sendUnsupportedErrorResponse(request dap.Request) {
s.sendErrorResponse(request, UnsupportedCommand, "Unsupported command",
fmt.Sprintf("cannot process '%s' request", request.Command))
Expand Down
2 changes: 1 addition & 1 deletion vendor/github.com/google/go-dap/codec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/github.com/google/go-dap/io.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

201 changes: 100 additions & 101 deletions vendor/github.com/google/go-dap/schematypes.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.