mirror of
https://github.com/golang/go
synced 2024-11-25 01:57:56 -07:00
runtime: work around false negative in deadlock detection
Not a complete fix for issue 3342, but fixes the trivial case. There may still be a race in the instants before and after a scavenger-induced garbage collection. Intended to be "obviously safe": a call to runtime·gosched before main.main is no different than a call to runtime.Gosched at the beginning of main.main, and it is (or had better be) safe to call runtime.Gosched at any point during main. Update #3342. R=iant CC=golang-dev https://golang.org/cl/5919052
This commit is contained in:
parent
9d7076b178
commit
5eb007dede
@ -236,6 +236,11 @@ runtime·main(void)
|
|||||||
if(!runtime·sched.lockmain)
|
if(!runtime·sched.lockmain)
|
||||||
runtime·UnlockOSThread();
|
runtime·UnlockOSThread();
|
||||||
|
|
||||||
|
// The deadlock detection has false negatives.
|
||||||
|
// Let scvg start up, to eliminate the false negative
|
||||||
|
// for the trivial program func main() { select{} }.
|
||||||
|
runtime·gosched();
|
||||||
|
|
||||||
main·main();
|
main·main();
|
||||||
runtime·exit(0);
|
runtime·exit(0);
|
||||||
for(;;)
|
for(;;)
|
||||||
@ -591,6 +596,20 @@ top:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Look for deadlock situation.
|
// Look for deadlock situation.
|
||||||
|
// There is a race with the scavenger that causes false negatives:
|
||||||
|
// if the scavenger is just starting, then we have
|
||||||
|
// scvg != nil && grunning == 0 && gwait == 0
|
||||||
|
// and we do not detect a deadlock. It is possible that we should
|
||||||
|
// add that case to the if statement here, but it is too close to Go 1
|
||||||
|
// to make such a subtle change. Instead, we work around the
|
||||||
|
// false negative in trivial programs by calling runtime.gosched
|
||||||
|
// from the main goroutine just before main.main.
|
||||||
|
// See runtime·main above.
|
||||||
|
//
|
||||||
|
// On a related note, it is also possible that the scvg == nil case is
|
||||||
|
// wrong and should include gwait, but that does not happen in
|
||||||
|
// standard Go programs, which all start the scavenger.
|
||||||
|
//
|
||||||
if((scvg == nil && runtime·sched.grunning == 0) ||
|
if((scvg == nil && runtime·sched.grunning == 0) ||
|
||||||
(scvg != nil && runtime·sched.grunning == 1 && runtime·sched.gwait == 0 &&
|
(scvg != nil && runtime·sched.grunning == 1 && runtime·sched.gwait == 0 &&
|
||||||
(scvg->status == Grunning || scvg->status == Gsyscall))) {
|
(scvg->status == Grunning || scvg->status == Gsyscall))) {
|
||||||
|
13
test/fixedbugs/bug429.go
Normal file
13
test/fixedbugs/bug429.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// $G $D/$F.go && $L $F.$A && ! ./$A.out || echo BUG: bug429
|
||||||
|
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Should print deadlock message, not hang.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
select {}
|
||||||
|
}
|
@ -15,6 +15,9 @@
|
|||||||
|
|
||||||
== fixedbugs/
|
== fixedbugs/
|
||||||
|
|
||||||
|
=========== fixedbugs/bug429.go
|
||||||
|
throw: all goroutines are asleep - deadlock!
|
||||||
|
|
||||||
== bugs/
|
== bugs/
|
||||||
|
|
||||||
=========== bugs/bug395.go
|
=========== bugs/bug395.go
|
||||||
|
Loading…
Reference in New Issue
Block a user