From eed309f5fb223a879630e9dced8c44c2b049cf71 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Thu, 29 Sep 2016 11:53:42 -0400 Subject: [PATCH] cmd/trace: move process-wide GC events to their own row Currently, the process-wide GC state is attributed to the P that happened to perform the allocation that exceeded the GC trigger. This is pretty arbitrary and makes it hard to see when GC is running since the GC spans are intermingled with a lot of other trace noise. The current display is particularly confusing because it creates three sub-rows in the P row that can overlap each other. Usually a P has just two sub-rows: one showing the current G and another showing that G's activity. However, because GC is attributed to a proc, it winds up as a third row that neither subsumes nor is subsumed by any other row. This in turn screws up the trace's layout and results in overlapping events. Fix these problems by creating a new dedicated row like the existing "Network" and "Timer" rows and displaying process-wide GC events in this row. Mark termination and sweep events still appear in their respective P rows because these are meaningfully attributed. Change-Id: Ie1a1c6cf8c446e4b043f10f3968f91ff1b546d15 Reviewed-on: https://go-review.googlesource.com/30017 Reviewed-by: Dmitry Vyukov --- src/cmd/trace/trace.go | 3 +++ src/internal/trace/parser.go | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/cmd/trace/trace.go b/src/cmd/trace/trace.go index 2b6a37bfd8..7d38ab0799 100644 --- a/src/cmd/trace/trace.go +++ b/src/cmd/trace/trace.go @@ -429,6 +429,9 @@ func generateTrace(params *traceParams) ViewerData { ctx.emit(&ViewerEvent{Name: "process_name", Phase: "M", Pid: 1, Arg: &NameArg{"STATS"}}) ctx.emit(&ViewerEvent{Name: "process_sort_index", Phase: "M", Pid: 1, Arg: &SortIndexArg{0}}) + ctx.emit(&ViewerEvent{Name: "thread_name", Phase: "M", Pid: 0, Tid: trace.GCP, Arg: &NameArg{"GC"}}) + ctx.emit(&ViewerEvent{Name: "thread_sort_index", Phase: "M", Pid: 0, Tid: trace.GCP, Arg: &SortIndexArg{-6}}) + ctx.emit(&ViewerEvent{Name: "thread_name", Phase: "M", Pid: 0, Tid: trace.NetpollP, Arg: &NameArg{"Network"}}) ctx.emit(&ViewerEvent{Name: "thread_sort_index", Phase: "M", Pid: 0, Tid: trace.NetpollP, Arg: &SortIndexArg{-5}}) diff --git a/src/internal/trace/parser.go b/src/internal/trace/parser.go index b1fc17ac58..527aba7ab4 100644 --- a/src/internal/trace/parser.go +++ b/src/internal/trace/parser.go @@ -56,6 +56,7 @@ const ( TimerP // depicts timer unblocks NetpollP // depicts network unblocks SyscallP // depicts returns from syscalls + GCP // depicts GC state ) // Parse parses, post-processes and verifies the trace. @@ -548,6 +549,8 @@ func postProcessTrace(ver int, events []*Event) error { return fmt.Errorf("previous GC is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts) } evGC = ev + // Attribute this to the global GC state. + ev.P = GCP case EvGCDone: if evGC == nil { return fmt.Errorf("bogus GC end (offset %v, time %v)", ev.Off, ev.Ts) -- 2.48.1