mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime/cgo: fix deadlock involving signals on darwin
sigprocmask() is process-wide on darwin, so two concurrent libcgo_sys_thread_start() can result in all signals permanently blocked, which in particular blocks handling of nil derefs. Fixes #4833. R=golang-dev, dave, rsc CC=golang-dev https://golang.org/cl/7324058
This commit is contained in:
parent
052d845c5c
commit
4eb7ba743d
3 changed files with 77 additions and 4 deletions
|
|
@ -99,6 +99,14 @@ func TestLockedDeadlock2(t *testing.T) {
|
|||
testDeadlock(t, lockedDeadlockSource2)
|
||||
}
|
||||
|
||||
func TestCgoSignalDeadlock(t *testing.T) {
|
||||
got := executeTest(t, cgoSignalDeadlockSource, nil)
|
||||
want := "OK\n"
|
||||
if got != want {
|
||||
t.Fatalf("expected %q, but got %q", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
const crashSource = `
|
||||
package main
|
||||
|
||||
|
|
@ -183,3 +191,68 @@ func main() {
|
|||
select {}
|
||||
}
|
||||
`
|
||||
|
||||
const cgoSignalDeadlockSource = `
|
||||
package main
|
||||
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
runtime.GOMAXPROCS(100)
|
||||
ping := make(chan bool)
|
||||
go func() {
|
||||
for i := 0; ; i++ {
|
||||
runtime.Gosched()
|
||||
select {
|
||||
case done := <-ping:
|
||||
if done {
|
||||
ping <- true
|
||||
return
|
||||
}
|
||||
ping <- true
|
||||
default:
|
||||
}
|
||||
func() {
|
||||
defer func() {
|
||||
recover()
|
||||
}()
|
||||
var s *string
|
||||
*s = ""
|
||||
}()
|
||||
}
|
||||
}()
|
||||
time.Sleep(time.Millisecond)
|
||||
for i := 0; i < 64; i++ {
|
||||
go func() {
|
||||
runtime.LockOSThread()
|
||||
select {}
|
||||
}()
|
||||
go func() {
|
||||
runtime.LockOSThread()
|
||||
select {}
|
||||
}()
|
||||
time.Sleep(time.Millisecond)
|
||||
ping <- false
|
||||
select {
|
||||
case <-ping:
|
||||
case <-time.After(time.Second):
|
||||
fmt.Printf("HANG\n")
|
||||
return
|
||||
}
|
||||
}
|
||||
ping <- true
|
||||
select {
|
||||
case <-ping:
|
||||
case <-time.After(time.Second):
|
||||
fmt.Printf("HANG\n")
|
||||
return
|
||||
}
|
||||
fmt.Printf("OK\n")
|
||||
}
|
||||
`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue