mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: synchronize StartTrace and StopTrace with sysmon
Currently sysmon is not stopped when the world is stopped, which is in general a difficult thing to do. The result of this is that when tracing starts and the value of trace.enabled changes, it's possible for sysmon to fail to emit an event when it really should. This leads to traces which the execution trace parser deems inconsistent. Fix this by putting all of sysmon's work behind a new lock sysmonlock. StartTrace and StopTrace both acquire this lock after stopping the world but before performing any work in order to ensure sysmon sees the required state change in tracing. This change is expected to slow down StartTrace and StopTrace, but will help ensure consistent traces are generated. Updates #29707. Fixes #38794. Change-Id: I64c58e7c3fd173cd5281ffc208d6db24ff6c0284 Reviewed-on: https://go-review.googlesource.com/c/go/+/234617 Run-TryBot: Michael Knyszek <mknyszek@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com> Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
39ea0ea05d
commit
c847589ad0
4 changed files with 61 additions and 26 deletions
|
|
@ -533,6 +533,7 @@ func cpuinit() {
|
|||
// The new G calls runtime·main.
|
||||
func schedinit() {
|
||||
lockInit(&sched.lock, lockRankSched)
|
||||
lockInit(&sched.sysmonlock, lockRankSysmon)
|
||||
lockInit(&sched.deferlock, lockRankDefer)
|
||||
lockInit(&sched.sudoglock, lockRankSudog)
|
||||
lockInit(&deadlock, lockRankDeadlock)
|
||||
|
|
@ -4613,6 +4614,18 @@ func sysmon() {
|
|||
}
|
||||
unlock(&sched.lock)
|
||||
}
|
||||
lock(&sched.sysmonlock)
|
||||
{
|
||||
// If we spent a long time blocked on sysmonlock
|
||||
// then we want to update now and next since it's
|
||||
// likely stale.
|
||||
now1 := nanotime()
|
||||
if now1-now > 50*1000 /* 50µs */ {
|
||||
next, _ = timeSleepUntil()
|
||||
}
|
||||
now = now1
|
||||
}
|
||||
|
||||
// trigger libc interceptors if needed
|
||||
if *cgo_yield != nil {
|
||||
asmcgocall(*cgo_yield, nil)
|
||||
|
|
@ -4665,6 +4678,7 @@ func sysmon() {
|
|||
lasttrace = now
|
||||
schedtrace(debug.scheddetail > 0)
|
||||
}
|
||||
unlock(&sched.sysmonlock)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue