Skip to content

A potential goleak in cluster.go #47859

@xuxiaofan1203

Description

@xuxiaofan1203

Description

Hello, I found in the function clusterLeave()

func (nDB *NetworkDB) clusterLeave() error {

func (nDB *NetworkDB) clusterLeave() error {
	mlist := nDB.memberlist


	if err := nDB.sendNodeEvent(NodeEventTypeLeave); err != nil {
		log.G(context.TODO()).Errorf("failed to send node leave: %v", err)
	}


	if err := mlist.Leave(time.Second); err != nil {
		return err
	}


	// cancel the context
	nDB.cancelCtx()


	for _, t := range nDB.tickers {
		t.Stop()
	}


	return mlist.Shutdown()
}

If the mlist.Leave() return err, the nDB.cancelCtx() below will not get executed.

if err := mlist.Leave(time.Second); err != nil {
return err
}
// cancel the context
nDB.cancelCtx()

And it will lead the <-nDB.ctx.Done in triggerFunc() blocked persistently, so the goroutine leak.

go nDB.triggerFunc(trigger.interval, t.C, trigger.fn)

blocking position:

for {
select {
case <-C:
f()
case <-nDB.ctx.Done():
return
}
}

Reproduce

I reproduce the bug by goleak.
Firstly, I modified the judge condition from err != nil to err == nil. Because I don't know how to let err != nil, the change only to make the return err can be executed easier. I'm not sure whether the change can lead other influences.
Normally:

	if err := mlist.Leave(time.Second); err != nil {
		return err
	}

After modified:

	if err := mlist.Leave(time.Second); err == nil {
		return err
	}

Then I used goleak to test in these test function related the funciton.

func TestNetworkDBSimple(t *testing.T) {

Like this:
O` O$Y@3FVFWM%V4H3AQ8EH
The result shows that there is a bug at the <-nDB.ctx.Done
DPNHW@V DSD))B4B5~TO5M

Expected behavior

No response

docker version

latest

docker info

latest

Additional Info

In short, I think the bug is caused by return but have not called the cancelFunc. I have tried to describe it in detail.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions