Browse Source

abci/server: print panic & stack trace to STDERR if logger is not set

Closes #4382
pull/4726/head
Anton Kaliaev 5 years ago
committed by GitHub
parent
commit
33a19dabd7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 19 deletions
  1. +1
    -0
      CHANGELOG_PENDING.md
  2. +6
    -7
      abci/server/grpc_server.go
  3. +26
    -12
      abci/server/socket_server.go

+ 1
- 0
CHANGELOG_PENDING.md View File

@ -23,6 +23,7 @@ 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)
- [txindex] [\#4466](https://github.com/tendermint/tendermint/pull/4466) Allow to index an event at runtime (@favadi)


+ 6
- 7
abci/server/grpc_server.go View File

@ -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()
}

+ 26
- 12
abci/server/socket_server.go View File

@ -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
}
}


Loading…
Cancel
Save