From 8515d9cf656dedce3dbcb09ac7dc00f036e454d3 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Mon, 1 Apr 2019 12:22:22 -0700 Subject: [PATCH] runtime: randomize package initialization order in race mode This is one small step to force people to not depend on the order of initialization of packages which are not explicitly ordered by import directives. Similar to randomizing map iteration order, this makes sure people aren't depending on the behavior of the current release, so that we can change the order in future releases without breaking everyone. Maybe one day we can randomize always, but for now we do it just in race mode. (We would need to measure the impact on startup time before we enabled it always.) RELNOTE=yes Change-Id: I99026394796125974c5f2c3660a88becb92c9df3 Reviewed-on: https://go-review.googlesource.com/c/go/+/170318 Run-TryBot: Keith Randall TryBot-Result: Gobot Gobot Reviewed-by: Josh Bleecher Snyder --- src/runtime/proc.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/runtime/proc.go b/src/runtime/proc.go index e94de3a43a..83f3d5226f 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -5209,6 +5209,15 @@ func doInit(t *initTask) { throw("recursive call during initialization - linker skew") default: // not initialized yet t.state = 1 // initialization in progress + if raceenabled { + // Randomize initialization order of packages t depends on. + // TODO: enable always instead of just for race? + s := *(*[]uintptr)(unsafe.Pointer(&slice{array: add(unsafe.Pointer(t), 3*sys.PtrSize), len: int(t.ndeps), cap: int(t.ndeps)})) + for i := len(s) - 1; i > 0; i-- { + j := int(fastrandn(uint32(i + 1))) + s[i], s[j] = s[j], s[i] + } + } for i := uintptr(0); i < t.ndeps; i++ { p := add(unsafe.Pointer(t), (3+i)*sys.PtrSize) t2 := *(**initTask)(p)