Skip to content

runtime: stack trace shows confusing call sequence during panic #13857

Closed
@rogpeppe

Description

@rogpeppe

I had a program that seemed to be deadlocking, and it showed the
following confusing stack trace:

goroutine 8 [semacquire]:
sync.runtime_Semacquire(0xc82019c91c)
    /home/rog/go/src/runtime/sema.go:47 +0x26
sync.(*WaitGroup).Wait(0xc82019c910)
    /home/rog/go/src/sync/waitgroup.go:127 +0xb4
gopkg.in/juju/charmstore.v5-unstable/internal/entitycache.(*Cache).Close(0xc82019c900)
    /home/rog/src/go/src/gopkg.in/juju/charmstore.v5-unstable/internal/entitycache/cache.go:90 +0x2d
sync.(*Mutex).Unlock(0xc82019c9a8)
    /home/rog/go/src/sync/mutex.go:109 +0x9f
gopkg.in/juju/charmstore.v5-unstable/internal/entitycache_test.newChanStore.func2(0xc8201de0c0, 0xc82016a600, 0x3, 0x0, 0x0)
    /home/rog/src/go/src/gopkg.in/juju/charmstore.v5-unstable/internal/entitycache/cache_test.go:253 +0xa0
gopkg.in/juju/charmstore.v5-unstable/internal/entitycache_test.(*callbackStore).FindBaseEntity(0xc820118860, 0xc8201de0c0, 0xc82016a600, 0x0, 0x0, 0x0)
    /home/rog/src/go/src/gopkg.in/juju/charmstore.v5-unstable/internal/entitycache/cache_test.go:275 +0x44
gopkg.in/juju/charmstore.v5-unstable/internal/entitycache.(*Cache).getBaseEntity(0xc82019c900, 0xc8201de0c0, 0xc82016a600, 0x0, 0x0, 0x0, 0x0)
    /home/rog/src/go/src/gopkg.in/juju/charmstore.v5-unstable/internal/entitycache/cache.go:187 +0x85
gopkg.in/juju/charmstore.v5-unstable/internal/entitycache.(*Cache).(gopkg.in/juju/charmstore.v5-unstable/internal/entitycache.getBaseEntity)-fm(0xc8201de0c0, 0xc82016a600, 0x0, 0x0, 0x0, 0x0)
    /home/rog/src/go/src/gopkg.in/juju/charmstore.v5-unstable/internal/entitycache/cache.go:82 +0x50
gopkg.in/juju/charmstore.v5-unstable/internal/entitycache.(*stash).fetch(0xc82019c998, 0xc8201de0c0, 0xc82016a600, 0x0, 0x0, 0x0)
    /home/rog/src/go/src/gopkg.in/juju/charmstore.v5-unstable/internal/entitycache/cache.go:364 +0x5b
gopkg.in/juju/charmstore.v5-unstable/internal/entitycache.(*stash).entity(0xc82019c998, 0xc8201de0c0, 0xc82016a7e0, 0x0, 0x0, 0x0, 0x0)
    /home/rog/src/go/src/gopkg.in/juju/charmstore.v5-unstable/internal/entitycache/cache.go:285 +0x49d
gopkg.in/juju/charmstore.v5-unstable/internal/entitycache.(*Cache).BaseEntity(0xc82019c900, 0xc8201de060, 0xc82016a7e0, 0xbc05f0, 0x0, 0x0)
    /home/rog/src/go/src/gopkg.in/juju/charmstore.v5-unstable/internal/entitycache/cache.go:158 +0xd8
gopkg.in/juju/charmstore.v5-unstable/internal/entitycache_test.(*suite).TestEntityIssuesBaseEntityQuerySequentiallyForPromulgatedURL(0xddd8e0, 0xc8200f60f0)
    /home/rog/src/go/src/gopkg.in/juju/charmstore.v5-unstable/internal/entitycache/cache_test.go:105 +0xf1e
reflect.Value.call(0x9bb6e0, 0xddd8e0, 0x213, 0xaa1a88, 0x4, 0xc8200d9f00, 0x1, 0x1, 0x0, 0x0, ...)
    /home/rog/go/src/reflect/value.go:435 +0x120d
reflect.Value.Call(0x9bb6e0, 0xddd8e0, 0x213, 0xc8200d9f00, 0x1, 0x1, 0x0, 0x0, 0x0)
    /home/rog/go/src/reflect/value.go:303 +0xb1
gopkg.in/check%2ev1.(*suiteRunner).forkTest.func1(0xc8200f60f0)
    /home/rog/src/go/src/gopkg.in/check.v1/check.go:757 +0x489
gopkg.in/check%2ev1.(*suiteRunner).forkCall.func1(0xc82007fc80, 0xc8200f60f0, 0xc820114680)
    /home/rog/src/go/src/gopkg.in/check.v1/check.go:651 +0x6f
created by gopkg.in/check%2ev1.(*suiteRunner).forkCall
    /home/rog/src/go/src/gopkg.in/check.v1/check.go:652 +0x299

It seems fairly clear that sync.Mutex.Unlock should not be calling entitycache.Cache.Close directly.

It seems we're unlocking an already-unlocked mutex (a bug in the code), so sync.Mutex is panicking, but shouldn't this fact be visible in the stack trace?

To reproduce, there's a branch in github.com/rogpeppe/charmstore called stacktrace-oddity; it should be checked out into gopkg.in/juju/charmstore.v5-unstable and its prereqs go-gotten. Running go test in internal/entitycache reproduces the issue reasonably often (reproduced under Go 1.4.1 and Go 1.6 beta). ^\ to see the stack trace when it's deadlocked (go 1.4 panics with a deadlock).

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions