Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expvar: deadlock in Map.String #7575

Closed
dvyukov opened this issue Mar 18, 2014 · 5 comments
Closed

expvar: deadlock in Map.String #7575

dvyukov opened this issue Mar 18, 2014 · 5 comments
Milestone

Comments

@dvyukov
Copy link
Member

dvyukov commented Mar 18, 2014

Detected by experimental deadlock detector in cl/77450043.

==================
WARNING: DEADLOCK
Goroutine 999 lock mutex 11 while holding mutex 11:
  sync.(*RWMutex).RLock()
      src/pkg/sync/rwmutex.go:42 +0xa2
  expvar.(*Map).String()
      src/pkg/expvar/expvar.go:106 +0x77
  expvar.TestMapCounter()
      src/pkg/expvar/expvar_test.go:113 +0x53f
  testing.tRunner()
      src/pkg/testing/testing.go:422 +0x121

Mutex 11 was previously locked here:
  sync.(*RWMutex).RLock()
      src/pkg/sync/rwmutex.go:42 +0xa2
  expvar.(*Map).Do()
      src/pkg/expvar/expvar.go:203 +0x54
  expvar.(*Map).String()
      src/pkg/expvar/expvar.go:117 +0x1b4
  expvar.TestMapCounter()
      src/pkg/expvar/expvar_test.go:113 +0x53f
  testing.tRunner()
      src/pkg/testing/testing.go:422 +0x121
==================

In fact the following program crashes with "fatal error: all goroutines are asleep
- deadlock!":
http://play.golang.org/p/1uvDCFc0Vx

The problem is in the Map.String function that locks v.mu recursively (the second time
in v.Do):

func (v *Map) String() string {
    v.mu.RLock()
    defer v.mu.RUnlock()
    var b bytes.Buffer
    fmt.Fprintf(&b, "{")
    first := true
    v.Do(func(kv KeyValue) {
        if !first {
            fmt.Fprintf(&b, ", ")
        }
        fmt.Fprintf(&b, "\"%s\": %v", kv.Key, kv.Value)
        first = false
    })
    fmt.Fprintf(&b, "}")
    return b.String()
}

sync.RWMutex is not recursive for readers (and for writers)
.
@bradfitz
Copy link
Contributor

Comment 1:

Seems fine to me.

@dvyukov
Copy link
Member Author

dvyukov commented Mar 18, 2014

Comment 2:

RWmutex can't be acquire recursively.

@bradfitz
Copy link
Contributor

Comment 3:

Can we have this discussion in one place instead of arguing it in many separate bugs?

@dvyukov
Copy link
Member Author

dvyukov commented Mar 18, 2014

Comment 4:

sent email to golang-dev

@bradfitz
Copy link
Contributor

Comment 5:

This issue was closed by revision 666f5b4.

Status changed to Fixed.

@rsc rsc added this to the Go1.3 milestone Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 25, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants