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

sync: detect recursive locks, somehow #33584

Closed
kevinburke1 opened this issue Aug 11, 2019 · 3 comments
Closed

sync: detect recursive locks, somehow #33584

kevinburke1 opened this issue Aug 11, 2019 · 3 comments

Comments

@kevinburke1
Copy link

kevinburke1 commented Aug 11, 2019

This (single threaded program) will never work:

func TestDoubleLock(t *testing.T) {
    var mu sync.Mutex
    mu.Lock()
    mu.Lock()
}

But instead of getting an error, panic, data race with the race detector, the program just hangs forever. It would be nice if there was some way to detect and warn about this obviously incorrect program, besides just hanging forever.

@robpike
Copy link
Contributor

robpike commented Aug 11, 2019

The short answer is that it's infeasible. It's also I think an error to try. Yes, adjacent calls like this are a bug but the point of locking is to keep someone out. It's not even necessarily an error for the same goroutine to call Lock twice: it could be the job of another one to unlock. This works:

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var mu sync.Mutex
	go func() { time.Sleep(time.Second); mu.Unlock() }()
	mu.Lock()
	mu.Lock()
	fmt.Println("hi")
}

https://play.golang.org/p/O3pOKFeCkRG

Now that's clearly a ridiculous example but the model of its computation is legitimate: I wait for you to release a resource. All I've done here is release the lock you think is erroneous, but perhaps it's another goroutine's job to do that, and from looking at your code it's really not possible to know that.

You'd need some magical whole-program analysis, possibly even the solution to the halting problem, to know statically when a lock call is erroneous. Even dynamically, I think it's almost impossible to get it right every time.

Unfortunate as deadlocks are, they're just bugs of a different flavor, and need to be debugged using any tool that works. In this case, I don't think vet is the right tool.

@kevinburke1
Copy link
Author

but the model of its computation is legitimate

Fair enough.

It's also I think an error to try.

I guess one of the nice things about Go is that it makes it easier to reason about concurrent programs. Being able to detect a case where a thread holds a lock, and is blocked on itself would be really helpful.

@andybons
Copy link
Member

Closing but reopen if there's something I'm missing.

@golang golang locked and limited conversation to collaborators Aug 11, 2020
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