1
0
mirror of https://github.com/golang/go synced 2024-11-13 18:50:24 -07:00

runtime: fix race that dropped GoSysExit events from trace

This makes TestTraceStressStartStop much less flaky.
Running under stress, it changes the failure rate from
above 1/100 to under 1/50000. That very unlikely
failure happens when an unexpected GoSysExit is
written. Not sure how that happens yet, but it is much
less important.

Fixes #11953.

Change-Id: I034671936334b4f3ab733614ef239aa121d20247
Reviewed-on: https://go-review.googlesource.com/13321
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
This commit is contained in:
Russ Cox 2015-08-06 13:44:37 -04:00
parent 5973558826
commit 26baed6af7

View File

@ -1348,7 +1348,23 @@ func execute(gp *g, inheritTime bool) {
// GoSysExit has to happen when we have a P, but before GoStart.
// So we emit it here.
if gp.syscallsp != 0 && gp.sysblocktraced {
traceGoSysExit(gp.sysexitseq, gp.sysexitticks)
// Since gp.sysblocktraced is true, we must emit an event.
// There is a race between the code that initializes sysexitseq
// and sysexitticks (in exitsyscall, which runs without a P,
// and therefore is not stopped with the rest of the world)
// and the code that initializes a new trace.
// The recorded sysexitseq and sysexitticks must therefore
// be treated as "best effort". If they are valid for this trace,
// then great, use them for greater accuracy.
// But if they're not valid for this trace, assume that the
// trace was started after the actual syscall exit (but before
// we actually managed to start the goroutine, aka right now),
// and assign a fresh time stamp to keep the log consistent.
seq, ts := gp.sysexitseq, gp.sysexitticks
if seq == 0 || int64(seq)-int64(trace.seqStart) < 0 {
seq, ts = tracestamp()
}
traceGoSysExit(seq, ts)
}
traceGoStart()
}