Skip to content

Commit da0785b

Browse files
mvanhornandrinoff
authored andcommitted
fix(daemon): recover acceptLoop panics (#1305)
## What? Adds a top-level `defer func() { recover(); log }()` to `(*Daemon).acceptLoop` so a panic in the accept goroutine logs with a stack trace instead of taking down the whole daemon. Closes #1119 ## Why? `daemon/daemon.go:120` launches `go d.acceptLoop()` with no panic recovery. A panic inside the loop (or in `addClient` / `daemonrpc.NewConn`) propagates up and the runtime aborts the process. The sync loop, IDLE watcher, and connected clients all die with it. The issue notes the same risk applies to the prior recovery fixes (#979 / #980 / #981). The recovery pattern matches the existing one at `main.go:4089`: log the panic with a `runtime/debug.Stack()` trace and let the goroutine exit. The daemon stops accepting new connections after a recovered panic, but already-connected clients and the background sync loop keep running, which is what the issue body asks for.
1 parent f9c8767 commit da0785b

1 file changed

Lines changed: 23 additions & 11 deletions

File tree

daemon/daemon.go

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"log"
77
"net"
88
"os"
9+
"runtime/debug"
910
"sort"
1011
"sync"
1112
"time"
@@ -185,19 +186,30 @@ func (d *Daemon) initProviders() {
185186

186187
func (d *Daemon) acceptLoop() {
187188
for {
188-
conn, err := d.listener.Accept()
189-
if err != nil {
190-
select {
191-
case <-d.shutdown:
192-
return
193-
default:
194-
log.Printf("daemon: accept error: %v", err)
195-
continue
189+
done := func() bool {
190+
defer func() {
191+
if r := recover(); r != nil {
192+
log.Printf("daemon: acceptLoop panic recovered: %v\n%s", r, debug.Stack())
193+
}
194+
}()
195+
conn, err := d.listener.Accept()
196+
if err != nil {
197+
select {
198+
case <-d.shutdown:
199+
return true
200+
default:
201+
log.Printf("daemon: accept error: %v", err)
202+
return false
203+
}
196204
}
205+
rpcConn := daemonrpc.NewConn(conn)
206+
d.addClient(rpcConn)
207+
go d.handleClient(rpcConn)
208+
return false
209+
}()
210+
if done {
211+
return
197212
}
198-
rpcConn := daemonrpc.NewConn(conn)
199-
d.addClient(rpcConn)
200-
go d.handleClient(rpcConn)
201213
}
202214
}
203215

0 commit comments

Comments
 (0)