go runtime_error ai_generated true

fatal error: sync: unlock of unlocked mutex

ID: go/mutex-unlock-of-unlocked-mutex

Also available as: JSON · Markdown · 中文
80%Fix Rate
87%Confidence
0Evidence
2024-09-12First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.18 active — — —
1.20 active — — —
1.22 active — — —

Root Cause

Unlock() is called on a sync.Mutex that is not currently locked, usually from a deferred Unlock on an error path where Lock was never reached.

generic

中文

对一个当前未加锁的 sync.Mutex 调用 Unlock(),通常是在未执行 Lock 的错误路径上执行了 defer Unlock。

Workarounds

  1. 95% success
    mu.Lock()
    defer mu.Unlock()
    // critical section
  2. 88% success
    func lock(mu *sync.Mutex) func() {
        mu.Lock()
        return mu.Unlock
    }
    unlock := lock(&mu)
    defer unlock()

Dead Ends

Common approaches that don't work:

  1. 75% fail

    The mutex state is inconsistent; subsequent Lock calls may deadlock or panic unpredictably.

  2. 70% fail

    RWMutex has the same Unlock semantics, so the bug persists.