diff options
Diffstat (limited to 'libgo/go/runtime/trace.go')
-rw-r--r-- | libgo/go/runtime/trace.go | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/libgo/go/runtime/trace.go b/libgo/go/runtime/trace.go index 358674b..ce185fc 100644 --- a/libgo/go/runtime/trace.go +++ b/libgo/go/runtime/trace.go @@ -181,9 +181,15 @@ func traceBufPtrOf(b *traceBuf) traceBufPtr { // Most clients should use the runtime/trace package or the testing package's // -test.trace flag instead of calling StartTrace directly. func StartTrace() error { - // Stop the world, so that we can take a consistent snapshot + // Stop the world so that we can take a consistent snapshot // of all goroutines at the beginning of the trace. - stopTheWorld("start tracing") + // Do not stop the world during GC so we ensure we always see + // a consistent view of GC-related events (e.g. a start is always + // paired with an end). + stopTheWorldGC("start tracing") + + // Prevent sysmon from running any code that could generate events. + lock(&sched.sysmonlock) // We are in stop-the-world, but syscalls can finish and write to trace concurrently. // Exitsyscall could check trace.enabled long before and then suddenly wake up @@ -194,7 +200,8 @@ func StartTrace() error { if trace.enabled || trace.shutdown { unlock(&trace.bufLock) - startTheWorld() + unlock(&sched.sysmonlock) + startTheWorldGC() return errorString("tracing is already enabled") } @@ -265,7 +272,9 @@ func StartTrace() error { unlock(&trace.bufLock) - startTheWorld() + unlock(&sched.sysmonlock) + + startTheWorldGC() return nil } @@ -274,14 +283,18 @@ func StartTrace() error { func StopTrace() { // Stop the world so that we can collect the trace buffers from all p's below, // and also to avoid races with traceEvent. - stopTheWorld("stop tracing") + stopTheWorldGC("stop tracing") + + // See the comment in StartTrace. + lock(&sched.sysmonlock) // See the comment in StartTrace. lock(&trace.bufLock) if !trace.enabled { unlock(&trace.bufLock) - startTheWorld() + unlock(&sched.sysmonlock) + startTheWorldGC() return } @@ -318,7 +331,9 @@ func StopTrace() { trace.shutdown = true unlock(&trace.bufLock) - startTheWorld() + unlock(&sched.sysmonlock) + + startTheWorldGC() // The world is started but we've set trace.shutdown, so new tracing can't start. // Wait for the trace reader to flush pending buffers and stop. @@ -859,6 +874,7 @@ func (tab *traceStackTable) dump() { tab.mem.drop() *tab = traceStackTable{} + lockInit(&((*tab).lock), lockRankTraceStackTab) } type traceFrame struct { |