Defer Lock

ID

go.defer_lock

Severity

high

Remediation Complexity

trivial

Remediation Risk

medium

Remediation Effort

low

Resource

Reliability

Language

Go

Tags

reliability, suspicious

Description

Reports defer mu.Lock() (or defer mu.RLock()) — a defer whose call acquires a lock rather than releasing it.

Rationale

This is almost always a typo for defer mu.Unlock(). The deferred Lock does not run when the statement is reached: it is queued until the function returns. So the body executes without the intended lock, and on the way out the function acquires the lock and never releases it — frequently deadlocking the next caller.

defer mu.Lock()  // FLAW — almost certainly meant defer mu.Unlock()
defer mu.RLock() // FLAW — meant defer mu.RUnlock()

mu.Lock()
defer mu.Unlock() // OK

Remediation

Acquire the lock with a direct call and defer the matching release: mu.Lock(); defer mu.Unlock() (or mu.RLock(); defer mu.RUnlock()).