Skip to content

Commit fad55dc

Browse files
authored
feat(log): log trace if panic (#405)
1 parent 68d550a commit fad55dc

9 files changed

+72
-4
lines changed

pkg/core/gvisortcphandler.go

+2
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@ func (h *gvisorTCPHandler) handle(ctx context.Context, tcpConn net.Conn) {
4040
endpoint := channel.New(tcp.DefaultReceiveBufferSize, uint32(config.DefaultMTU), tcpip.GetRandMacAddr())
4141
errChan := make(chan error, 2)
4242
go func() {
43+
defer util.HandleCrash()
4344
h.readFromTCPConnWriteToEndpoint(ctx, tcpConn, endpoint)
4445
util.SafeClose(errChan)
4546
}()
4647
go func() {
48+
defer util.HandleCrash()
4749
h.readFromEndpointWriteToTCPConn(ctx, tcpConn, endpoint)
4850
util.SafeClose(errChan)
4951
}()

pkg/core/gvisorudpforwarder.go

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"gvisor.dev/gvisor/pkg/waiter"
1515

1616
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
17+
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
1718
)
1819

1920
func UDPForwarder(s *stack.Stack, ctx context.Context) func(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
@@ -51,6 +52,7 @@ func UDPForwarder(s *stack.Stack, ctx context.Context) func(id stack.TransportEn
5152
defer remote.Close()
5253
errChan := make(chan error, 2)
5354
go func() {
55+
defer util.HandleCrash()
5456
buf := config.LPool.Get().([]byte)[:]
5557
defer config.LPool.Put(buf[:])
5658

@@ -80,6 +82,7 @@ func UDPForwarder(s *stack.Stack, ctx context.Context) func(id stack.TransportEn
8082
errChan <- err
8183
}()
8284
go func() {
85+
defer util.HandleCrash()
8386
buf := config.LPool.Get().([]byte)[:]
8487
defer config.LPool.Put(buf[:])
8588

pkg/core/gvisorudphandler.go

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
log "github.com/sirupsen/logrus"
1010
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
11+
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
1112
)
1213

1314
type gvisorUDPHandler struct{}
@@ -102,6 +103,7 @@ func handle(ctx context.Context, tcpConn net.Conn, udpConn *net.UDPConn) {
102103
log.Debugf("[TUN-UDP] %s <-> %s", tcpConn.RemoteAddr(), udpConn.LocalAddr())
103104
errChan := make(chan error, 2)
104105
go func() {
106+
defer util.HandleCrash()
105107
buf := config.LPool.Get().([]byte)[:]
106108
defer config.LPool.Put(buf[:])
107109

@@ -146,6 +148,7 @@ func handle(ctx context.Context, tcpConn net.Conn, udpConn *net.UDPConn) {
146148
}()
147149

148150
go func() {
151+
defer util.HandleCrash()
149152
buf := config.LPool.Get().([]byte)[:]
150153
defer config.LPool.Put(buf[:])
151154

pkg/core/tunhandler.go

+6
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ type Device struct {
9595
}
9696

9797
func (d *Device) readFromTun() {
98+
defer util.HandleCrash()
9899
for {
99100
buf := config.LPool.Get().([]byte)[:]
100101
n, err := d.tun.Read(buf[:])
@@ -128,6 +129,7 @@ func (d *Device) readFromTun() {
128129
}
129130

130131
func (d *Device) writeToTun() {
132+
defer util.HandleCrash()
131133
for e := range d.tunOutbound {
132134
_, err := d.tun.Write(e.data[:e.length])
133135
config.LPool.Put(e.data[:])
@@ -277,6 +279,7 @@ func (p *Peer) sendErr(err error) {
277279
}
278280

279281
func (p *Peer) readFromConn() {
282+
defer util.HandleCrash()
280283
for {
281284
buf := config.LPool.Get().([]byte)[:]
282285
n, from, err := p.conn.ReadFrom(buf[:])
@@ -312,6 +315,7 @@ func (p *Peer) readFromConn() {
312315
}
313316

314317
func (p *Peer) readFromTCPConn() {
318+
defer util.HandleCrash()
315319
for packet := range TCPPacketChan {
316320
src, dst, err := util.ParseIP(packet.Data)
317321
if err != nil {
@@ -331,6 +335,7 @@ func (p *Peer) readFromTCPConn() {
331335
}
332336

333337
func (p *Peer) routePeer() {
338+
defer util.HandleCrash()
334339
for e := range p.connInbound {
335340
if routeToAddr := p.routeMapUDP.RouteTo(e.dst); routeToAddr != nil {
336341
log.Debugf("[UDP] Find UDP route to dst: %s -> %s", e.dst, routeToAddr)
@@ -363,6 +368,7 @@ func (p *Peer) routePeer() {
363368
}
364369

365370
func (p *Peer) routeTUN() {
371+
defer util.HandleCrash()
366372
for e := range p.tunInbound {
367373
if addr := p.routeMapUDP.RouteTo(e.dst); addr != nil {
368374
log.Debugf("[TUN] Find UDP route to dst: %s -> %s", e.dst, addr)

pkg/core/tunhandlerclient.go

+4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ func transportTunClient(ctx context.Context, tunInbound <-chan *DataElem, tunOut
8181
defer packetConn.Close()
8282

8383
go func() {
84+
defer util.HandleCrash()
8485
for e := range tunInbound {
8586
if e.src.Equal(e.dst) {
8687
util.SafeWrite(tunOutbound, e)
@@ -96,6 +97,7 @@ func transportTunClient(ctx context.Context, tunInbound <-chan *DataElem, tunOut
9697
}()
9798

9899
go func() {
100+
defer util.HandleCrash()
99101
for {
100102
buf := config.LPool.Get().([]byte)[:]
101103
n, _, err := packetConn.ReadFrom(buf[:])
@@ -145,6 +147,7 @@ func (d *ClientDevice) SetTunInboundHandler(handler func(tunInbound <-chan *Data
145147
}
146148

147149
func (d *ClientDevice) readFromTun() {
150+
defer util.HandleCrash()
148151
for {
149152
buf := config.LPool.Get().([]byte)[:]
150153
n, err := d.tun.Read(buf[:])
@@ -172,6 +175,7 @@ func (d *ClientDevice) readFromTun() {
172175
}
173176

174177
func (d *ClientDevice) writeToTun() {
178+
defer util.HandleCrash()
175179
for e := range d.tunOutbound {
176180
_, err := d.tun.Write(e.data[:e.length])
177181
config.LPool.Put(e.data[:])

pkg/daemon/daemon.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ func (o *SvrOption) Start(ctx context.Context) error {
5050
LocalTime: true,
5151
Compress: false,
5252
}
53-
53+
5454
// for gssapi to lookup KDCs in DNS
5555
// c.LibDefaults.DNSLookupKDC = true
5656
// c.LibDefaults.DNSLookupRealm = true
5757
net.DefaultResolver.PreferGo = true
58-
58+
5959
util.InitLoggerForServer(true)
6060
log.SetOutput(l)
6161
klog.SetOutput(l)
@@ -89,7 +89,9 @@ func (o *SvrOption) Start(ctx context.Context) error {
8989
return err
9090
}
9191

92-
svr := grpc.NewServer()
92+
unaryPanicInterceptor := grpc.UnaryInterceptor(rpc.UnaryPanicHandler)
93+
streamPanicInterceptor := grpc.StreamInterceptor(rpc.StreamPanicHandler)
94+
svr := grpc.NewServer(unaryPanicInterceptor, streamPanicInterceptor)
9395
cleanup, err := admin.Register(svr)
9496
if err != nil {
9597
log.Errorf("Failed to register admin: %v", err)

pkg/daemon/rpc/panicinterceptor.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package rpc
2+
3+
import (
4+
"fmt"
5+
"runtime/debug"
6+
7+
"github.com/sirupsen/logrus"
8+
"golang.org/x/net/context"
9+
"google.golang.org/grpc"
10+
"google.golang.org/grpc/codes"
11+
"google.golang.org/grpc/status"
12+
)
13+
14+
var _ grpc.UnaryServerInterceptor = UnaryPanicHandler
15+
var _ grpc.StreamServerInterceptor = StreamPanicHandler
16+
17+
func UnaryPanicHandler(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
18+
defer func() {
19+
if r := recover(); r != nil {
20+
str := fmt.Sprintf("Panic: `%s` %s", info.FullMethod, string(debug.Stack()))
21+
err = status.Error(codes.Internal, str)
22+
logrus.Panic(str)
23+
}
24+
}()
25+
return handler(ctx, req)
26+
}
27+
28+
func StreamPanicHandler(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error) {
29+
defer func() {
30+
if r := recover(); r != nil {
31+
str := fmt.Sprintf("Panic: `%s` %s", info.FullMethod, string(debug.Stack()))
32+
err = status.Error(codes.Internal, str)
33+
logrus.Panic(str)
34+
}
35+
}()
36+
return handler(srv, ss)
37+
}

pkg/dns/dns.go

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"tailscale.com/net/dns"
2828

2929
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
30+
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
3031
)
3132

3233
type Config struct {
@@ -73,6 +74,7 @@ func (c *Config) AddServiceNameToHosts(ctx context.Context, serviceInterface v13
7374
}
7475

7576
func (c *Config) watchServiceToAddHosts(ctx context.Context, serviceInterface v13.ServiceInterface, hosts []Entry) {
77+
defer util.HandleCrash()
7678
ticker := time.NewTicker(time.Second * 15)
7779
defer ticker.Stop()
7880
immediate := make(chan struct{}, 1)

pkg/util/grpc.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import (
66
"fmt"
77
"io"
88
"os"
9-
9+
"runtime/debug"
10+
11+
"github.com/sirupsen/logrus"
1012
"google.golang.org/grpc"
1113
)
1214

@@ -76,3 +78,10 @@ func CopyAndConvertGRPCStream[I any, O any](r grpc.ClientStream, w grpc.ServerSt
7678
}
7779
}
7880
}
81+
82+
func HandleCrash() {
83+
if r := recover(); r != nil {
84+
logrus.Panic(fmt.Sprintf("Panic: %s", string(debug.Stack())))
85+
panic(r)
86+
}
87+
}

0 commit comments

Comments
 (0)