diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 47656715a..deeb1ec15 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -22,5 +22,6 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi ### IMPROVEMENTS: +- [abci/server] [\#4719](https://github.com/tendermint/tendermint/pull/4719) Print panic & stack trace to STDERR if logger is not set (@melekes) ### BUG FIXES: diff --git a/abci/server/grpc_server.go b/abci/server/grpc_server.go index b953c404d..0f74a34aa 100644 --- a/abci/server/grpc_server.go +++ b/abci/server/grpc_server.go @@ -34,25 +34,24 @@ func NewGRPCServer(protoAddr string, app types.ABCIApplicationServer) service.Se return s } -// OnStart starts the gRPC service +// OnStart starts the gRPC service. func (s *GRPCServer) OnStart() error { - if err := s.BaseService.OnStart(); err != nil { - return err - } ln, err := net.Listen(s.proto, s.addr) if err != nil { return err } - s.Logger.Info("Listening", "proto", s.proto, "addr", s.addr) + s.listener = ln s.server = grpc.NewServer() types.RegisterABCIApplicationServer(s.server, s.app) + + s.Logger.Info("Listening", "proto", s.proto, "addr", s.addr) go s.server.Serve(s.listener) + return nil } -// OnStop stops the gRPC server +// OnStop stops the gRPC server. func (s *GRPCServer) OnStop() { - s.BaseService.OnStop() s.server.Stop() } diff --git a/abci/server/socket_server.go b/abci/server/socket_server.go index efb4d94e0..e68d79599 100644 --- a/abci/server/socket_server.go +++ b/abci/server/socket_server.go @@ -5,9 +5,12 @@ import ( "fmt" "io" "net" + "os" + "runtime" "sync" "github.com/tendermint/tendermint/abci/types" + tmlog "github.com/tendermint/tendermint/libs/log" tmnet "github.com/tendermint/tendermint/libs/net" "github.com/tendermint/tendermint/libs/service" ) @@ -16,6 +19,7 @@ import ( type SocketServer struct { service.BaseService + isLoggerSet bool proto string addr string @@ -42,21 +46,24 @@ func NewSocketServer(protoAddr string, app types.Application) service.Service { return s } +func (s *SocketServer) SetLogger(l tmlog.Logger) { + s.BaseService.SetLogger(l) + s.isLoggerSet = true +} + func (s *SocketServer) OnStart() error { - if err := s.BaseService.OnStart(); err != nil { - return err - } ln, err := net.Listen(s.proto, s.addr) if err != nil { return err } + s.listener = ln go s.acceptConnectionsRoutine() + return nil } func (s *SocketServer) OnStop() { - s.BaseService.OnStop() if err := s.listener.Close(); err != nil { s.Logger.Error("Error closing listener", "err", err) } @@ -105,7 +112,7 @@ func (s *SocketServer) acceptConnectionsRoutine() { if !s.IsRunning() { return // Ignore error from listener closing. } - s.Logger.Error("Failed to accept connection: " + err.Error()) + s.Logger.Error("Failed to accept connection", "err", err) continue } @@ -132,15 +139,15 @@ func (s *SocketServer) waitForClose(closeConn chan error, connID int) { case err == io.EOF: s.Logger.Error("Connection was closed by client") case err != nil: - s.Logger.Error("Connection error", "error", err) + s.Logger.Error("Connection error", "err", err) default: // never happens - s.Logger.Error("Connection was closed.") + s.Logger.Error("Connection was closed") } // Close the connection if err := s.rmConn(connID); err != nil { - s.Logger.Error("Error in closing connection", "error", err) + s.Logger.Error("Error closing connection", "err", err) } } @@ -153,7 +160,14 @@ func (s *SocketServer) handleRequests(closeConn chan error, conn io.Reader, resp // make sure to recover from any app-related panics to allow proper socket cleanup r := recover() if r != nil { - closeConn <- fmt.Errorf("recovered from panic: %v", r) + const size = 64 << 10 + buf := make([]byte, size) + buf = buf[:runtime.Stack(buf, false)] + err := fmt.Errorf("recovered from panic: %v\n%s", r, buf) + if !s.isLoggerSet { + fmt.Fprintln(os.Stderr, err) + } + closeConn <- err s.appMtx.Unlock() } }() @@ -166,7 +180,7 @@ func (s *SocketServer) handleRequests(closeConn chan error, conn io.Reader, resp if err == io.EOF { closeConn <- err } else { - closeConn <- fmt.Errorf("error reading message: %v", err) + closeConn <- fmt.Errorf("error reading message: %w", err) } return } @@ -223,13 +237,13 @@ func (s *SocketServer) handleResponses(closeConn chan error, conn io.Writer, res var res = <-responses err := types.WriteMessage(res, bufWriter) if err != nil { - closeConn <- fmt.Errorf("error writing message: %v", err.Error()) + closeConn <- fmt.Errorf("error writing message: %w", err) return } if _, ok := res.Value.(*types.Response_Flush); ok { err = bufWriter.Flush() if err != nil { - closeConn <- fmt.Errorf("error flushing write buffer: %v", err.Error()) + closeConn <- fmt.Errorf("error flushing write buffer: %w", err) return } }