-
Notifications
You must be signed in to change notification settings - Fork 17.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[release-branch.go1.11] runtime: never call into race detector with r…
…etaken P cgocall could previously invoke the race detector on an M whose P had been retaken. The race detector would attempt to use the P-local state from this stale P, racing with the thread that was actually wired to that P. The result was memory corruption of ThreadSanitizer's internal data structures that presented as hard-to-understand assertion failures and segfaults. Reorder cgocall so that it always acquires a P before invoking the race detector, and add a test that stresses the interaction between cgo and the race detector to protect against future bugs of this kind. Fixes #28690. Change-Id: Ide93f96a23490314d6647547140e0a412a97f0d4 Reviewed-on: https://go-review.googlesource.com/c/148717 Run-TryBot: Dmitry Vyukov <[email protected]> Reviewed-by: Dmitry Vyukov <[email protected]> (cherry picked from commit e496e61) Reviewed-on: https://go-review.googlesource.com/c/148902 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
- Loading branch information
1 parent
e8a95ae
commit 402eb45
Showing
3 changed files
with
68 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Copyright 2018 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. | ||
|
||
// Stress the interaction between the race detector and cgo in an | ||
// attempt to reproduce the memory corruption described in #27660. | ||
// The bug was very timing sensitive; at the time of writing this | ||
// test would only trigger the bug about once out of every five runs. | ||
|
||
package cgotest | ||
|
||
// #include <unistd.h> | ||
import "C" | ||
|
||
import ( | ||
"context" | ||
"math/rand" | ||
"runtime" | ||
"sync" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func test27660(t *testing.T) { | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
defer cancel() | ||
ints := make([]int, 100) | ||
locks := make([]sync.Mutex, 100) | ||
// Slowly create threads so that ThreadSanitizer is forced to | ||
// frequently resize its SyncClocks. | ||
for i := 0; i < 100; i++ { | ||
go func() { | ||
for ctx.Err() == nil { | ||
// Sleep in C for long enough that it is likely that the runtime | ||
// will retake this goroutine's currently wired P. | ||
C.usleep(1000 /* 1ms */) | ||
runtime.Gosched() // avoid starvation (see #28701) | ||
} | ||
}() | ||
go func() { | ||
// Trigger lots of synchronization and memory reads/writes to | ||
// increase the likelihood that the race described in #27660 | ||
// results in corruption of ThreadSanitizer's internal state | ||
// and thus an assertion failure or segfault. | ||
for ctx.Err() == nil { | ||
j := rand.Intn(100) | ||
locks[j].Lock() | ||
ints[j]++ | ||
locks[j].Unlock() | ||
} | ||
}() | ||
time.Sleep(time.Millisecond) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters