ReleaseFunc from importClient.Send panics
lthibault opened this issue · comments
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x11dbfe6]
goroutine 368 [running]:
capnproto.org/go/capnp/v3/rpc.(*importClient).Send.func4()
capnproto.org/go/capnp/v3@v3.0.0-alpha.2/rpc/import.go:127 +0x46
github.com/wetware/ww/pkg/cap/pubsub.Topic.Publish({0xc13f5ac000?}, {0x225cbe0, 0xc006861dc0}, {0xc13f64e000, 0x707c1, 0xa12a8})
github.com/wetware/ww@v0.0.0-alpha.2/pkg/cap/pubsub/client.go:52 +0x11a
github.com/wetware/ww/pkg/client.(*futureTopic).Publish(0xc1233c9300?, {0x225cbe0, 0xc006861dc0}, {0xc13f64e000, 0x707c1, 0xa12a8})
github.com/wetware/ww@v0.0.0-alpha.2/pkg/client/pubsub.go:44 +0x54
github.com/ethereum/go-ethereum/eth.publisher.Publish({{0x2260480?, 0xc0138f60f0?}}, {0x225cbe0, 0xc006861dc0}, 0x339cf20?)
github.com/ethereum/go-ethereum/eth/wetware.go:224 +0x72
github.com/ethereum/go-ethereum/eth.(*wetware).publishPendingTx.func1()
github.com/ethereum/go-ethereum/eth/wetware.go:179 +0x652
golang.org/x/sync/errgroup.(*Group).Go.func1()
golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c/errgroup/errgroup.go:57 +0x67
created by golang.org/x/sync/errgroup.(*Group).Go
golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c/errgroup/errgroup.go:54 +0x8d
I encountered the above panic in a production environment that streams a moderately large volume of data (several hundred items per second, with each item averaging around 70kb).
The stack trace bottoms out in importClient.Send
, on line 127, which is the last line of the following release function:
return ans, func() {
<-ans.Done()
q.p.ReleaseClients()
q.release() // PANIC
}
@zenhack Is there something the client code could be doing incorrectly that would cause q.release
to be nil?
@zenhack I see the comment following comment in question.go
:
type question struct {
// ...
release capnp.ReleaseFunc // written before resolving p
// ...
}
This suggests to me that question
starts its lifecycle without a release function. Maybe we're forgetting to set it somewhere?
Maybe. I'd have to dig into the code to provide much extra insight, but I vaguely recall there were a bunch of places where we set:
q.release = func() { }
...so maybe we missed a spot?
Could this be happening in handleReturn
due to that new goroutine? Perhaps something is trying to call q.release()
before q.release = func() { }
executes?
That seems plausible.
I haven't seen this one in a while. Closing optimistically.