cmd/trace: init goroutine info entries with GoCreate event

golang.org/cl/81315 attempted to distinguish system goroutines
by examining the function name in the goroutine stack. It assumes that
the information would be available when GoSysBlock or GoInSyscall
events are processed, but it turned out the stack information is
set too late (when the goroutine gets a chance to run).

This change initializes the goroutine information entry when
processing GoCreate event which should be one of the very first
events for the every goroutine in trace.

Fixes #22574

Change-Id: I1ed37087ce2e78ed27c9b419b7d942eb4140cc69
Reviewed-on: https://go-review.googlesource.com/83595
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Hana Kim 2017-12-12 18:20:06 -05:00 committed by Hyang-Ah Hana Kim
parent 841d865a56
commit a58286c289
7 changed files with 221 additions and 72 deletions

View file

@ -106,19 +106,19 @@ func main() {
}
log.Print("Parsing trace...")
events, err := parseEvents()
res, err := parseTrace()
if err != nil {
dief("%v\n", err)
}
if *debugFlag {
trace.Print(events)
trace.Print(res.Events)
os.Exit(0)
}
log.Print("Serializing trace...")
params := &traceParams{
events: events,
parsed: res,
endTime: int64(1<<63 - 1),
}
data, err := generateTrace(params)
@ -142,12 +142,22 @@ func main() {
var ranges []Range
var loader struct {
once sync.Once
events []*trace.Event
err error
once sync.Once
res trace.ParseResult
err error
}
// parseEvents is a compatibility wrapper that returns only
// the Events part of trace.ParseResult returned by parseTrace.
func parseEvents() ([]*trace.Event, error) {
res, err := parseTrace()
if err != nil {
return nil, err
}
return res.Events, err
}
func parseTrace() (trace.ParseResult, error) {
loader.once.Do(func() {
tracef, err := os.Open(traceFile)
if err != nil {
@ -157,14 +167,14 @@ func parseEvents() ([]*trace.Event, error) {
defer tracef.Close()
// Parse and symbolize.
events, err := trace.Parse(bufio.NewReader(tracef), programBinary)
res, err := trace.Parse(bufio.NewReader(tracef), programBinary)
if err != nil {
loader.err = fmt.Errorf("failed to parse trace: %v", err)
return
}
loader.events = events
loader.res = res
})
return loader.events, loader.err
return loader.res, loader.err
}
// httpMain serves the starting page.