-
Notifications
You must be signed in to change notification settings - Fork 21.4k
Description
System information
Geth version: 1.9.10
OS & Version: Windows/Linux/OSX
Commit hash : 8045504
Expected behaviour
Possible goroutine leaks in test.
- p2p/server_test.go:
TestServerDial()
:accepted
go-ethereum/p2p/server_test.go
Lines 134 to 142 in 5f2002b
accepted := make(chan net.Conn) go func() { conn, err := listener.Accept() if err != nil { t.Error("accept error:", err) return } accepted <- conn }()
Goroutine may leak because sending toaccept
is blocked on L141 whenselect
on L154 selects timeout. Althought.Error()
is often called in these certain cases, it won't stop the leaking, because "Calling FailNow does not stop those other goroutines.". The fix is to replace the unbuffered channel with a buffered channel (buffer size 1). - p2p/server_test.go:
TestServerInboundThrottle
:connClosed
go-ethereum/p2p/server_test.go
Lines 673 to 685 in 5f2002b
connClosed := make(chan struct{}) conn, err = net.DialTimeout("tcp", srv.ListenAddr, timeout) if err != nil { t.Fatalf("could not dial: %v", err) } defer conn.Close() go func() { conn.SetDeadline(time.Now().Add(timeout)) buf := make([]byte, 10) if n, err := conn.Read(buf); err != io.EOF || n != 0 { t.Errorf("expected io.EOF and n == 0, got error %q and n == %d", err, n) } connClosed <- struct{}{}
Similar to 1. - rpc/client_test.go:
TestClientSubscribeClose
:errc
go-ethereum/rpc/client_test.go
Lines 300 to 306 in 5f2002b
errc = make(chan error) sub *ClientSubscription err error ) go func() { sub, err = client.Subscribe(context.Background(), "nftest2", nc, "hangSubscription", 999) errc <- err
Similar to 1. - rpc/subscription_test.go:
TestSubscriptions
:successes
andnotifications
go-ethereum/rpc/subscription_test.go
Lines 60 to 75 in 5f2002b
successes = make(chan subConfirmation) notifications = make(chan subscriptionResult) errors = make(chan error, subCount*notificationCount+1) ) // setup and start server for _, namespace := range namespaces { if err := server.RegisterName(namespace, service); err != nil { t.Fatalf("unable to register test service %v", err) } } go server.ServeCodec(NewCodec(serverConn), 0) defer server.Stop() // wait for message and write them to the given channels go waitForMessages(in, successes, notifications, errors) - rpc/client_test.go:
TestClientHTTP
:errc
go-ethereum/rpc/client_test.go
Lines 414 to 421 in 5f2002b
errc = make(chan error) wantResult = echoResult{"a", 1, new(echoArgs)} ) defer client.Close() for i := range results { i := i go func() { errc <- client.Call(&results[i], "test_echo", - event/event_test.go:
BenchmarkChanSend
:closed
go-ethereum/event/event_test.go
Lines 205 to 208 in 5f2002b
c := make(chan interface{}) closed := make(chan struct{}) go func() { for range c { - eth/handler_test.go:
TestBroadcastMalformedBlock
:notify
go-ethereum/eth/handler_test.go
Lines 680 to 693 in 5f2002b
notify := make(chan struct{}) go func() { if _, err := sink.app.ReadMsg(); err == nil { notify <- struct{}{} } }() // Try to broadcast all malformations and ensure they all get discarded for _, header := range []*types.Header{malformedUncles, malformedTransactions, malformedEverything} { block := types.NewBlockWithHeader(header).WithBody(chain[0].Transactions(), chain[0].Uncles()) if err := p2p.Send(source.app, NewBlockMsg, []interface{}{block, big.NewInt(131136)}); err != nil { t.Fatalf("failed to broadcast block: %v", err) } select { case <-notify: - miner/worker_test.go:
testGenerateBlockAndImport
:loopErr
go-ethereum/miner/worker_test.go
Lines 218 to 228 in 5f2002b
loopErr := make(chan error) newBlock := make(chan struct{}) listenNewBlock := func() { sub := w.mux.Subscribe(core.NewMinedBlockEvent{}) defer sub.Unsubscribe() for item := range sub.Chan() { block := item.Data.(core.NewMinedBlockEvent).Block _, err := chain.InsertChain([]*types.Block{block}) if err != nil { loopErr <- fmt.Errorf("failed to insert new mined block:%d, error:%v", block.NumberU64(), err) - console/console.go:
Interactive
:scheduler
go-ethereum/console/console.go
Lines 346 to 364 in 5f2002b
scheduler = make(chan string) // Channel to send the next prompt on and receive the input ) // Start a goroutine to listen for prompt requests and send back inputs go func() { for { // Read the next user input line, err := c.prompter.PromptInput(<-scheduler) if err != nil { // In case of an error, either clear the prompt or fail if err == liner.ErrPromptAborted { // ctrl-C prompt, indents, input = c.prompt, 0, "" scheduler <- "" continue } close(scheduler) return } // User input retrieved, send for interpretation and loop scheduler <- line - common/mclock/simclock_test.go:
TestSimulatedSleep
:done
go-ethereum/common/mclock/simclock_test.go
Lines 99 to 103 in 5f2002b
done = make(chan AbsTime) ) go func() { c.Sleep(timeout) done <- c.Now() - common/prque/lazyqueue_test.go:
TestLazyQueue
:stopCh
go-ethereum/common/prque/lazyqueue_test.go
Lines 78 to 86 in 5f2002b
stopCh := make(chan chan struct{}) go func() { for { select { case <-clock.After(testQueueRefresh): lock.Lock() q.Refresh() lock.Unlock() case stop := <-stopCh:
I have not verified all of them. I will try to fix similar bugs in one patch.
Actual behaviour
No, I found it through static analysis.
Steps to reproduce the behaviour
No.
Backtrace
No.