From 01ad44bc08c7ea3b8a7d1d989051046c77b6a63d Mon Sep 17 00:00:00 2001 From: Carlos Amedee Date: Tue, 7 May 2024 10:37:48 -0400 Subject: cmd/trace: collapse v2 directory into trace This change removes the old trace code and replaces it with the new tracer. It does the following: - Moves the contents of the v2 directory into the parent trace directory. - Combines the old tracer main file with the new main file. - Replaces any existing files with the corresponding v2 files. - Removes any unused files. Updates #67367 Change-Id: I2237920e13588258a2442b639d562cf7f8a8e944 Reviewed-on: https://go-review.googlesource.com/c/go/+/584536 LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Knyszek --- src/cmd/trace/annotations.go | 1196 ------- src/cmd/trace/annotations_test.go | 39 - src/cmd/trace/gen.go | 394 +++ src/cmd/trace/goroutinegen.go | 167 + src/cmd/trace/goroutines.go | 504 +-- src/cmd/trace/gstate.go | 373 +++ src/cmd/trace/jsontrace.go | 229 ++ src/cmd/trace/jsontrace_test.go | 291 ++ src/cmd/trace/main.go | 375 ++- src/cmd/trace/pprof.go | 393 ++- src/cmd/trace/procgen.go | 212 ++ src/cmd/trace/regions.go | 529 ++++ src/cmd/trace/tasks.go | 477 +++ src/cmd/trace/testdata/generate.go | 6 + src/cmd/trace/testdata/go122.test | 4639 ++++++++++++++++++++++++++++ src/cmd/trace/testdata/mktests.go | 58 + src/cmd/trace/testdata/testprog/main.go | 129 + src/cmd/trace/threadgen.go | 204 ++ src/cmd/trace/trace.go | 810 ----- src/cmd/trace/trace_test.go | 178 -- src/cmd/trace/v2/gen.go | 394 --- src/cmd/trace/v2/goroutinegen.go | 167 - src/cmd/trace/v2/goroutines.go | 420 --- src/cmd/trace/v2/gstate.go | 373 --- src/cmd/trace/v2/jsontrace.go | 229 -- src/cmd/trace/v2/jsontrace_test.go | 291 -- src/cmd/trace/v2/main.go | 323 -- src/cmd/trace/v2/pprof.go | 336 -- src/cmd/trace/v2/procgen.go | 212 -- src/cmd/trace/v2/regions.go | 529 ---- src/cmd/trace/v2/tasks.go | 477 --- src/cmd/trace/v2/testdata/generate.go | 6 - src/cmd/trace/v2/testdata/go122.test | 4639 ---------------------------- src/cmd/trace/v2/testdata/mktests.go | 58 - src/cmd/trace/v2/testdata/testprog/main.go | 129 - src/cmd/trace/v2/threadgen.go | 204 -- src/cmd/trace/v2/viewer.go | 56 - src/cmd/trace/viewer.go | 56 + 38 files changed, 8566 insertions(+), 11536 deletions(-) delete mode 100644 src/cmd/trace/annotations.go delete mode 100644 src/cmd/trace/annotations_test.go create mode 100644 src/cmd/trace/gen.go create mode 100644 src/cmd/trace/goroutinegen.go create mode 100644 src/cmd/trace/gstate.go create mode 100644 src/cmd/trace/jsontrace.go create mode 100644 src/cmd/trace/jsontrace_test.go create mode 100644 src/cmd/trace/procgen.go create mode 100644 src/cmd/trace/regions.go create mode 100644 src/cmd/trace/tasks.go create mode 100644 src/cmd/trace/testdata/generate.go create mode 100644 src/cmd/trace/testdata/go122.test create mode 100644 src/cmd/trace/testdata/mktests.go create mode 100644 src/cmd/trace/testdata/testprog/main.go create mode 100644 src/cmd/trace/threadgen.go delete mode 100644 src/cmd/trace/trace.go delete mode 100644 src/cmd/trace/trace_test.go delete mode 100644 src/cmd/trace/v2/gen.go delete mode 100644 src/cmd/trace/v2/goroutinegen.go delete mode 100644 src/cmd/trace/v2/goroutines.go delete mode 100644 src/cmd/trace/v2/gstate.go delete mode 100644 src/cmd/trace/v2/jsontrace.go delete mode 100644 src/cmd/trace/v2/jsontrace_test.go delete mode 100644 src/cmd/trace/v2/main.go delete mode 100644 src/cmd/trace/v2/pprof.go delete mode 100644 src/cmd/trace/v2/procgen.go delete mode 100644 src/cmd/trace/v2/regions.go delete mode 100644 src/cmd/trace/v2/tasks.go delete mode 100644 src/cmd/trace/v2/testdata/generate.go delete mode 100644 src/cmd/trace/v2/testdata/go122.test delete mode 100644 src/cmd/trace/v2/testdata/mktests.go delete mode 100644 src/cmd/trace/v2/testdata/testprog/main.go delete mode 100644 src/cmd/trace/v2/threadgen.go delete mode 100644 src/cmd/trace/v2/viewer.go create mode 100644 src/cmd/trace/viewer.go (limited to 'src') diff --git a/src/cmd/trace/annotations.go b/src/cmd/trace/annotations.go deleted file mode 100644 index df194a7598..0000000000 --- a/src/cmd/trace/annotations.go +++ /dev/null @@ -1,1196 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "bytes" - "fmt" - "html/template" - "internal/trace" - "internal/trace/traceviewer" - "log" - "net/http" - "net/url" - "reflect" - "sort" - "strconv" - "strings" - "time" -) - -func init() { - http.HandleFunc("/usertasks", httpUserTasks) - http.HandleFunc("/usertask", httpUserTask) - http.HandleFunc("/userregions", httpUserRegions) - http.HandleFunc("/userregion", httpUserRegion) -} - -// httpUserTasks reports all tasks found in the trace. -func httpUserTasks(w http.ResponseWriter, r *http.Request) { - res, err := analyzeAnnotations() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - tasks := res.tasks - summary := make(map[string]taskStats) - for _, task := range tasks { - stats, ok := summary[task.name] - if !ok { - stats.Type = task.name - } - - stats.add(task) - summary[task.name] = stats - } - - // Sort tasks by type. - userTasks := make([]taskStats, 0, len(summary)) - for _, stats := range summary { - userTasks = append(userTasks, stats) - } - sort.Slice(userTasks, func(i, j int) bool { - return userTasks[i].Type < userTasks[j].Type - }) - - // Emit table. - err = templUserTaskTypes.Execute(w, userTasks) - if err != nil { - http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) - return - } -} - -func httpUserRegions(w http.ResponseWriter, r *http.Request) { - res, err := analyzeAnnotations() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - allRegions := res.regions - - summary := make(map[regionTypeID]regionStats) - for id, regions := range allRegions { - stats, ok := summary[id] - if !ok { - stats.regionTypeID = id - } - for _, s := range regions { - stats.add(s) - } - summary[id] = stats - } - // Sort regions by pc and name - userRegions := make([]regionStats, 0, len(summary)) - for _, stats := range summary { - userRegions = append(userRegions, stats) - } - sort.Slice(userRegions, func(i, j int) bool { - if userRegions[i].Type != userRegions[j].Type { - return userRegions[i].Type < userRegions[j].Type - } - return userRegions[i].Frame.PC < userRegions[j].Frame.PC - }) - // Emit table. - err = templUserRegionTypes.Execute(w, userRegions) - if err != nil { - http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) - return - } -} - -func httpUserRegion(w http.ResponseWriter, r *http.Request) { - filter, err := newRegionFilter(r) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - res, err := analyzeAnnotations() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - allRegions := res.regions - - var data []regionDesc - - var maxTotal int64 - for id, regions := range allRegions { - for _, s := range regions { - if !filter.match(id, s) { - continue - } - data = append(data, s) - if maxTotal < s.TotalTime { - maxTotal = s.TotalTime - } - } - } - - sortby := r.FormValue("sortby") - _, ok := reflect.TypeOf(regionDesc{}).FieldByNameFunc(func(s string) bool { - return s == sortby - }) - if !ok { - sortby = "TotalTime" - } - sort.Slice(data, func(i, j int) bool { - ival := reflect.ValueOf(data[i]).FieldByName(sortby).Int() - jval := reflect.ValueOf(data[j]).FieldByName(sortby).Int() - return ival > jval - }) - - err = templUserRegionType.Execute(w, struct { - MaxTotal int64 - Data []regionDesc - Name string - Filter *regionFilter - }{ - MaxTotal: maxTotal, - Data: data, - Name: filter.name, - Filter: filter, - }) - if err != nil { - http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) - return - } -} - -// httpUserTask presents the details of the selected tasks. -func httpUserTask(w http.ResponseWriter, r *http.Request) { - filter, err := newTaskFilter(r) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - res, err := analyzeAnnotations() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - tasks := res.tasks - - type event struct { - WhenString string - Elapsed time.Duration - Go uint64 - What string - // TODO: include stack trace of creation time - } - type entry struct { - WhenString string - ID uint64 - Duration time.Duration - Complete bool - Events []event - Start, End time.Duration // Time since the beginning of the trace - GCTime time.Duration - } - - base := time.Duration(firstTimestamp()) * time.Nanosecond // trace start - - var data []entry - - for _, task := range tasks { - if !filter.match(task) { - continue - } - // merge events in the task.events and task.regions.Start - rawEvents := append([]*trace.Event{}, task.events...) - for _, s := range task.regions { - if s.Start != nil { - rawEvents = append(rawEvents, s.Start) - } - } - sort.SliceStable(rawEvents, func(i, j int) bool { return rawEvents[i].Ts < rawEvents[j].Ts }) - - var events []event - var last time.Duration - for i, ev := range rawEvents { - when := time.Duration(ev.Ts)*time.Nanosecond - base - elapsed := time.Duration(ev.Ts)*time.Nanosecond - last - if i == 0 { - elapsed = 0 - } - - what := describeEvent(ev) - if what != "" { - events = append(events, event{ - WhenString: fmt.Sprintf("%2.9f", when.Seconds()), - Elapsed: elapsed, - What: what, - Go: ev.G, - }) - last = time.Duration(ev.Ts) * time.Nanosecond - } - } - - data = append(data, entry{ - WhenString: fmt.Sprintf("%2.9fs", (time.Duration(task.firstTimestamp())*time.Nanosecond - base).Seconds()), - Duration: task.duration(), - ID: task.id, - Complete: task.complete(), - Events: events, - Start: time.Duration(task.firstTimestamp()) * time.Nanosecond, - End: time.Duration(task.endTimestamp()) * time.Nanosecond, - GCTime: task.overlappingGCDuration(res.gcEvents), - }) - } - sort.Slice(data, func(i, j int) bool { - return data[i].Duration < data[j].Duration - }) - - // Emit table. - err = templUserTaskType.Execute(w, struct { - Name string - Entry []entry - }{ - Name: filter.name, - Entry: data, - }) - if err != nil { - log.Printf("failed to execute template: %v", err) - http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) - return - } -} - -type annotationAnalysisResult struct { - tasks map[uint64]*taskDesc // tasks - regions map[regionTypeID][]regionDesc // regions - gcEvents []*trace.Event // GCStartevents, sorted -} - -type regionTypeID struct { - Frame trace.Frame // top frame - Type string -} - -// analyzeAnnotations analyzes user annotation events and -// returns the task descriptors keyed by internal task id. -func analyzeAnnotations() (annotationAnalysisResult, error) { - res, err := parseTrace() - if err != nil { - return annotationAnalysisResult{}, fmt.Errorf("failed to parse trace: %v", err) - } - - events := res.Events - if len(events) == 0 { - return annotationAnalysisResult{}, fmt.Errorf("empty trace") - } - - tasks := allTasks{} - regions := map[regionTypeID][]regionDesc{} - var gcEvents []*trace.Event - - for _, ev := range events { - switch typ := ev.Type; typ { - case trace.EvUserTaskCreate, trace.EvUserTaskEnd, trace.EvUserLog: - taskid := ev.Args[0] - task := tasks.task(taskid) - task.addEvent(ev) - - // retrieve parent task information - if typ == trace.EvUserTaskCreate { - if parentID := ev.Args[1]; parentID != 0 { - parentTask := tasks.task(parentID) - task.parent = parentTask - if parentTask != nil { - parentTask.children = append(parentTask.children, task) - } - } - } - - case trace.EvGCStart: - gcEvents = append(gcEvents, ev) - } - } - // combine region info. - analyzeGoroutines(events) - for goid, stats := range gs { - // gs is a global var defined in goroutines.go as a result - // of analyzeGoroutines. TODO(hyangah): fix this not to depend - // on a 'global' var. - for _, s := range stats.Regions { - if s.TaskID != 0 { - task := tasks.task(s.TaskID) - task.goroutines[goid] = struct{}{} - task.regions = append(task.regions, regionDesc{UserRegionDesc: s, G: goid}) - } - var frame trace.Frame - if s.Start != nil { - frame = *s.Start.Stk[0] - } - id := regionTypeID{Frame: frame, Type: s.Name} - regions[id] = append(regions[id], regionDesc{UserRegionDesc: s, G: goid}) - } - } - - // sort regions in tasks based on the timestamps. - for _, task := range tasks { - sort.SliceStable(task.regions, func(i, j int) bool { - si, sj := task.regions[i].firstTimestamp(), task.regions[j].firstTimestamp() - if si != sj { - return si < sj - } - return task.regions[i].lastTimestamp() < task.regions[j].lastTimestamp() - }) - } - return annotationAnalysisResult{tasks: tasks, regions: regions, gcEvents: gcEvents}, nil -} - -// taskDesc represents a task. -type taskDesc struct { - name string // user-provided task name - id uint64 // internal task id - events []*trace.Event // sorted based on timestamp. - regions []regionDesc // associated regions, sorted based on the start timestamp and then the last timestamp. - goroutines map[uint64]struct{} // involved goroutines - - create *trace.Event // Task create event - end *trace.Event // Task end event - - parent *taskDesc - children []*taskDesc -} - -func newTaskDesc(id uint64) *taskDesc { - return &taskDesc{ - id: id, - goroutines: make(map[uint64]struct{}), - } -} - -func (task *taskDesc) String() string { - if task == nil { - return "task " - } - wb := new(strings.Builder) - fmt.Fprintf(wb, "task %d:\t%s\n", task.id, task.name) - fmt.Fprintf(wb, "\tstart: %v end: %v complete: %t\n", task.firstTimestamp(), task.endTimestamp(), task.complete()) - fmt.Fprintf(wb, "\t%d goroutines\n", len(task.goroutines)) - fmt.Fprintf(wb, "\t%d regions:\n", len(task.regions)) - for _, s := range task.regions { - fmt.Fprintf(wb, "\t\t%s(goid=%d)\n", s.Name, s.G) - } - if task.parent != nil { - fmt.Fprintf(wb, "\tparent: %s\n", task.parent.name) - } - fmt.Fprintf(wb, "\t%d children:\n", len(task.children)) - for _, c := range task.children { - fmt.Fprintf(wb, "\t\t%s\n", c.name) - } - - return wb.String() -} - -// regionDesc represents a region. -type regionDesc struct { - *trace.UserRegionDesc - G uint64 // id of goroutine where the region was defined -} - -type allTasks map[uint64]*taskDesc - -func (tasks allTasks) task(taskID uint64) *taskDesc { - if taskID == 0 { - return nil // notask - } - - t, ok := tasks[taskID] - if ok { - return t - } - - t = newTaskDesc(taskID) - tasks[taskID] = t - return t -} - -func (task *taskDesc) addEvent(ev *trace.Event) { - if task == nil { - return - } - - task.events = append(task.events, ev) - task.goroutines[ev.G] = struct{}{} - - switch typ := ev.Type; typ { - case trace.EvUserTaskCreate: - task.name = ev.SArgs[0] - task.create = ev - case trace.EvUserTaskEnd: - task.end = ev - } -} - -// complete is true only if both start and end events of this task -// are present in the trace. -func (task *taskDesc) complete() bool { - if task == nil { - return false - } - return task.create != nil && task.end != nil -} - -// descendants returns all the task nodes in the subtree rooted from this task. -func (task *taskDesc) descendants() []*taskDesc { - if task == nil { - return nil - } - res := []*taskDesc{task} - for i := 0; len(res[i:]) > 0; i++ { - t := res[i] - res = append(res, t.children...) - } - return res -} - -// firstTimestamp returns the first timestamp of this task found in -// this trace. If the trace does not contain the task creation event, -// the first timestamp of the trace will be returned. -func (task *taskDesc) firstTimestamp() int64 { - if task != nil && task.create != nil { - return task.create.Ts - } - return firstTimestamp() -} - -// lastTimestamp returns the last timestamp of this task in this -// trace. If the trace does not contain the task end event, the last -// timestamp of the trace will be returned. -func (task *taskDesc) lastTimestamp() int64 { - endTs := task.endTimestamp() - if last := task.lastEvent(); last != nil && last.Ts > endTs { - return last.Ts - } - return endTs -} - -// endTimestamp returns the timestamp of this task's end event. -// If the trace does not contain the task end event, the last -// timestamp of the trace will be returned. -func (task *taskDesc) endTimestamp() int64 { - if task != nil && task.end != nil { - return task.end.Ts - } - return lastTimestamp() -} - -func (task *taskDesc) duration() time.Duration { - return time.Duration(task.endTimestamp()-task.firstTimestamp()) * time.Nanosecond -} - -func (region *regionDesc) duration() time.Duration { - return time.Duration(region.lastTimestamp()-region.firstTimestamp()) * time.Nanosecond -} - -// overlappingGCDuration returns the sum of GC period overlapping with the task's lifetime. -func (task *taskDesc) overlappingGCDuration(evs []*trace.Event) (overlapping time.Duration) { - for _, ev := range evs { - // make sure we only consider the global GC events. - if typ := ev.Type; typ != trace.EvGCStart { - continue - } - - if o, overlapped := task.overlappingDuration(ev); overlapped { - overlapping += o - } - } - return overlapping -} - -// overlappingInstant reports whether the instantaneous event, ev, occurred during -// any of the task's region if ev is a goroutine-local event, or overlaps with the -// task's lifetime if ev is a global event. -func (task *taskDesc) overlappingInstant(ev *trace.Event) bool { - if _, ok := isUserAnnotationEvent(ev); ok && task.id != ev.Args[0] { - return false // not this task's user event. - } - - ts := ev.Ts - taskStart := task.firstTimestamp() - taskEnd := task.endTimestamp() - if ts < taskStart || taskEnd < ts { - return false - } - if ev.P == trace.GCP { - return true - } - - // Goroutine local event. Check whether there are regions overlapping with the event. - goid := ev.G - for _, region := range task.regions { - if region.G != goid { - continue - } - if region.firstTimestamp() <= ts && ts <= region.lastTimestamp() { - return true - } - } - return false -} - -// overlappingDuration reports whether the durational event, ev, overlaps with -// any of the task's region if ev is a goroutine-local event, or overlaps with -// the task's lifetime if ev is a global event. It returns the overlapping time -// as well. -func (task *taskDesc) overlappingDuration(ev *trace.Event) (time.Duration, bool) { - start := ev.Ts - end := lastTimestamp() - if ev.Link != nil { - end = ev.Link.Ts - } - - if start > end { - return 0, false - } - - goid := ev.G - goid2 := ev.G - if ev.Link != nil { - goid2 = ev.Link.G - } - - // This event is a global GC event - if ev.P == trace.GCP { - taskStart := task.firstTimestamp() - taskEnd := task.endTimestamp() - o := overlappingDuration(taskStart, taskEnd, start, end) - return o, o > 0 - } - - // Goroutine local event. Check whether there are regions overlapping with the event. - var overlapping time.Duration - var lastRegionEnd int64 // the end of previous overlapping region - for _, region := range task.regions { - if region.G != goid && region.G != goid2 { - continue - } - regionStart, regionEnd := region.firstTimestamp(), region.lastTimestamp() - if regionStart < lastRegionEnd { // skip nested regions - continue - } - - if o := overlappingDuration(regionStart, regionEnd, start, end); o > 0 { - // overlapping. - lastRegionEnd = regionEnd - overlapping += o - } - } - return overlapping, overlapping > 0 -} - -// overlappingDuration returns the overlapping time duration between -// two time intervals [start1, end1] and [start2, end2] where -// start, end parameters are all int64 representing nanoseconds. -func overlappingDuration(start1, end1, start2, end2 int64) time.Duration { - // assume start1 <= end1 and start2 <= end2 - if end1 < start2 || end2 < start1 { - return 0 - } - - if start1 < start2 { // choose the later one - start1 = start2 - } - if end1 > end2 { // choose the earlier one - end1 = end2 - } - return time.Duration(end1 - start1) -} - -func (task *taskDesc) lastEvent() *trace.Event { - if task == nil { - return nil - } - - if n := len(task.events); n > 0 { - return task.events[n-1] - } - return nil -} - -// firstTimestamp returns the timestamp of region start event. -// If the region's start event is not present in the trace, -// the first timestamp of the trace will be returned. -func (region *regionDesc) firstTimestamp() int64 { - if region.Start != nil { - return region.Start.Ts - } - return firstTimestamp() -} - -// lastTimestamp returns the timestamp of region end event. -// If the region's end event is not present in the trace, -// the last timestamp of the trace will be returned. -func (region *regionDesc) lastTimestamp() int64 { - if region.End != nil { - return region.End.Ts - } - return lastTimestamp() -} - -// RelatedGoroutines returns IDs of goroutines related to the task. A goroutine -// is related to the task if user annotation activities for the task occurred. -// If non-zero depth is provided, this searches all events with BFS and includes -// goroutines unblocked any of related goroutines to the result. -func (task *taskDesc) RelatedGoroutines(events []*trace.Event, depth int) map[uint64]bool { - start, end := task.firstTimestamp(), task.endTimestamp() - - gmap := map[uint64]bool{} - for k := range task.goroutines { - gmap[k] = true - } - - for i := 0; i < depth; i++ { - gmap1 := make(map[uint64]bool) - for g := range gmap { - gmap1[g] = true - } - for _, ev := range events { - if ev.Ts < start || ev.Ts > end { - continue - } - if ev.Type == trace.EvGoUnblock && gmap[ev.Args[0]] { - gmap1[ev.G] = true - } - gmap = gmap1 - } - } - gmap[0] = true // for GC events (goroutine id = 0) - return gmap -} - -type taskFilter struct { - name string - cond []func(*taskDesc) bool -} - -func (f *taskFilter) match(t *taskDesc) bool { - if t == nil { - return false - } - for _, c := range f.cond { - if !c(t) { - return false - } - } - return true -} - -func newTaskFilter(r *http.Request) (*taskFilter, error) { - if err := r.ParseForm(); err != nil { - return nil, err - } - - var name []string - var conditions []func(*taskDesc) bool - - param := r.Form - if typ, ok := param["type"]; ok && len(typ) > 0 { - name = append(name, "type="+typ[0]) - conditions = append(conditions, func(t *taskDesc) bool { - return t.name == typ[0] - }) - } - if complete := r.FormValue("complete"); complete == "1" { - name = append(name, "complete") - conditions = append(conditions, func(t *taskDesc) bool { - return t.complete() - }) - } else if complete == "0" { - name = append(name, "incomplete") - conditions = append(conditions, func(t *taskDesc) bool { - return !t.complete() - }) - } - if lat, err := time.ParseDuration(r.FormValue("latmin")); err == nil { - name = append(name, fmt.Sprintf("latency >= %s", lat)) - conditions = append(conditions, func(t *taskDesc) bool { - return t.complete() && t.duration() >= lat - }) - } - if lat, err := time.ParseDuration(r.FormValue("latmax")); err == nil { - name = append(name, fmt.Sprintf("latency <= %s", lat)) - conditions = append(conditions, func(t *taskDesc) bool { - return t.complete() && t.duration() <= lat - }) - } - if text := r.FormValue("logtext"); text != "" { - name = append(name, fmt.Sprintf("log contains %q", text)) - conditions = append(conditions, func(t *taskDesc) bool { - return taskMatches(t, text) - }) - } - - return &taskFilter{name: strings.Join(name, ","), cond: conditions}, nil -} - -func taskMatches(t *taskDesc, text string) bool { - for _, ev := range t.events { - switch ev.Type { - case trace.EvUserTaskCreate, trace.EvUserRegion, trace.EvUserLog: - for _, s := range ev.SArgs { - if strings.Contains(s, text) { - return true - } - } - } - } - return false -} - -type regionFilter struct { - name string - params url.Values - cond []func(regionTypeID, regionDesc) bool -} - -func (f *regionFilter) match(id regionTypeID, s regionDesc) bool { - for _, c := range f.cond { - if !c(id, s) { - return false - } - } - return true -} - -func newRegionFilter(r *http.Request) (*regionFilter, error) { - if err := r.ParseForm(); err != nil { - return nil, err - } - - var name []string - var conditions []func(regionTypeID, regionDesc) bool - filterParams := make(url.Values) - - param := r.Form - if typ, ok := param["type"]; ok && len(typ) > 0 { - name = append(name, "type="+typ[0]) - conditions = append(conditions, func(id regionTypeID, s regionDesc) bool { - return id.Type == typ[0] - }) - filterParams.Add("type", typ[0]) - } - if pc, err := strconv.ParseUint(r.FormValue("pc"), 16, 64); err == nil { - encPC := fmt.Sprintf("%x", pc) - name = append(name, "pc="+encPC) - conditions = append(conditions, func(id regionTypeID, s regionDesc) bool { - return id.Frame.PC == pc - }) - filterParams.Add("pc", encPC) - } - - if lat, err := time.ParseDuration(r.FormValue("latmin")); err == nil { - name = append(name, fmt.Sprintf("latency >= %s", lat)) - conditions = append(conditions, func(_ regionTypeID, s regionDesc) bool { - return s.duration() >= lat - }) - filterParams.Add("latmin", lat.String()) - } - if lat, err := time.ParseDuration(r.FormValue("latmax")); err == nil { - name = append(name, fmt.Sprintf("latency <= %s", lat)) - conditions = append(conditions, func(_ regionTypeID, s regionDesc) bool { - return s.duration() <= lat - }) - filterParams.Add("latmax", lat.String()) - } - - return ®ionFilter{ - name: strings.Join(name, ","), - cond: conditions, - params: filterParams, - }, nil -} - -type regionStats struct { - regionTypeID - Histogram traceviewer.TimeHistogram -} - -func (s *regionStats) UserRegionURL() func(min, max time.Duration) string { - return func(min, max time.Duration) string { - return fmt.Sprintf("/userregion?type=%s&pc=%x&latmin=%v&latmax=%v", template.URLQueryEscaper(s.Type), s.Frame.PC, template.URLQueryEscaper(min), template.URLQueryEscaper(max)) - } -} - -func (s *regionStats) add(region regionDesc) { - s.Histogram.Add(region.duration()) -} - -var templUserRegionTypes = template.Must(template.New("").Parse(` - - - - - - - - - -{{range $}} - - - - - -{{end}} -
Region typeCountDuration distribution (complete tasks)
{{.Type}}
{{.Frame.Fn}}
{{.Frame.File}}:{{.Frame.Line}}
{{.Histogram.Count}}{{.Histogram.ToHTML (.UserRegionURL)}}
- - -`)) - -type taskStats struct { - Type string - Count int // Complete + incomplete tasks - Histogram traceviewer.TimeHistogram // Complete tasks only -} - -func (s *taskStats) UserTaskURL(complete bool) func(min, max time.Duration) string { - return func(min, max time.Duration) string { - return fmt.Sprintf("/usertask?type=%s&complete=%v&latmin=%v&latmax=%v", template.URLQueryEscaper(s.Type), template.URLQueryEscaper(complete), template.URLQueryEscaper(min), template.URLQueryEscaper(max)) - } -} - -func (s *taskStats) add(task *taskDesc) { - s.Count++ - if task.complete() { - s.Histogram.Add(task.duration()) - } -} - -var templUserTaskTypes = template.Must(template.New("").Parse(` - - - -Search log text:

- - - - - - -{{range $}} - - - - - -{{end}} -
Task typeCountDuration distribution (complete tasks)
{{.Type}}{{.Count}}{{.Histogram.ToHTML (.UserTaskURL true)}}
- - -`)) - -var templUserTaskType = template.Must(template.New("userTask").Funcs(template.FuncMap{ - "elapsed": elapsed, - "asMillisecond": asMillisecond, - "trimSpace": strings.TrimSpace, -}).Parse(` - - User Task: {{.Name}} - - - -

User Task: {{.Name}}

- -Search log text:
- -

- - - - {{range $el := $.Entry}} - - - - - - - {{range $el.Events}} - - - - - - - {{end}} - - - - - - {{end}} - - -`)) - -func elapsed(d time.Duration) string { - b := fmt.Appendf(nil, "%.9f", d.Seconds()) - - // For subsecond durations, blank all zeros before decimal point, - // and all zeros between the decimal point and the first non-zero digit. - if d < time.Second { - dot := bytes.IndexByte(b, '.') - for i := 0; i < dot; i++ { - b[i] = ' ' - } - for i := dot + 1; i < len(b); i++ { - if b[i] == '0' { - b[i] = ' ' - } else { - break - } - } - } - - return string(b) -} - -func asMillisecond(d time.Duration) float64 { - return float64(d.Nanoseconds()) / 1e6 -} - -func formatUserLog(ev *trace.Event) string { - k, v := ev.SArgs[0], ev.SArgs[1] - if k == "" { - return v - } - if v == "" { - return k - } - return fmt.Sprintf("%v=%v", k, v) -} - -func describeEvent(ev *trace.Event) string { - switch ev.Type { - case trace.EvGoCreate: - goid := ev.Args[0] - return fmt.Sprintf("new goroutine %d: %s", goid, gs[goid].Name) - case trace.EvGoEnd, trace.EvGoStop: - return "goroutine stopped" - case trace.EvUserLog: - return formatUserLog(ev) - case trace.EvUserRegion: - if ev.Args[1] == 0 { - duration := "unknown" - if ev.Link != nil { - duration = (time.Duration(ev.Link.Ts-ev.Ts) * time.Nanosecond).String() - } - return fmt.Sprintf("region %s started (duration: %v)", ev.SArgs[0], duration) - } - return fmt.Sprintf("region %s ended", ev.SArgs[0]) - case trace.EvUserTaskCreate: - return fmt.Sprintf("task %v (id %d, parent %d) created", ev.SArgs[0], ev.Args[0], ev.Args[1]) - // TODO: add child task creation events into the parent task events - case trace.EvUserTaskEnd: - return "task end" - } - return "" -} - -func isUserAnnotationEvent(ev *trace.Event) (taskID uint64, ok bool) { - switch ev.Type { - case trace.EvUserLog, trace.EvUserRegion, trace.EvUserTaskCreate, trace.EvUserTaskEnd: - return ev.Args[0], true - } - return 0, false -} - -var templUserRegionType = template.Must(template.New("").Funcs(template.FuncMap{ - "prettyDuration": func(nsec int64) template.HTML { - d := time.Duration(nsec) * time.Nanosecond - return template.HTML(d.String()) - }, - "percent": func(dividend, divisor int64) template.HTML { - if divisor == 0 { - return "" - } - return template.HTML(fmt.Sprintf("(%.1f%%)", float64(dividend)/float64(divisor)*100)) - }, - "barLen": func(dividend, divisor int64) template.HTML { - if divisor == 0 { - return "0" - } - return template.HTML(fmt.Sprintf("%.2f%%", float64(dividend)/float64(divisor)*100)) - }, - "unknownTime": func(desc regionDesc) int64 { - sum := desc.ExecTime + desc.IOTime + desc.BlockTime + desc.SyscallTime + desc.SchedWaitTime - if sum < desc.TotalTime { - return desc.TotalTime - sum - } - return 0 - }, - "filterParams": func(f *regionFilter) template.URL { - return template.URL(f.params.Encode()) - }, -}).Parse(` - -User Region {{.Name}} - - - - -

{{.Name}}

- -{{ with $p := filterParams .Filter}} -
WhenElapsedGoroutine IDEvents
{{$el.WhenString}}{{$el.Duration}} -Task {{$el.ID}} -(goroutine view) -({{if .Complete}}complete{{else}}incomplete{{end}})
{{.WhenString}}{{elapsed .Elapsed}}{{.Go}}{{.What}}
GC:{{$el.GCTime}}
- - - - -
Network Wait Time: graph(download)
Sync Block Time: graph(download)
Blocking Syscall Time: graph(download)
Scheduler Wait Time: graph(download)
-{{ end }} -

- - - - - - - - - - - - - - -{{range .Data}} - - - - - - - - - - - - - -{{end}} -
Goroutine Task Total Execution Network wait Sync block Blocking syscall Scheduler wait GC sweeping GC pause
{{.G}} {{if .TaskID}}{{.TaskID}}{{end}} {{prettyDuration .TotalTime}} -
- {{if unknownTime .}} {{end}} - {{if .ExecTime}} {{end}} - {{if .IOTime}} {{end}} - {{if .BlockTime}} {{end}} - {{if .SyscallTime}} {{end}} - {{if .SchedWaitTime}} {{end}} -
-
{{prettyDuration .ExecTime}} {{prettyDuration .IOTime}} {{prettyDuration .BlockTime}} {{prettyDuration .SyscallTime}} {{prettyDuration .SchedWaitTime}} {{prettyDuration .SweepTime}} {{percent .SweepTime .TotalTime}} {{prettyDuration .GCTime}} {{percent .GCTime .TotalTime}}
-

-`)) diff --git a/src/cmd/trace/annotations_test.go b/src/cmd/trace/annotations_test.go deleted file mode 100644 index 5585e485f7..0000000000 --- a/src/cmd/trace/annotations_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !js - -package main - -import ( - "testing" - "time" -) - -func TestOverlappingDuration(t *testing.T) { - cases := []struct { - start0, end0, start1, end1 int64 - want time.Duration - }{ - { - 1, 10, 11, 20, 0, - }, - { - 1, 10, 5, 20, 5 * time.Nanosecond, - }, - { - 1, 10, 2, 8, 6 * time.Nanosecond, - }, - } - - for _, tc := range cases { - s0, e0, s1, e1 := tc.start0, tc.end0, tc.start1, tc.end1 - if got := overlappingDuration(s0, e0, s1, e1); got != tc.want { - t.Errorf("overlappingDuration(%d, %d, %d, %d)=%v; want %v", s0, e0, s1, e1, got, tc.want) - } - if got := overlappingDuration(s1, e1, s0, e0); got != tc.want { - t.Errorf("overlappingDuration(%d, %d, %d, %d)=%v; want %v", s1, e1, s0, e0, got, tc.want) - } - } -} diff --git a/src/cmd/trace/gen.go b/src/cmd/trace/gen.go new file mode 100644 index 0000000000..b947489037 --- /dev/null +++ b/src/cmd/trace/gen.go @@ -0,0 +1,394 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "internal/trace" + "internal/trace/traceviewer" + tracev2 "internal/trace/v2" + "strings" +) + +// generator is an interface for generating a JSON trace for the trace viewer +// from a trace. Each method in this interface is a handler for a kind of event +// that is interesting to render in the UI via the JSON trace. +type generator interface { + // Global parts. + Sync() // Notifies the generator of an EventSync event. + StackSample(ctx *traceContext, ev *tracev2.Event) + GlobalRange(ctx *traceContext, ev *tracev2.Event) + GlobalMetric(ctx *traceContext, ev *tracev2.Event) + + // Goroutine parts. + GoroutineLabel(ctx *traceContext, ev *tracev2.Event) + GoroutineRange(ctx *traceContext, ev *tracev2.Event) + GoroutineTransition(ctx *traceContext, ev *tracev2.Event) + + // Proc parts. + ProcRange(ctx *traceContext, ev *tracev2.Event) + ProcTransition(ctx *traceContext, ev *tracev2.Event) + + // User annotations. + Log(ctx *traceContext, ev *tracev2.Event) + + // Finish indicates the end of the trace and finalizes generation. + Finish(ctx *traceContext) +} + +// runGenerator produces a trace into ctx by running the generator over the parsed trace. +func runGenerator(ctx *traceContext, g generator, parsed *parsedTrace, opts *genOpts) { + for i := range parsed.events { + ev := &parsed.events[i] + + switch ev.Kind() { + case tracev2.EventSync: + g.Sync() + case tracev2.EventStackSample: + g.StackSample(ctx, ev) + case tracev2.EventRangeBegin, tracev2.EventRangeActive, tracev2.EventRangeEnd: + r := ev.Range() + switch r.Scope.Kind { + case tracev2.ResourceGoroutine: + g.GoroutineRange(ctx, ev) + case tracev2.ResourceProc: + g.ProcRange(ctx, ev) + case tracev2.ResourceNone: + g.GlobalRange(ctx, ev) + } + case tracev2.EventMetric: + g.GlobalMetric(ctx, ev) + case tracev2.EventLabel: + l := ev.Label() + if l.Resource.Kind == tracev2.ResourceGoroutine { + g.GoroutineLabel(ctx, ev) + } + case tracev2.EventStateTransition: + switch ev.StateTransition().Resource.Kind { + case tracev2.ResourceProc: + g.ProcTransition(ctx, ev) + case tracev2.ResourceGoroutine: + g.GoroutineTransition(ctx, ev) + } + case tracev2.EventLog: + g.Log(ctx, ev) + } + } + for i, task := range opts.tasks { + emitTask(ctx, task, i) + if opts.mode&traceviewer.ModeGoroutineOriented != 0 { + for _, region := range task.Regions { + emitRegion(ctx, region) + } + } + } + g.Finish(ctx) +} + +// emitTask emits information about a task into the trace viewer's event stream. +// +// sortIndex sets the order in which this task will appear related to other tasks, +// lowest first. +func emitTask(ctx *traceContext, task *trace.UserTaskSummary, sortIndex int) { + // Collect information about the task. + var startStack, endStack tracev2.Stack + var startG, endG tracev2.GoID + startTime, endTime := ctx.startTime, ctx.endTime + if task.Start != nil { + startStack = task.Start.Stack() + startG = task.Start.Goroutine() + startTime = task.Start.Time() + } + if task.End != nil { + endStack = task.End.Stack() + endG = task.End.Goroutine() + endTime = task.End.Time() + } + arg := struct { + ID uint64 `json:"id"` + StartG uint64 `json:"start_g,omitempty"` + EndG uint64 `json:"end_g,omitempty"` + }{ + ID: uint64(task.ID), + StartG: uint64(startG), + EndG: uint64(endG), + } + + // Emit the task slice and notify the emitter of the task. + ctx.Task(uint64(task.ID), fmt.Sprintf("T%d %s", task.ID, task.Name), sortIndex) + ctx.TaskSlice(traceviewer.SliceEvent{ + Name: task.Name, + Ts: ctx.elapsed(startTime), + Dur: endTime.Sub(startTime), + Resource: uint64(task.ID), + Stack: ctx.Stack(viewerFrames(startStack)), + EndStack: ctx.Stack(viewerFrames(endStack)), + Arg: arg, + }) + // Emit an arrow from the parent to the child. + if task.Parent != nil && task.Start != nil && task.Start.Kind() == tracev2.EventTaskBegin { + ctx.TaskArrow(traceviewer.ArrowEvent{ + Name: "newTask", + Start: ctx.elapsed(task.Start.Time()), + End: ctx.elapsed(task.Start.Time()), + FromResource: uint64(task.Parent.ID), + ToResource: uint64(task.ID), + FromStack: ctx.Stack(viewerFrames(task.Start.Stack())), + }) + } +} + +// emitRegion emits goroutine-based slice events to the UI. The caller +// must be emitting for a goroutine-oriented trace. +// +// TODO(mknyszek): Make regions part of the regular generator loop and +// treat them like ranges so that we can emit regions in traces oriented +// by proc or thread. +func emitRegion(ctx *traceContext, region *trace.UserRegionSummary) { + if region.Name == "" { + return + } + // Collect information about the region. + var startStack, endStack tracev2.Stack + goroutine := tracev2.NoGoroutine + startTime, endTime := ctx.startTime, ctx.endTime + if region.Start != nil { + startStack = region.Start.Stack() + startTime = region.Start.Time() + goroutine = region.Start.Goroutine() + } + if region.End != nil { + endStack = region.End.Stack() + endTime = region.End.Time() + goroutine = region.End.Goroutine() + } + if goroutine == tracev2.NoGoroutine { + return + } + arg := struct { + TaskID uint64 `json:"taskid"` + }{ + TaskID: uint64(region.TaskID), + } + ctx.AsyncSlice(traceviewer.AsyncSliceEvent{ + SliceEvent: traceviewer.SliceEvent{ + Name: region.Name, + Ts: ctx.elapsed(startTime), + Dur: endTime.Sub(startTime), + Resource: uint64(goroutine), + Stack: ctx.Stack(viewerFrames(startStack)), + EndStack: ctx.Stack(viewerFrames(endStack)), + Arg: arg, + }, + Category: "Region", + Scope: fmt.Sprintf("%x", region.TaskID), + TaskColorIndex: uint64(region.TaskID), + }) +} + +// Building blocks for generators. + +// stackSampleGenerator implements a generic handler for stack sample events. +// The provided resource is the resource the stack sample should count against. +type stackSampleGenerator[R resource] struct { + // getResource is a function to extract a resource ID from a stack sample event. + getResource func(*tracev2.Event) R +} + +// StackSample implements a stack sample event handler. It expects ev to be one such event. +func (g *stackSampleGenerator[R]) StackSample(ctx *traceContext, ev *tracev2.Event) { + id := g.getResource(ev) + if id == R(noResource) { + // We have nowhere to put this in the UI. + return + } + ctx.Instant(traceviewer.InstantEvent{ + Name: "CPU profile sample", + Ts: ctx.elapsed(ev.Time()), + Resource: uint64(id), + Stack: ctx.Stack(viewerFrames(ev.Stack())), + }) +} + +// globalRangeGenerator implements a generic handler for EventRange* events that pertain +// to tracev2.ResourceNone (the global scope). +type globalRangeGenerator struct { + ranges map[string]activeRange + seenSync bool +} + +// Sync notifies the generator of an EventSync event. +func (g *globalRangeGenerator) Sync() { + g.seenSync = true +} + +// GlobalRange implements a handler for EventRange* events whose Scope.Kind is ResourceNone. +// It expects ev to be one such event. +func (g *globalRangeGenerator) GlobalRange(ctx *traceContext, ev *tracev2.Event) { + if g.ranges == nil { + g.ranges = make(map[string]activeRange) + } + r := ev.Range() + switch ev.Kind() { + case tracev2.EventRangeBegin: + g.ranges[r.Name] = activeRange{ev.Time(), ev.Stack()} + case tracev2.EventRangeActive: + // If we've seen a Sync event, then Active events are always redundant. + if !g.seenSync { + // Otherwise, they extend back to the start of the trace. + g.ranges[r.Name] = activeRange{ctx.startTime, ev.Stack()} + } + case tracev2.EventRangeEnd: + // Only emit GC events, because we have nowhere to + // put other events. + ar := g.ranges[r.Name] + if strings.Contains(r.Name, "GC") { + ctx.Slice(traceviewer.SliceEvent{ + Name: r.Name, + Ts: ctx.elapsed(ar.time), + Dur: ev.Time().Sub(ar.time), + Resource: trace.GCP, + Stack: ctx.Stack(viewerFrames(ar.stack)), + EndStack: ctx.Stack(viewerFrames(ev.Stack())), + }) + } + delete(g.ranges, r.Name) + } +} + +// Finish flushes any outstanding ranges at the end of the trace. +func (g *globalRangeGenerator) Finish(ctx *traceContext) { + for name, ar := range g.ranges { + if !strings.Contains(name, "GC") { + continue + } + ctx.Slice(traceviewer.SliceEvent{ + Name: name, + Ts: ctx.elapsed(ar.time), + Dur: ctx.endTime.Sub(ar.time), + Resource: trace.GCP, + Stack: ctx.Stack(viewerFrames(ar.stack)), + }) + } +} + +// globalMetricGenerator implements a generic handler for Metric events. +type globalMetricGenerator struct { +} + +// GlobalMetric implements an event handler for EventMetric events. ev must be one such event. +func (g *globalMetricGenerator) GlobalMetric(ctx *traceContext, ev *tracev2.Event) { + m := ev.Metric() + switch m.Name { + case "/memory/classes/heap/objects:bytes": + ctx.HeapAlloc(ctx.elapsed(ev.Time()), m.Value.Uint64()) + case "/gc/heap/goal:bytes": + ctx.HeapGoal(ctx.elapsed(ev.Time()), m.Value.Uint64()) + case "/sched/gomaxprocs:threads": + ctx.Gomaxprocs(m.Value.Uint64()) + } +} + +// procRangeGenerator implements a generic handler for EventRange* events whose Scope.Kind is +// ResourceProc. +type procRangeGenerator struct { + ranges map[tracev2.Range]activeRange + seenSync bool +} + +// Sync notifies the generator of an EventSync event. +func (g *procRangeGenerator) Sync() { + g.seenSync = true +} + +// ProcRange implements a handler for EventRange* events whose Scope.Kind is ResourceProc. +// It expects ev to be one such event. +func (g *procRangeGenerator) ProcRange(ctx *traceContext, ev *tracev2.Event) { + if g.ranges == nil { + g.ranges = make(map[tracev2.Range]activeRange) + } + r := ev.Range() + switch ev.Kind() { + case tracev2.EventRangeBegin: + g.ranges[r] = activeRange{ev.Time(), ev.Stack()} + case tracev2.EventRangeActive: + // If we've seen a Sync event, then Active events are always redundant. + if !g.seenSync { + // Otherwise, they extend back to the start of the trace. + g.ranges[r] = activeRange{ctx.startTime, ev.Stack()} + } + case tracev2.EventRangeEnd: + // Emit proc-based ranges. + ar := g.ranges[r] + ctx.Slice(traceviewer.SliceEvent{ + Name: r.Name, + Ts: ctx.elapsed(ar.time), + Dur: ev.Time().Sub(ar.time), + Resource: uint64(r.Scope.Proc()), + Stack: ctx.Stack(viewerFrames(ar.stack)), + EndStack: ctx.Stack(viewerFrames(ev.Stack())), + }) + delete(g.ranges, r) + } +} + +// Finish flushes any outstanding ranges at the end of the trace. +func (g *procRangeGenerator) Finish(ctx *traceContext) { + for r, ar := range g.ranges { + ctx.Slice(traceviewer.SliceEvent{ + Name: r.Name, + Ts: ctx.elapsed(ar.time), + Dur: ctx.endTime.Sub(ar.time), + Resource: uint64(r.Scope.Proc()), + Stack: ctx.Stack(viewerFrames(ar.stack)), + }) + } +} + +// activeRange represents an active EventRange* range. +type activeRange struct { + time tracev2.Time + stack tracev2.Stack +} + +// completedRange represents a completed EventRange* range. +type completedRange struct { + name string + startTime tracev2.Time + endTime tracev2.Time + startStack tracev2.Stack + endStack tracev2.Stack + arg any +} + +type logEventGenerator[R resource] struct { + // getResource is a function to extract a resource ID from a Log event. + getResource func(*tracev2.Event) R +} + +// Log implements a log event handler. It expects ev to be one such event. +func (g *logEventGenerator[R]) Log(ctx *traceContext, ev *tracev2.Event) { + id := g.getResource(ev) + if id == R(noResource) { + // We have nowhere to put this in the UI. + return + } + + // Construct the name to present. + log := ev.Log() + name := log.Message + if log.Category != "" { + name = "[" + log.Category + "] " + name + } + + // Emit an instant event. + ctx.Instant(traceviewer.InstantEvent{ + Name: name, + Ts: ctx.elapsed(ev.Time()), + Category: "user event", + Resource: uint64(id), + Stack: ctx.Stack(viewerFrames(ev.Stack())), + }) +} diff --git a/src/cmd/trace/goroutinegen.go b/src/cmd/trace/goroutinegen.go new file mode 100644 index 0000000000..096aa9972a --- /dev/null +++ b/src/cmd/trace/goroutinegen.go @@ -0,0 +1,167 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + tracev2 "internal/trace/v2" +) + +var _ generator = &goroutineGenerator{} + +type goroutineGenerator struct { + globalRangeGenerator + globalMetricGenerator + stackSampleGenerator[tracev2.GoID] + logEventGenerator[tracev2.GoID] + + gStates map[tracev2.GoID]*gState[tracev2.GoID] + focus tracev2.GoID + filter map[tracev2.GoID]struct{} +} + +func newGoroutineGenerator(ctx *traceContext, focus tracev2.GoID, filter map[tracev2.GoID]struct{}) *goroutineGenerator { + gg := new(goroutineGenerator) + rg := func(ev *tracev2.Event) tracev2.GoID { + return ev.Goroutine() + } + gg.stackSampleGenerator.getResource = rg + gg.logEventGenerator.getResource = rg + gg.gStates = make(map[tracev2.GoID]*gState[tracev2.GoID]) + gg.focus = focus + gg.filter = filter + + // Enable a filter on the emitter. + if filter != nil { + ctx.SetResourceFilter(func(resource uint64) bool { + _, ok := filter[tracev2.GoID(resource)] + return ok + }) + } + return gg +} + +func (g *goroutineGenerator) Sync() { + g.globalRangeGenerator.Sync() +} + +func (g *goroutineGenerator) GoroutineLabel(ctx *traceContext, ev *tracev2.Event) { + l := ev.Label() + g.gStates[l.Resource.Goroutine()].setLabel(l.Label) +} + +func (g *goroutineGenerator) GoroutineRange(ctx *traceContext, ev *tracev2.Event) { + r := ev.Range() + switch ev.Kind() { + case tracev2.EventRangeBegin: + g.gStates[r.Scope.Goroutine()].rangeBegin(ev.Time(), r.Name, ev.Stack()) + case tracev2.EventRangeActive: + g.gStates[r.Scope.Goroutine()].rangeActive(r.Name) + case tracev2.EventRangeEnd: + gs := g.gStates[r.Scope.Goroutine()] + gs.rangeEnd(ev.Time(), r.Name, ev.Stack(), ctx) + } +} + +func (g *goroutineGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event) { + st := ev.StateTransition() + goID := st.Resource.Goroutine() + + // If we haven't seen this goroutine before, create a new + // gState for it. + gs, ok := g.gStates[goID] + if !ok { + gs = newGState[tracev2.GoID](goID) + g.gStates[goID] = gs + } + + // Try to augment the name of the goroutine. + gs.augmentName(st.Stack) + + // Handle the goroutine state transition. + from, to := st.Goroutine() + if from == to { + // Filter out no-op events. + return + } + if from.Executing() && !to.Executing() { + if to == tracev2.GoWaiting { + // Goroutine started blocking. + gs.block(ev.Time(), ev.Stack(), st.Reason, ctx) + } else { + gs.stop(ev.Time(), ev.Stack(), ctx) + } + } + if !from.Executing() && to.Executing() { + start := ev.Time() + if from == tracev2.GoUndetermined { + // Back-date the event to the start of the trace. + start = ctx.startTime + } + gs.start(start, goID, ctx) + } + + if from == tracev2.GoWaiting { + // Goroutine unblocked. + gs.unblock(ev.Time(), ev.Stack(), ev.Goroutine(), ctx) + } + if from == tracev2.GoNotExist && to == tracev2.GoRunnable { + // Goroutine was created. + gs.created(ev.Time(), ev.Goroutine(), ev.Stack()) + } + if from == tracev2.GoSyscall && to != tracev2.GoRunning { + // Exiting blocked syscall. + gs.syscallEnd(ev.Time(), true, ctx) + gs.blockedSyscallEnd(ev.Time(), ev.Stack(), ctx) + } else if from == tracev2.GoSyscall { + // Check if we're exiting a syscall in a non-blocking way. + gs.syscallEnd(ev.Time(), false, ctx) + } + + // Handle syscalls. + if to == tracev2.GoSyscall { + start := ev.Time() + if from == tracev2.GoUndetermined { + // Back-date the event to the start of the trace. + start = ctx.startTime + } + // Write down that we've entered a syscall. Note: we might have no G or P here + // if we're in a cgo callback or this is a transition from GoUndetermined + // (i.e. the G has been blocked in a syscall). + gs.syscallBegin(start, goID, ev.Stack()) + } + + // Note down the goroutine transition. + _, inMarkAssist := gs.activeRanges["GC mark assist"] + ctx.GoroutineTransition(ctx.elapsed(ev.Time()), viewerGState(from, inMarkAssist), viewerGState(to, inMarkAssist)) +} + +func (g *goroutineGenerator) ProcRange(ctx *traceContext, ev *tracev2.Event) { + // TODO(mknyszek): Extend procRangeGenerator to support rendering proc ranges + // that overlap with a goroutine's execution. +} + +func (g *goroutineGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { + // Not needed. All relevant information for goroutines can be derived from goroutine transitions. +} + +func (g *goroutineGenerator) Finish(ctx *traceContext) { + ctx.SetResourceType("G") + + // Finish off global ranges. + g.globalRangeGenerator.Finish(ctx) + + // Finish off all the goroutine slices. + for id, gs := range g.gStates { + gs.finish(ctx) + + // Tell the emitter about the goroutines we want to render. + ctx.Resource(uint64(id), gs.name()) + } + + // Set the goroutine to focus on. + if g.focus != tracev2.NoGoroutine { + ctx.Focus(uint64(g.focus)) + } +} diff --git a/src/cmd/trace/goroutines.go b/src/cmd/trace/goroutines.go index 28eace82fa..be003861a6 100644 --- a/src/cmd/trace/goroutines.go +++ b/src/cmd/trace/goroutines.go @@ -7,210 +7,262 @@ package main import ( + "cmp" "fmt" "html/template" "internal/trace" + "internal/trace/traceviewer" + tracev2 "internal/trace/v2" "log" "net/http" - "reflect" + "slices" "sort" - "strconv" - "sync" + "strings" "time" ) -func init() { - http.HandleFunc("/goroutines", httpGoroutines) - http.HandleFunc("/goroutine", httpGoroutine) -} - -// gtype describes a group of goroutines grouped by start PC. -type gtype struct { - ID uint64 // Unique identifier (PC). - Name string // Start function. - N int // Total number of goroutines in this group. - ExecTime int64 // Total execution time of all goroutines in this group. -} - -var ( - gsInit sync.Once - gs map[uint64]*trace.GDesc -) - -// analyzeGoroutines generates statistics about execution of all goroutines and stores them in gs. -func analyzeGoroutines(events []*trace.Event) { - gsInit.Do(func() { - gs = trace.GoroutineStats(events) - }) -} - -// httpGoroutines serves list of goroutine groups. -func httpGoroutines(w http.ResponseWriter, r *http.Request) { - events, err := parseEvents() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - analyzeGoroutines(events) - gss := make(map[uint64]gtype) - for _, g := range gs { - gs1 := gss[g.PC] - gs1.ID = g.PC - gs1.Name = g.Name - gs1.N++ - gs1.ExecTime += g.ExecTime - gss[g.PC] = gs1 - } - var glist []gtype - for k, v := range gss { - v.ID = k - // If goroutine didn't run during the trace (no sampled PC), - // the v.ID and v.Name will be zero value. - if v.ID == 0 && v.Name == "" { - v.Name = "(Inactive, no stack trace sampled)" +// GoroutinesHandlerFunc returns a HandlerFunc that serves list of goroutine groups. +func GoroutinesHandlerFunc(summaries map[tracev2.GoID]*trace.GoroutineSummary) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // goroutineGroup describes a group of goroutines grouped by name. + type goroutineGroup struct { + Name string // Start function. + N int // Total number of goroutines in this group. + ExecTime time.Duration // Total execution time of all goroutines in this group. + } + // Accumulate groups by Name. + groupsByName := make(map[string]goroutineGroup) + for _, summary := range summaries { + group := groupsByName[summary.Name] + group.Name = summary.Name + group.N++ + group.ExecTime += summary.ExecTime + groupsByName[summary.Name] = group + } + var groups []goroutineGroup + for _, group := range groupsByName { + groups = append(groups, group) + } + slices.SortFunc(groups, func(a, b goroutineGroup) int { + return cmp.Compare(b.ExecTime, a.ExecTime) + }) + w.Header().Set("Content-Type", "text/html;charset=utf-8") + if err := templGoroutines.Execute(w, groups); err != nil { + log.Printf("failed to execute template: %v", err) + return } - glist = append(glist, v) - } - sort.Slice(glist, func(i, j int) bool { return glist[i].ExecTime > glist[j].ExecTime }) - w.Header().Set("Content-Type", "text/html;charset=utf-8") - if err := templGoroutines.Execute(w, glist); err != nil { - log.Printf("failed to execute template: %v", err) - return } } var templGoroutines = template.Must(template.New("").Parse(` + -Goroutines:
+

Goroutines

+Below is a table of all goroutines in the trace grouped by start location and sorted by the total execution time of the group.
+
+Click a start location to view more details about that group.
+
+ + + + + + {{range $}} - {{.Name}} N={{.N}}
+ + + + + {{end}} +
Start locationCountTotal execution time
{{or .Name "(Inactive, no stack trace sampled)"}}{{.N}}{{.ExecTime}}
`)) -// httpGoroutine serves list of goroutines in a particular group. -func httpGoroutine(w http.ResponseWriter, r *http.Request) { - // TODO(hyangah): support format=csv (raw data) +// GoroutineHandler creates a handler that serves information about +// goroutines in a particular group. +func GoroutineHandler(summaries map[tracev2.GoID]*trace.GoroutineSummary) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + goroutineName := r.FormValue("name") - events, err := parseEvents() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } + type goroutine struct { + *trace.GoroutineSummary + NonOverlappingStats map[string]time.Duration + HasRangeTime bool + } - pc, err := strconv.ParseUint(r.FormValue("id"), 10, 64) - if err != nil { - http.Error(w, fmt.Sprintf("failed to parse id parameter '%v': %v", r.FormValue("id"), err), http.StatusInternalServerError) - return - } - analyzeGoroutines(events) - var ( - glist []*trace.GDesc - name string - totalExecTime, execTime int64 - maxTotalTime int64 - ) + // Collect all the goroutines in the group. + var ( + goroutines []goroutine + name string + totalExecTime, execTime time.Duration + maxTotalTime time.Duration + ) + validNonOverlappingStats := make(map[string]struct{}) + validRangeStats := make(map[string]struct{}) + for _, summary := range summaries { + totalExecTime += summary.ExecTime - for _, g := range gs { - totalExecTime += g.ExecTime + if summary.Name != goroutineName { + continue + } + nonOverlappingStats := summary.NonOverlappingStats() + for name := range nonOverlappingStats { + validNonOverlappingStats[name] = struct{}{} + } + var totalRangeTime time.Duration + for name, dt := range summary.RangeTime { + validRangeStats[name] = struct{}{} + totalRangeTime += dt + } + goroutines = append(goroutines, goroutine{ + GoroutineSummary: summary, + NonOverlappingStats: nonOverlappingStats, + HasRangeTime: totalRangeTime != 0, + }) + name = summary.Name + execTime += summary.ExecTime + if maxTotalTime < summary.TotalTime { + maxTotalTime = summary.TotalTime + } + } - if g.PC != pc { - continue + // Compute the percent of total execution time these goroutines represent. + execTimePercent := "" + if totalExecTime > 0 { + execTimePercent = fmt.Sprintf("%.2f%%", float64(execTime)/float64(totalExecTime)*100) } - glist = append(glist, g) - name = g.Name - execTime += g.ExecTime - if maxTotalTime < g.TotalTime { - maxTotalTime = g.TotalTime + + // Sort. + sortBy := r.FormValue("sortby") + if _, ok := validNonOverlappingStats[sortBy]; ok { + slices.SortFunc(goroutines, func(a, b goroutine) int { + return cmp.Compare(b.NonOverlappingStats[sortBy], a.NonOverlappingStats[sortBy]) + }) + } else { + // Sort by total time by default. + slices.SortFunc(goroutines, func(a, b goroutine) int { + return cmp.Compare(b.TotalTime, a.TotalTime) + }) } - } - execTimePercent := "" - if totalExecTime > 0 { - execTimePercent = fmt.Sprintf("%.2f%%", float64(execTime)/float64(totalExecTime)*100) - } + // Write down all the non-overlapping stats and sort them. + allNonOverlappingStats := make([]string, 0, len(validNonOverlappingStats)) + for name := range validNonOverlappingStats { + allNonOverlappingStats = append(allNonOverlappingStats, name) + } + slices.SortFunc(allNonOverlappingStats, func(a, b string) int { + if a == b { + return 0 + } + if a == "Execution time" { + return -1 + } + if b == "Execution time" { + return 1 + } + return cmp.Compare(a, b) + }) - sortby := r.FormValue("sortby") - _, ok := reflect.TypeOf(trace.GDesc{}).FieldByNameFunc(func(s string) bool { - return s == sortby - }) - if !ok { - sortby = "TotalTime" - } + // Write down all the range stats and sort them. + allRangeStats := make([]string, 0, len(validRangeStats)) + for name := range validRangeStats { + allRangeStats = append(allRangeStats, name) + } + sort.Strings(allRangeStats) - sort.Slice(glist, func(i, j int) bool { - ival := reflect.ValueOf(glist[i]).Elem().FieldByName(sortby).Int() - jval := reflect.ValueOf(glist[j]).Elem().FieldByName(sortby).Int() - return ival > jval - }) + err := templGoroutine.Execute(w, struct { + Name string + N int + ExecTimePercent string + MaxTotal time.Duration + Goroutines []goroutine + NonOverlappingStats []string + RangeStats []string + }{ + Name: name, + N: len(goroutines), + ExecTimePercent: execTimePercent, + MaxTotal: maxTotalTime, + Goroutines: goroutines, + NonOverlappingStats: allNonOverlappingStats, + RangeStats: allRangeStats, + }) + if err != nil { + http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) + return + } + } +} - err = templGoroutine.Execute(w, struct { - Name string - PC uint64 - N int - ExecTimePercent string - MaxTotal int64 - GList []*trace.GDesc - }{ - Name: name, - PC: pc, - N: len(glist), - ExecTimePercent: execTimePercent, - MaxTotal: maxTotalTime, - GList: glist}) - if err != nil { - http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) - return +func stat2Color(statName string) string { + color := "#636363" + if strings.HasPrefix(statName, "Block time") { + color = "#d01c8b" + } + switch statName { + case "Sched wait time": + color = "#2c7bb6" + case "Syscall execution time": + color = "#7b3294" + case "Execution time": + color = "#d7191c" } + return color } var templGoroutine = template.Must(template.New("").Funcs(template.FuncMap{ - "prettyDuration": func(nsec int64) template.HTML { - d := time.Duration(nsec) * time.Nanosecond - return template.HTML(d.String()) - }, - "percent": func(dividend, divisor int64) template.HTML { + "percent": func(dividend, divisor time.Duration) template.HTML { if divisor == 0 { return "" } return template.HTML(fmt.Sprintf("(%.1f%%)", float64(dividend)/float64(divisor)*100)) }, - "barLen": func(dividend, divisor int64) template.HTML { - if divisor == 0 { - return "0" - } - return template.HTML(fmt.Sprintf("%.2f%%", float64(dividend)/float64(divisor)*100)) + "headerStyle": func(statName string) template.HTMLAttr { + return template.HTMLAttr(fmt.Sprintf("style=\"background-color: %s;\"", stat2Color(statName))) }, - "unknownTime": func(desc *trace.GDesc) int64 { - sum := desc.ExecTime + desc.IOTime + desc.BlockTime + desc.SyscallTime + desc.SchedWaitTime - if sum < desc.TotalTime { - return desc.TotalTime - sum + "barStyle": func(statName string, dividend, divisor time.Duration) template.HTMLAttr { + width := "0" + if divisor != 0 { + width = fmt.Sprintf("%.2f%%", float64(dividend)/float64(divisor)*100) } - return 0 + return template.HTMLAttr(fmt.Sprintf("style=\"width: %s; background-color: %s;\"", width, stat2Color(statName))) }, }).Parse(` -Goroutine {{.Name}} - +

Goroutines

+ +Table of contents + + +

Summary

+ - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Goroutine Name:{{.Name}}
Number of Goroutines:{{.N}}
Execution Time:{{.ExecTimePercent}} of total program execution time
Network Wait Time: graph(download)
Sync Block Time: graph(download)
Blocking Syscall Time: graph(download)
Scheduler Wait Time: graph(download)
Goroutine start location:{{.Name}}
Count:{{.N}}
Execution Time:{{.ExecTimePercent}} of total program execution time
Network wait profile: graph (download)
Sync block profile: graph (download)
Syscall profile: graph (download)
Scheduler wait profile: graph (download)
-

+ +

Breakdown

+ +The table below breaks down where each goroutine is spent its time during the +traced period. +All of the columns except total time are non-overlapping. +
+
+ - + - - - - - - - +{{range $.NonOverlappingStats}} + +{{end}} -{{range .GList}} - - - - - - - - - - - - +{{range .Goroutines}} + + + + + {{$Goroutine := .}} + {{range $.NonOverlappingStats}} + {{$Time := index $Goroutine.NonOverlappingStats .}} + + {{end}} + +{{end}} +
Goroutine Total Total Execution Network wait Sync block Blocking syscall Scheduler wait GC sweeping GC pause {{.}}
{{.ID}} {{prettyDuration .TotalTime}} -
- {{if unknownTime .}} {{end}} - {{if .ExecTime}} {{end}} - {{if .IOTime}} {{end}} - {{if .BlockTime}} {{end}} - {{if .SyscallTime}} {{end}} - {{if .SchedWaitTime}} {{end}} -
-
{{prettyDuration .ExecTime}} {{prettyDuration .IOTime}} {{prettyDuration .BlockTime}} {{prettyDuration .SyscallTime}} {{prettyDuration .SchedWaitTime}} {{prettyDuration .SweepTime}} {{percent .SweepTime .TotalTime}} {{prettyDuration .GCTime}} {{percent .GCTime .TotalTime}}
{{.ID}} {{ .TotalTime.String }} +
+ {{$Goroutine := .}} + {{range $.NonOverlappingStats}} + {{$Time := index $Goroutine.NonOverlappingStats .}} + {{if $Time}} +   + {{end}} + {{end}} +
+
{{$Time.String}}
+ +

Special ranges

+ +The table below describes how much of the traced period each goroutine spent in +certain special time ranges. +If a goroutine has spent no time in any special time ranges, it is excluded from +the table. +For example, how much time it spent helping the GC. Note that these times do +overlap with the times from the first table. +In general the goroutine may not be executing in these special time ranges. +For example, it may have blocked while trying to help the GC. +This must be taken into account when interpreting the data. +
+
+ + + + + +{{range $.RangeStats}} + +{{end}} + +{{range .Goroutines}} + {{if .HasRangeTime}} + + + + {{$Goroutine := .}} + {{range $.RangeStats}} + {{$Time := index $Goroutine.RangeTime .}} + + {{end}} + + {{end}} {{end}}
Goroutine Total {{.}}
{{.ID}} {{ .TotalTime.String }} {{$Time.String}}
`)) diff --git a/src/cmd/trace/gstate.go b/src/cmd/trace/gstate.go new file mode 100644 index 0000000000..4535929093 --- /dev/null +++ b/src/cmd/trace/gstate.go @@ -0,0 +1,373 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "internal/trace" + "internal/trace/traceviewer" + "internal/trace/traceviewer/format" + tracev2 "internal/trace/v2" + "strings" +) + +// resource is a generic constraint interface for resource IDs. +type resource interface { + tracev2.GoID | tracev2.ProcID | tracev2.ThreadID +} + +// noResource indicates the lack of a resource. +const noResource = -1 + +// gState represents the trace viewer state of a goroutine in a trace. +// +// The type parameter on this type is the resource which is used to construct +// a timeline of events. e.g. R=ProcID for a proc-oriented view, R=GoID for +// a goroutine-oriented view, etc. +type gState[R resource] struct { + baseName string + named bool // Whether baseName has been set. + label string // EventLabel extension. + isSystemG bool + + executing R // The resource this goroutine is executing on. (Could be itself.) + + // lastStopStack is the stack trace at the point of the last + // call to the stop method. This tends to be a more reliable way + // of picking up stack traces, since the parser doesn't provide + // a stack for every state transition event. + lastStopStack tracev2.Stack + + // activeRanges is the set of all active ranges on the goroutine. + activeRanges map[string]activeRange + + // completedRanges is a list of ranges that completed since before the + // goroutine stopped executing. These are flushed on every stop or block. + completedRanges []completedRange + + // startRunning is the most recent event that caused a goroutine to + // transition to GoRunning. + startRunningTime tracev2.Time + + // startSyscall is the most recent event that caused a goroutine to + // transition to GoSyscall. + syscall struct { + time tracev2.Time + stack tracev2.Stack + active bool + } + + // startBlockReason is the StateTransition.Reason of the most recent + // event that caused a goroutine to transition to GoWaiting. + startBlockReason string + + // startCause is the event that allowed this goroutine to start running. + // It's used to generate flow events. This is typically something like + // an unblock event or a goroutine creation event. + // + // startCause.resource is the resource on which startCause happened, but is + // listed separately because the cause may have happened on a resource that + // isn't R (or perhaps on some abstract nebulous resource, like trace.NetpollP). + startCause struct { + time tracev2.Time + name string + resource uint64 + stack tracev2.Stack + } +} + +// newGState constructs a new goroutine state for the goroutine +// identified by the provided ID. +func newGState[R resource](goID tracev2.GoID) *gState[R] { + return &gState[R]{ + baseName: fmt.Sprintf("G%d", goID), + executing: R(noResource), + activeRanges: make(map[string]activeRange), + } +} + +// augmentName attempts to use stk to augment the name of the goroutine +// with stack information. This stack must be related to the goroutine +// in some way, but it doesn't really matter which stack. +func (gs *gState[R]) augmentName(stk tracev2.Stack) { + if gs.named { + return + } + if stk == tracev2.NoStack { + return + } + name := lastFunc(stk) + gs.baseName += fmt.Sprintf(" %s", name) + gs.named = true + gs.isSystemG = trace.IsSystemGoroutine(name) +} + +// setLabel adds an additional label to the goroutine's name. +func (gs *gState[R]) setLabel(label string) { + gs.label = label +} + +// name returns a name for the goroutine. +func (gs *gState[R]) name() string { + name := gs.baseName + if gs.label != "" { + name += " (" + gs.label + ")" + } + return name +} + +// setStartCause sets the reason a goroutine will be allowed to start soon. +// For example, via unblocking or exiting a blocked syscall. +func (gs *gState[R]) setStartCause(ts tracev2.Time, name string, resource uint64, stack tracev2.Stack) { + gs.startCause.time = ts + gs.startCause.name = name + gs.startCause.resource = resource + gs.startCause.stack = stack +} + +// created indicates that this goroutine was just created by the provided creator. +func (gs *gState[R]) created(ts tracev2.Time, creator R, stack tracev2.Stack) { + if creator == R(noResource) { + return + } + gs.setStartCause(ts, "go", uint64(creator), stack) +} + +// start indicates that a goroutine has started running on a proc. +func (gs *gState[R]) start(ts tracev2.Time, resource R, ctx *traceContext) { + // Set the time for all the active ranges. + for name := range gs.activeRanges { + gs.activeRanges[name] = activeRange{ts, tracev2.NoStack} + } + + if gs.startCause.name != "" { + // It has a start cause. Emit a flow event. + ctx.Arrow(traceviewer.ArrowEvent{ + Name: gs.startCause.name, + Start: ctx.elapsed(gs.startCause.time), + End: ctx.elapsed(ts), + FromResource: uint64(gs.startCause.resource), + ToResource: uint64(resource), + FromStack: ctx.Stack(viewerFrames(gs.startCause.stack)), + }) + gs.startCause.time = 0 + gs.startCause.name = "" + gs.startCause.resource = 0 + gs.startCause.stack = tracev2.NoStack + } + gs.executing = resource + gs.startRunningTime = ts +} + +// syscallBegin indicates that the goroutine entered a syscall on a proc. +func (gs *gState[R]) syscallBegin(ts tracev2.Time, resource R, stack tracev2.Stack) { + gs.syscall.time = ts + gs.syscall.stack = stack + gs.syscall.active = true + if gs.executing == R(noResource) { + gs.executing = resource + gs.startRunningTime = ts + } +} + +// syscallEnd ends the syscall slice, wherever the syscall is at. This is orthogonal +// to blockedSyscallEnd -- both must be called when a syscall ends and that syscall +// blocked. They're kept separate because syscallEnd indicates the point at which the +// goroutine is no longer executing on the resource (e.g. a proc) whereas blockedSyscallEnd +// is the point at which the goroutine actually exited the syscall regardless of which +// resource that happened on. +func (gs *gState[R]) syscallEnd(ts tracev2.Time, blocked bool, ctx *traceContext) { + if !gs.syscall.active { + return + } + blockString := "no" + if blocked { + blockString = "yes" + } + gs.completedRanges = append(gs.completedRanges, completedRange{ + name: "syscall", + startTime: gs.syscall.time, + endTime: ts, + startStack: gs.syscall.stack, + arg: format.BlockedArg{Blocked: blockString}, + }) + gs.syscall.active = false + gs.syscall.time = 0 + gs.syscall.stack = tracev2.NoStack +} + +// blockedSyscallEnd indicates the point at which the blocked syscall ended. This is distinct +// and orthogonal to syscallEnd; both must be called if the syscall blocked. This sets up an instant +// to emit a flow event from, indicating explicitly that this goroutine was unblocked by the system. +func (gs *gState[R]) blockedSyscallEnd(ts tracev2.Time, stack tracev2.Stack, ctx *traceContext) { + name := "exit blocked syscall" + gs.setStartCause(ts, name, trace.SyscallP, stack) + + // Emit an syscall exit instant event for the "Syscall" lane. + ctx.Instant(traceviewer.InstantEvent{ + Name: name, + Ts: ctx.elapsed(ts), + Resource: trace.SyscallP, + Stack: ctx.Stack(viewerFrames(stack)), + }) +} + +// unblock indicates that the goroutine gs represents has been unblocked. +func (gs *gState[R]) unblock(ts tracev2.Time, stack tracev2.Stack, resource R, ctx *traceContext) { + name := "unblock" + viewerResource := uint64(resource) + if gs.startBlockReason != "" { + name = fmt.Sprintf("%s (%s)", name, gs.startBlockReason) + } + if strings.Contains(gs.startBlockReason, "network") { + // Attribute the network instant to the nebulous "NetpollP" if + // resource isn't a thread, because there's a good chance that + // resource isn't going to be valid in this case. + // + // TODO(mknyszek): Handle this invalidness in a more general way. + if _, ok := any(resource).(tracev2.ThreadID); !ok { + // Emit an unblock instant event for the "Network" lane. + viewerResource = trace.NetpollP + } + ctx.Instant(traceviewer.InstantEvent{ + Name: name, + Ts: ctx.elapsed(ts), + Resource: viewerResource, + Stack: ctx.Stack(viewerFrames(stack)), + }) + } + gs.startBlockReason = "" + if viewerResource != 0 { + gs.setStartCause(ts, name, viewerResource, stack) + } +} + +// block indicates that the goroutine has stopped executing on a proc -- specifically, +// it blocked for some reason. +func (gs *gState[R]) block(ts tracev2.Time, stack tracev2.Stack, reason string, ctx *traceContext) { + gs.startBlockReason = reason + gs.stop(ts, stack, ctx) +} + +// stop indicates that the goroutine has stopped executing on a proc. +func (gs *gState[R]) stop(ts tracev2.Time, stack tracev2.Stack, ctx *traceContext) { + // Emit the execution time slice. + var stk int + if gs.lastStopStack != tracev2.NoStack { + stk = ctx.Stack(viewerFrames(gs.lastStopStack)) + } + // Check invariants. + if gs.startRunningTime == 0 { + panic("silently broken trace or generator invariant (startRunningTime != 0) not held") + } + if gs.executing == R(noResource) { + panic("non-executing goroutine stopped") + } + ctx.Slice(traceviewer.SliceEvent{ + Name: gs.name(), + Ts: ctx.elapsed(gs.startRunningTime), + Dur: ts.Sub(gs.startRunningTime), + Resource: uint64(gs.executing), + Stack: stk, + }) + + // Flush completed ranges. + for _, cr := range gs.completedRanges { + ctx.Slice(traceviewer.SliceEvent{ + Name: cr.name, + Ts: ctx.elapsed(cr.startTime), + Dur: cr.endTime.Sub(cr.startTime), + Resource: uint64(gs.executing), + Stack: ctx.Stack(viewerFrames(cr.startStack)), + EndStack: ctx.Stack(viewerFrames(cr.endStack)), + Arg: cr.arg, + }) + } + gs.completedRanges = gs.completedRanges[:0] + + // Continue in-progress ranges. + for name, r := range gs.activeRanges { + // Check invariant. + if r.time == 0 { + panic("silently broken trace or generator invariant (activeRanges time != 0) not held") + } + ctx.Slice(traceviewer.SliceEvent{ + Name: name, + Ts: ctx.elapsed(r.time), + Dur: ts.Sub(r.time), + Resource: uint64(gs.executing), + Stack: ctx.Stack(viewerFrames(r.stack)), + }) + } + + // Clear the range info. + for name := range gs.activeRanges { + gs.activeRanges[name] = activeRange{0, tracev2.NoStack} + } + + gs.startRunningTime = 0 + gs.lastStopStack = stack + gs.executing = R(noResource) +} + +// finalize writes out any in-progress slices as if the goroutine stopped. +// This must only be used once the trace has been fully processed and no +// further events will be processed. This method may leave the gState in +// an inconsistent state. +func (gs *gState[R]) finish(ctx *traceContext) { + if gs.executing != R(noResource) { + gs.syscallEnd(ctx.endTime, false, ctx) + gs.stop(ctx.endTime, tracev2.NoStack, ctx) + } +} + +// rangeBegin indicates the start of a special range of time. +func (gs *gState[R]) rangeBegin(ts tracev2.Time, name string, stack tracev2.Stack) { + if gs.executing != R(noResource) { + // If we're executing, start the slice from here. + gs.activeRanges[name] = activeRange{ts, stack} + } else { + // If the goroutine isn't executing, there's no place for + // us to create a slice from. Wait until it starts executing. + gs.activeRanges[name] = activeRange{0, stack} + } +} + +// rangeActive indicates that a special range of time has been in progress. +func (gs *gState[R]) rangeActive(name string) { + if gs.executing != R(noResource) { + // If we're executing, and the range is active, then start + // from wherever the goroutine started running from. + gs.activeRanges[name] = activeRange{gs.startRunningTime, tracev2.NoStack} + } else { + // If the goroutine isn't executing, there's no place for + // us to create a slice from. Wait until it starts executing. + gs.activeRanges[name] = activeRange{0, tracev2.NoStack} + } +} + +// rangeEnd indicates the end of a special range of time. +func (gs *gState[R]) rangeEnd(ts tracev2.Time, name string, stack tracev2.Stack, ctx *traceContext) { + if gs.executing != R(noResource) { + r := gs.activeRanges[name] + gs.completedRanges = append(gs.completedRanges, completedRange{ + name: name, + startTime: r.time, + endTime: ts, + startStack: r.stack, + endStack: stack, + }) + } + delete(gs.activeRanges, name) +} + +func lastFunc(s tracev2.Stack) string { + var last tracev2.StackFrame + s.Frames(func(f tracev2.StackFrame) bool { + last = f + return true + }) + return last.Func +} diff --git a/src/cmd/trace/jsontrace.go b/src/cmd/trace/jsontrace.go new file mode 100644 index 0000000000..cdb1cd65bb --- /dev/null +++ b/src/cmd/trace/jsontrace.go @@ -0,0 +1,229 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "cmp" + "log" + "math" + "net/http" + "slices" + "strconv" + "time" + + "internal/trace" + "internal/trace/traceviewer" + tracev2 "internal/trace/v2" +) + +func JSONTraceHandler(parsed *parsedTrace) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + opts := defaultGenOpts() + + switch r.FormValue("view") { + case "thread": + opts.mode = traceviewer.ModeThreadOriented + } + if goids := r.FormValue("goid"); goids != "" { + // Render trace focused on a particular goroutine. + + id, err := strconv.ParseUint(goids, 10, 64) + if err != nil { + log.Printf("failed to parse goid parameter %q: %v", goids, err) + return + } + goid := tracev2.GoID(id) + g, ok := parsed.summary.Goroutines[goid] + if !ok { + log.Printf("failed to find goroutine %d", goid) + return + } + opts.mode = traceviewer.ModeGoroutineOriented + if g.StartTime != 0 { + opts.startTime = g.StartTime.Sub(parsed.startTime()) + } else { + opts.startTime = 0 + } + if g.EndTime != 0 { + opts.endTime = g.EndTime.Sub(parsed.startTime()) + } else { // The goroutine didn't end. + opts.endTime = parsed.endTime().Sub(parsed.startTime()) + } + opts.focusGoroutine = goid + opts.goroutines = trace.RelatedGoroutinesV2(parsed.events, goid) + } else if taskids := r.FormValue("focustask"); taskids != "" { + taskid, err := strconv.ParseUint(taskids, 10, 64) + if err != nil { + log.Printf("failed to parse focustask parameter %q: %v", taskids, err) + return + } + task, ok := parsed.summary.Tasks[tracev2.TaskID(taskid)] + if !ok || (task.Start == nil && task.End == nil) { + log.Printf("failed to find task with id %d", taskid) + return + } + opts.setTask(parsed, task) + } else if taskids := r.FormValue("taskid"); taskids != "" { + taskid, err := strconv.ParseUint(taskids, 10, 64) + if err != nil { + log.Printf("failed to parse taskid parameter %q: %v", taskids, err) + return + } + task, ok := parsed.summary.Tasks[tracev2.TaskID(taskid)] + if !ok { + log.Printf("failed to find task with id %d", taskid) + return + } + // This mode is goroutine-oriented. + opts.mode = traceviewer.ModeGoroutineOriented + opts.setTask(parsed, task) + + // Pick the goroutine to orient ourselves around by just + // trying to pick the earliest event in the task that makes + // any sense. Though, we always want the start if that's there. + var firstEv *tracev2.Event + if task.Start != nil { + firstEv = task.Start + } else { + for _, logEv := range task.Logs { + if firstEv == nil || logEv.Time() < firstEv.Time() { + firstEv = logEv + } + } + if task.End != nil && (firstEv == nil || task.End.Time() < firstEv.Time()) { + firstEv = task.End + } + } + if firstEv == nil || firstEv.Goroutine() == tracev2.NoGoroutine { + log.Printf("failed to find task with id %d", taskid) + return + } + + // Set the goroutine filtering options. + goid := firstEv.Goroutine() + opts.focusGoroutine = goid + goroutines := make(map[tracev2.GoID]struct{}) + for _, task := range opts.tasks { + // Find only directly involved goroutines. + for id := range task.Goroutines { + goroutines[id] = struct{}{} + } + } + opts.goroutines = goroutines + } + + // Parse start and end options. Both or none must be present. + start := int64(0) + end := int64(math.MaxInt64) + if startStr, endStr := r.FormValue("start"), r.FormValue("end"); startStr != "" && endStr != "" { + var err error + start, err = strconv.ParseInt(startStr, 10, 64) + if err != nil { + log.Printf("failed to parse start parameter %q: %v", startStr, err) + return + } + + end, err = strconv.ParseInt(endStr, 10, 64) + if err != nil { + log.Printf("failed to parse end parameter %q: %v", endStr, err) + return + } + } + + c := traceviewer.ViewerDataTraceConsumer(w, start, end) + if err := generateTrace(parsed, opts, c); err != nil { + log.Printf("failed to generate trace: %v", err) + } + }) +} + +// traceContext is a wrapper around a traceviewer.Emitter with some additional +// information that's useful to most parts of trace viewer JSON emission. +type traceContext struct { + *traceviewer.Emitter + startTime tracev2.Time + endTime tracev2.Time +} + +// elapsed returns the elapsed time between the trace time and the start time +// of the trace. +func (ctx *traceContext) elapsed(now tracev2.Time) time.Duration { + return now.Sub(ctx.startTime) +} + +type genOpts struct { + mode traceviewer.Mode + startTime time.Duration + endTime time.Duration + + // Used if mode != 0. + focusGoroutine tracev2.GoID + goroutines map[tracev2.GoID]struct{} // Goroutines to be displayed for goroutine-oriented or task-oriented view. goroutines[0] is the main goroutine. + tasks []*trace.UserTaskSummary +} + +// setTask sets a task to focus on. +func (opts *genOpts) setTask(parsed *parsedTrace, task *trace.UserTaskSummary) { + opts.mode |= traceviewer.ModeTaskOriented + if task.Start != nil { + opts.startTime = task.Start.Time().Sub(parsed.startTime()) + } else { // The task started before the trace did. + opts.startTime = 0 + } + if task.End != nil { + opts.endTime = task.End.Time().Sub(parsed.startTime()) + } else { // The task didn't end. + opts.endTime = parsed.endTime().Sub(parsed.startTime()) + } + opts.tasks = task.Descendents() + slices.SortStableFunc(opts.tasks, func(a, b *trace.UserTaskSummary) int { + aStart, bStart := parsed.startTime(), parsed.startTime() + if a.Start != nil { + aStart = a.Start.Time() + } + if b.Start != nil { + bStart = b.Start.Time() + } + if a.Start != b.Start { + return cmp.Compare(aStart, bStart) + } + // Break ties with the end time. + aEnd, bEnd := parsed.endTime(), parsed.endTime() + if a.End != nil { + aEnd = a.End.Time() + } + if b.End != nil { + bEnd = b.End.Time() + } + return cmp.Compare(aEnd, bEnd) + }) +} + +func defaultGenOpts() *genOpts { + return &genOpts{ + startTime: time.Duration(0), + endTime: time.Duration(math.MaxInt64), + } +} + +func generateTrace(parsed *parsedTrace, opts *genOpts, c traceviewer.TraceConsumer) error { + ctx := &traceContext{ + Emitter: traceviewer.NewEmitter(c, opts.startTime, opts.endTime), + startTime: parsed.events[0].Time(), + endTime: parsed.events[len(parsed.events)-1].Time(), + } + defer ctx.Flush() + + var g generator + if opts.mode&traceviewer.ModeGoroutineOriented != 0 { + g = newGoroutineGenerator(ctx, opts.focusGoroutine, opts.goroutines) + } else if opts.mode&traceviewer.ModeThreadOriented != 0 { + g = newThreadGenerator() + } else { + g = newProcGenerator() + } + runGenerator(ctx, g, parsed, opts) + return nil +} diff --git a/src/cmd/trace/jsontrace_test.go b/src/cmd/trace/jsontrace_test.go new file mode 100644 index 0000000000..74b37a239f --- /dev/null +++ b/src/cmd/trace/jsontrace_test.go @@ -0,0 +1,291 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bytes" + "encoding/json" + tracev1 "internal/trace" + "io" + "net/http/httptest" + "os" + "path/filepath" + "slices" + "strconv" + "strings" + "testing" + "time" + + "internal/trace/traceviewer/format" + "internal/trace/v2/raw" +) + +func TestJSONTraceHandler(t *testing.T) { + testPaths, err := filepath.Glob("./testdata/*.test") + if err != nil { + t.Fatalf("discovering tests: %v", err) + } + for _, testPath := range testPaths { + t.Run(filepath.Base(testPath), func(t *testing.T) { + parsed := getTestTrace(t, testPath) + data := recordJSONTraceHandlerResponse(t, parsed) + // TODO(mknyszek): Check that there's one at most goroutine per proc at any given time. + checkExecutionTimes(t, data) + checkPlausibleHeapMetrics(t, data) + // TODO(mknyszek): Check for plausible thread and goroutine metrics. + checkMetaNamesEmitted(t, data, "process_name", []string{"STATS", "PROCS"}) + checkMetaNamesEmitted(t, data, "thread_name", []string{"GC", "Network", "Timers", "Syscalls", "Proc 0"}) + checkProcStartStop(t, data) + checkSyscalls(t, data) + checkNetworkUnblock(t, data) + // TODO(mknyszek): Check for flow events. + }) + } +} + +func checkSyscalls(t *testing.T, data format.Data) { + data = filterViewerTrace(data, + filterEventName("syscall"), + filterStackRootFunc("main.blockingSyscall")) + if len(data.Events) <= 1 { + t.Errorf("got %d events, want > 1", len(data.Events)) + } + data = filterViewerTrace(data, filterBlocked("yes")) + if len(data.Events) != 1 { + t.Errorf("got %d events, want 1", len(data.Events)) + } +} + +type eventFilterFn func(*format.Event, *format.Data) bool + +func filterEventName(name string) eventFilterFn { + return func(e *format.Event, _ *format.Data) bool { + return e.Name == name + } +} + +// filterGoRoutineName returns an event filter that returns true if the event's +// goroutine name is equal to name. +func filterGoRoutineName(name string) eventFilterFn { + return func(e *format.Event, _ *format.Data) bool { + return parseGoroutineName(e) == name + } +} + +// parseGoroutineName returns the goroutine name from the event's name field. +// E.g. if e.Name is "G42 main.cpu10", this returns "main.cpu10". +func parseGoroutineName(e *format.Event) string { + parts := strings.SplitN(e.Name, " ", 2) + if len(parts) != 2 || !strings.HasPrefix(parts[0], "G") { + return "" + } + return parts[1] +} + +// filterBlocked returns an event filter that returns true if the event's +// "blocked" argument is equal to blocked. +func filterBlocked(blocked string) eventFilterFn { + return func(e *format.Event, _ *format.Data) bool { + m, ok := e.Arg.(map[string]any) + if !ok { + return false + } + return m["blocked"] == blocked + } +} + +// filterStackRootFunc returns an event filter that returns true if the function +// at the root of the stack trace is named name. +func filterStackRootFunc(name string) eventFilterFn { + return func(e *format.Event, data *format.Data) bool { + frames := stackFrames(data, e.Stack) + rootFrame := frames[len(frames)-1] + return strings.HasPrefix(rootFrame, name+":") + } +} + +// filterViewerTrace returns a copy of data with only the events that pass all +// of the given filters. +func filterViewerTrace(data format.Data, fns ...eventFilterFn) (filtered format.Data) { + filtered = data + filtered.Events = nil + for _, e := range data.Events { + keep := true + for _, fn := range fns { + keep = keep && fn(e, &filtered) + } + if keep { + filtered.Events = append(filtered.Events, e) + } + } + return +} + +func stackFrames(data *format.Data, stackID int) (frames []string) { + for { + frame, ok := data.Frames[strconv.Itoa(stackID)] + if !ok { + return + } + frames = append(frames, frame.Name) + stackID = frame.Parent + } +} + +func checkProcStartStop(t *testing.T, data format.Data) { + procStarted := map[uint64]bool{} + for _, e := range data.Events { + if e.Name == "proc start" { + if procStarted[e.TID] == true { + t.Errorf("proc started twice: %d", e.TID) + } + procStarted[e.TID] = true + } + if e.Name == "proc stop" { + if procStarted[e.TID] == false { + t.Errorf("proc stopped twice: %d", e.TID) + } + procStarted[e.TID] = false + } + } + if got, want := len(procStarted), 8; got != want { + t.Errorf("wrong number of procs started/stopped got=%d want=%d", got, want) + } +} + +func checkNetworkUnblock(t *testing.T, data format.Data) { + count := 0 + var netBlockEv *format.Event + for _, e := range data.Events { + if e.TID == tracev1.NetpollP && e.Name == "unblock (network)" && e.Phase == "I" && e.Scope == "t" { + count++ + netBlockEv = e + } + } + if netBlockEv == nil { + t.Error("failed to find a network unblock") + } + if count == 0 { + t.Errorf("found zero network block events, want at least one") + } + // TODO(mknyszek): Check for the flow of this event to some slice event of a goroutine running. +} + +func checkExecutionTimes(t *testing.T, data format.Data) { + cpu10 := sumExecutionTime(filterViewerTrace(data, filterGoRoutineName("main.cpu10"))) + cpu20 := sumExecutionTime(filterViewerTrace(data, filterGoRoutineName("main.cpu20"))) + if cpu10 <= 0 || cpu20 <= 0 || cpu10 >= cpu20 { + t.Errorf("bad execution times: cpu10=%v, cpu20=%v", cpu10, cpu20) + } +} + +func checkMetaNamesEmitted(t *testing.T, data format.Data, category string, want []string) { + t.Helper() + names := metaEventNameArgs(category, data) + for _, wantName := range want { + if !slices.Contains(names, wantName) { + t.Errorf("%s: names=%v, want %q", category, names, wantName) + } + } +} + +func metaEventNameArgs(category string, data format.Data) (names []string) { + for _, e := range data.Events { + if e.Name == category && e.Phase == "M" { + names = append(names, e.Arg.(map[string]any)["name"].(string)) + } + } + return +} + +func checkPlausibleHeapMetrics(t *testing.T, data format.Data) { + hms := heapMetrics(data) + var nonZeroAllocated, nonZeroNextGC bool + for _, hm := range hms { + if hm.Allocated > 0 { + nonZeroAllocated = true + } + if hm.NextGC > 0 { + nonZeroNextGC = true + } + } + + if !nonZeroAllocated { + t.Errorf("nonZeroAllocated=%v, want true", nonZeroAllocated) + } + if !nonZeroNextGC { + t.Errorf("nonZeroNextGC=%v, want true", nonZeroNextGC) + } +} + +func heapMetrics(data format.Data) (metrics []format.HeapCountersArg) { + for _, e := range data.Events { + if e.Phase == "C" && e.Name == "Heap" { + j, _ := json.Marshal(e.Arg) + var metric format.HeapCountersArg + json.Unmarshal(j, &metric) + metrics = append(metrics, metric) + } + } + return +} + +func recordJSONTraceHandlerResponse(t *testing.T, parsed *parsedTrace) format.Data { + h := JSONTraceHandler(parsed) + recorder := httptest.NewRecorder() + r := httptest.NewRequest("GET", "/jsontrace", nil) + h.ServeHTTP(recorder, r) + + var data format.Data + if err := json.Unmarshal(recorder.Body.Bytes(), &data); err != nil { + t.Fatal(err) + } + return data +} + +func sumExecutionTime(data format.Data) (sum time.Duration) { + for _, e := range data.Events { + sum += time.Duration(e.Dur) * time.Microsecond + } + return +} + +func getTestTrace(t *testing.T, testPath string) *parsedTrace { + t.Helper() + + // First read in the text trace and write it out as bytes. + f, err := os.Open(testPath) + if err != nil { + t.Fatalf("failed to open test %s: %v", testPath, err) + } + r, err := raw.NewTextReader(f) + if err != nil { + t.Fatalf("failed to read test %s: %v", testPath, err) + } + var trace bytes.Buffer + w, err := raw.NewWriter(&trace, r.Version()) + if err != nil { + t.Fatalf("failed to write out test %s: %v", testPath, err) + } + for { + ev, err := r.ReadEvent() + if err == io.EOF { + break + } + if err != nil { + t.Fatalf("failed to read test %s: %v", testPath, err) + } + if err := w.WriteEvent(ev); err != nil { + t.Fatalf("failed to write out test %s: %v", testPath, err) + } + } + + // Parse the test trace. + parsed, err := parseTrace(&trace, int64(trace.Len())) + if err != nil { + t.Fatalf("failed to parse trace: %v", err) + } + return parsed +} diff --git a/src/cmd/trace/main.go b/src/cmd/trace/main.go index 2c0b15623d..44a6d3c74f 100644 --- a/src/cmd/trace/main.go +++ b/src/cmd/trace/main.go @@ -5,23 +5,22 @@ package main import ( - "bufio" "cmd/internal/browser" "cmd/internal/telemetry" - cmdv2 "cmd/trace/v2" "flag" "fmt" "internal/trace" "internal/trace/traceviewer" + tracev2 "internal/trace/v2" + "internal/trace/v2/raw" + "io" "log" "net" "net/http" - "os" - "runtime" - "runtime/debug" - "sync" - _ "net/http/pprof" // Required to use pprof + "os" + "sync/atomic" + "time" ) const usageMessage = "" + @@ -87,166 +86,308 @@ func main() { flag.Usage() } - if isTraceV2(traceFile) { - if err := cmdv2.Main(traceFile, *httpFlag, *pprofFlag, *debugFlag); err != nil { - dief("%s\n", err) + tracef, err := os.Open(traceFile) + if err != nil { + logAndDie(fmt.Errorf("failed to read trace file: %w", err)) + } + defer tracef.Close() + + // Get the size of the trace file. + fi, err := tracef.Stat() + if err != nil { + logAndDie(fmt.Errorf("failed to stat trace file: %v", err)) + } + traceSize := fi.Size() + + // Handle requests for profiles. + if *pprofFlag != "" { + parsed, err := parseTrace(tracef, traceSize) + if err != nil { + logAndDie(err) } - return - } - - var pprofFunc traceviewer.ProfileFunc - switch *pprofFlag { - case "net": - pprofFunc = pprofByGoroutine(computePprofIO) - case "sync": - pprofFunc = pprofByGoroutine(computePprofBlock) - case "syscall": - pprofFunc = pprofByGoroutine(computePprofSyscall) - case "sched": - pprofFunc = pprofByGoroutine(computePprofSched) - } - if pprofFunc != nil { - records, err := pprofFunc(&http.Request{}) + var f traceviewer.ProfileFunc + switch *pprofFlag { + case "net": + f = pprofByGoroutine(computePprofIO(), parsed) + case "sync": + f = pprofByGoroutine(computePprofBlock(), parsed) + case "syscall": + f = pprofByGoroutine(computePprofSyscall(), parsed) + case "sched": + f = pprofByGoroutine(computePprofSched(), parsed) + default: + logAndDie(fmt.Errorf("unknown pprof type %s\n", *pprofFlag)) + } + records, err := f(&http.Request{}) if err != nil { - dief("failed to generate pprof: %v\n", err) + logAndDie(fmt.Errorf("failed to generate pprof: %v\n", err)) } if err := traceviewer.BuildProfile(records).Write(os.Stdout); err != nil { - dief("failed to generate pprof: %v\n", err) + logAndDie(fmt.Errorf("failed to generate pprof: %v\n", err)) } - os.Exit(0) + logAndDie(nil) } - if *pprofFlag != "" { - dief("unknown pprof type %s\n", *pprofFlag) + + // Debug flags. + switch *debugFlag { + case 1: + logAndDie(debugProcessedEvents(tracef)) + case 2: + logAndDie(debugRawEvents(tracef)) } ln, err := net.Listen("tcp", *httpFlag) if err != nil { - dief("failed to create server socket: %v\n", err) + logAndDie(fmt.Errorf("failed to create server socket: %w", err)) } + addr := "http://" + ln.Addr().String() - log.Print("Parsing trace...") - res, err := parseTrace() + log.Print("Preparing trace for viewer...") + parsed, err := parseTraceInteractive(tracef, traceSize) if err != nil { - dief("%v\n", err) + logAndDie(err) } + // N.B. tracef not needed after this point. + // We might double-close, but that's fine; we ignore the error. + tracef.Close() - if *debugFlag != 0 { - trace.Print(res.Events) - os.Exit(0) + // Print a nice message for a partial trace. + if parsed.err != nil { + log.Printf("Encountered error, but able to proceed. Error: %v", parsed.err) + + lost := parsed.size - parsed.valid + pct := float64(lost) / float64(parsed.size) * 100 + log.Printf("Lost %.2f%% of the latest trace data due to error (%s of %s)", pct, byteCount(lost), byteCount(parsed.size)) } - reportMemoryUsage("after parsing trace") - debug.FreeOSMemory() - log.Print("Splitting trace...") - ranges = splitTrace(res) - reportMemoryUsage("after splitting trace") - debug.FreeOSMemory() + log.Print("Splitting trace for viewer...") + ranges, err := splitTrace(parsed) + if err != nil { + logAndDie(err) + } - addr := "http://" + ln.Addr().String() log.Printf("Opening browser. Trace viewer is listening on %s", addr) browser.Open(addr) - // Install MMU handler. - http.HandleFunc("/mmu", traceviewer.MMUHandlerFunc(ranges, mutatorUtil)) + mutatorUtil := func(flags trace.UtilFlags) ([][]trace.MutatorUtil, error) { + return trace.MutatorUtilizationV2(parsed.events, flags), nil + } + + mux := http.NewServeMux() - // Install main handler. - http.Handle("/", traceviewer.MainHandler([]traceviewer.View{ + // Main endpoint. + mux.Handle("/", traceviewer.MainHandler([]traceviewer.View{ {Type: traceviewer.ViewProc, Ranges: ranges}, + // N.B. Use the same ranges for threads. It takes a long time to compute + // the split a second time, but the makeup of the events are similar enough + // that this is still a good split. + {Type: traceviewer.ViewThread, Ranges: ranges}, })) - // Start http server. - err = http.Serve(ln, nil) - dief("failed to start http server: %v\n", err) + // Catapult handlers. + mux.Handle("/trace", traceviewer.TraceHandler()) + mux.Handle("/jsontrace", JSONTraceHandler(parsed)) + mux.Handle("/static/", traceviewer.StaticHandler()) + + // Goroutines handlers. + mux.HandleFunc("/goroutines", GoroutinesHandlerFunc(parsed.summary.Goroutines)) + mux.HandleFunc("/goroutine", GoroutineHandler(parsed.summary.Goroutines)) + + // MMU handler. + mux.HandleFunc("/mmu", traceviewer.MMUHandlerFunc(ranges, mutatorUtil)) + + // Basic pprof endpoints. + mux.HandleFunc("/io", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofIO(), parsed))) + mux.HandleFunc("/block", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofBlock(), parsed))) + mux.HandleFunc("/syscall", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofSyscall(), parsed))) + mux.HandleFunc("/sched", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofSched(), parsed))) + + // Region-based pprof endpoints. + mux.HandleFunc("/regionio", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofIO(), parsed))) + mux.HandleFunc("/regionblock", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofBlock(), parsed))) + mux.HandleFunc("/regionsyscall", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofSyscall(), parsed))) + mux.HandleFunc("/regionsched", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofSched(), parsed))) + + // Region endpoints. + mux.HandleFunc("/userregions", UserRegionsHandlerFunc(parsed)) + mux.HandleFunc("/userregion", UserRegionHandlerFunc(parsed)) + + // Task endpoints. + mux.HandleFunc("/usertasks", UserTasksHandlerFunc(parsed)) + mux.HandleFunc("/usertask", UserTaskHandlerFunc(parsed)) + + err = http.Serve(ln, mux) + logAndDie(fmt.Errorf("failed to start http server: %w", err)) } -// isTraceV2 returns true if filename holds a v2 trace. -func isTraceV2(filename string) bool { - file, err := os.Open(filename) - if err != nil { - return false +func logAndDie(err error) { + if err == nil { + os.Exit(0) } - defer file.Close() + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) +} - ver, _, err := trace.ReadVersion(file) - if err != nil { - return false +func parseTraceInteractive(tr io.Reader, size int64) (parsed *parsedTrace, err error) { + done := make(chan struct{}) + cr := countingReader{r: tr} + go func() { + parsed, err = parseTrace(&cr, size) + done <- struct{}{} + }() + ticker := time.NewTicker(5 * time.Second) +progressLoop: + for { + select { + case <-ticker.C: + case <-done: + ticker.Stop() + break progressLoop + } + progress := cr.bytesRead.Load() + pct := float64(progress) / float64(size) * 100 + log.Printf("%s of %s (%.1f%%) processed...", byteCount(progress), byteCount(size), pct) } - return ver >= 1022 + return } -var ranges []traceviewer.Range - -var loader struct { - once sync.Once - res trace.ParseResult - err error +type parsedTrace struct { + events []tracev2.Event + summary *trace.Summary + size, valid int64 + 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() +func parseTrace(rr io.Reader, size int64) (*parsedTrace, error) { + // Set up the reader. + cr := countingReader{r: rr} + r, err := tracev2.NewReader(&cr) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to create trace reader: %w", err) } - return res.Events, err -} -func parseTrace() (trace.ParseResult, error) { - loader.once.Do(func() { - tracef, err := os.Open(traceFile) + // Set up state. + s := trace.NewSummarizer() + t := new(parsedTrace) + var validBytes int64 + var validEvents int + for { + ev, err := r.ReadEvent() + if err == io.EOF { + validBytes = cr.bytesRead.Load() + validEvents = len(t.events) + break + } if err != nil { - loader.err = fmt.Errorf("failed to open trace file: %v", err) - return + t.err = err + break } - defer tracef.Close() + t.events = append(t.events, ev) + s.Event(&t.events[len(t.events)-1]) - // Parse and symbolize. - res, err := trace.Parse(bufio.NewReader(tracef), programBinary) - if err != nil { - loader.err = fmt.Errorf("failed to parse trace: %v", err) - return + if ev.Kind() == tracev2.EventSync { + validBytes = cr.bytesRead.Load() + validEvents = len(t.events) } - loader.res = res - }) - return loader.res, loader.err + } + + // Check to make sure we got at least one good generation. + if validEvents == 0 { + return nil, fmt.Errorf("failed to parse any useful part of the trace: %v", t.err) + } + + // Finish off the parsedTrace. + t.summary = s.Finalize() + t.valid = validBytes + t.size = size + t.events = t.events[:validEvents] + return t, nil } -func dief(msg string, args ...any) { - fmt.Fprintf(os.Stderr, msg, args...) - os.Exit(1) +func (t *parsedTrace) startTime() tracev2.Time { + return t.events[0].Time() } -var debugMemoryUsage bool +func (t *parsedTrace) endTime() tracev2.Time { + return t.events[len(t.events)-1].Time() +} -func init() { - v := os.Getenv("DEBUG_MEMORY_USAGE") - debugMemoryUsage = v != "" +// splitTrace splits the trace into a number of ranges, each resulting in approx 100 MiB of +// json output (the trace viewer can hardly handle more). +func splitTrace(parsed *parsedTrace) ([]traceviewer.Range, error) { + // TODO(mknyszek): Split traces by generation by doing a quick first pass over the + // trace to identify all the generation boundaries. + s, c := traceviewer.SplittingTraceConsumer(100 << 20) // 100 MiB + if err := generateTrace(parsed, defaultGenOpts(), c); err != nil { + return nil, err + } + return s.Ranges, nil } -func reportMemoryUsage(msg string) { - if !debugMemoryUsage { - return - } - var s runtime.MemStats - runtime.ReadMemStats(&s) - w := os.Stderr - fmt.Fprintf(w, "%s\n", msg) - fmt.Fprintf(w, " Alloc:\t%d Bytes\n", s.Alloc) - fmt.Fprintf(w, " Sys:\t%d Bytes\n", s.Sys) - fmt.Fprintf(w, " HeapReleased:\t%d Bytes\n", s.HeapReleased) - fmt.Fprintf(w, " HeapSys:\t%d Bytes\n", s.HeapSys) - fmt.Fprintf(w, " HeapInUse:\t%d Bytes\n", s.HeapInuse) - fmt.Fprintf(w, " HeapAlloc:\t%d Bytes\n", s.HeapAlloc) - var dummy string - fmt.Printf("Enter to continue...") - fmt.Scanf("%s", &dummy) +func debugProcessedEvents(trace io.Reader) error { + tr, err := tracev2.NewReader(trace) + if err != nil { + return err + } + for { + ev, err := tr.ReadEvent() + if err == io.EOF { + return nil + } else if err != nil { + return err + } + fmt.Println(ev.String()) + } } -func mutatorUtil(flags trace.UtilFlags) ([][]trace.MutatorUtil, error) { - events, err := parseEvents() +func debugRawEvents(trace io.Reader) error { + rr, err := raw.NewReader(trace) if err != nil { - return nil, err + return err + } + for { + ev, err := rr.ReadEvent() + if err == io.EOF { + return nil + } else if err != nil { + return err + } + fmt.Println(ev.String()) + } +} + +type countingReader struct { + r io.Reader + bytesRead atomic.Int64 +} + +func (c *countingReader) Read(buf []byte) (n int, err error) { + n, err = c.r.Read(buf) + c.bytesRead.Add(int64(n)) + return n, err +} + +type byteCount int64 + +func (b byteCount) String() string { + var suffix string + var divisor int64 + switch { + case b < 1<<10: + suffix = "B" + divisor = 1 + case b < 1<<20: + suffix = "KiB" + divisor = 1 << 10 + case b < 1<<30: + suffix = "MiB" + divisor = 1 << 20 + case b < 1<<40: + suffix = "GiB" + divisor = 1 << 30 + } + if divisor == 1 { + return fmt.Sprintf("%d %s", b, suffix) } - return trace.MutatorUtilization(events, flags), nil + return fmt.Sprintf("%.1f %s", float64(b)/float64(divisor), suffix) } diff --git a/src/cmd/trace/pprof.go b/src/cmd/trace/pprof.go index 3722b37ab8..e921b38fca 100644 --- a/src/cmd/trace/pprof.go +++ b/src/cmd/trace/pprof.go @@ -7,257 +7,330 @@ package main import ( + "cmp" "fmt" "internal/trace" "internal/trace/traceviewer" + tracev2 "internal/trace/v2" "net/http" - "sort" - "strconv" + "slices" + "strings" "time" ) -func init() { - http.HandleFunc("/io", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofIO))) - http.HandleFunc("/block", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofBlock))) - http.HandleFunc("/syscall", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofSyscall))) - http.HandleFunc("/sched", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofSched))) - - http.HandleFunc("/regionio", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofIO))) - http.HandleFunc("/regionblock", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofBlock))) - http.HandleFunc("/regionsyscall", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofSyscall))) - http.HandleFunc("/regionsched", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofSched))) -} - -// interval represents a time interval in the trace. -type interval struct { - begin, end int64 // nanoseconds. -} - -func pprofByGoroutine(compute computePprofFunc) traceviewer.ProfileFunc { +func pprofByGoroutine(compute computePprofFunc, t *parsedTrace) traceviewer.ProfileFunc { return func(r *http.Request) ([]traceviewer.ProfileRecord, error) { - id := r.FormValue("id") - events, err := parseEvents() - if err != nil { - return nil, err - } - gToIntervals, err := pprofMatchingGoroutines(id, events) + name := r.FormValue("name") + gToIntervals, err := pprofMatchingGoroutines(name, t) if err != nil { return nil, err } - return compute(gToIntervals, events) + return compute(gToIntervals, t.events) } } -func pprofByRegion(compute computePprofFunc) traceviewer.ProfileFunc { +func pprofByRegion(compute computePprofFunc, t *parsedTrace) traceviewer.ProfileFunc { return func(r *http.Request) ([]traceviewer.ProfileRecord, error) { filter, err := newRegionFilter(r) if err != nil { return nil, err } - gToIntervals, err := pprofMatchingRegions(filter) + gToIntervals, err := pprofMatchingRegions(filter, t) if err != nil { return nil, err } - events, _ := parseEvents() - - return compute(gToIntervals, events) + return compute(gToIntervals, t.events) } } -// pprofMatchingGoroutines parses the goroutine type id string (i.e. pc) -// and returns the ids of goroutines of the matching type and its interval. +// pprofMatchingGoroutines returns the ids of goroutines of the matching name and its interval. // If the id string is empty, returns nil without an error. -func pprofMatchingGoroutines(id string, events []*trace.Event) (map[uint64][]interval, error) { - if id == "" { - return nil, nil - } - pc, err := strconv.ParseUint(id, 10, 64) // id is string - if err != nil { - return nil, fmt.Errorf("invalid goroutine type: %v", id) - } - analyzeGoroutines(events) - var res map[uint64][]interval - for _, g := range gs { - if g.PC != pc { +func pprofMatchingGoroutines(name string, t *parsedTrace) (map[tracev2.GoID][]interval, error) { + res := make(map[tracev2.GoID][]interval) + for _, g := range t.summary.Goroutines { + if name != "" && g.Name != name { continue } - if res == nil { - res = make(map[uint64][]interval) - } endTime := g.EndTime if g.EndTime == 0 { - endTime = lastTimestamp() // the trace doesn't include the goroutine end event. Use the trace end time. + endTime = t.endTime() // Use the trace end time, since the goroutine is still live then. } - res[g.ID] = []interval{{begin: g.StartTime, end: endTime}} + res[g.ID] = []interval{{start: g.StartTime, end: endTime}} } - if len(res) == 0 && id != "" { - return nil, fmt.Errorf("failed to find matching goroutines for id: %s", id) + if len(res) == 0 { + return nil, fmt.Errorf("failed to find matching goroutines for name: %s", name) } return res, nil } // pprofMatchingRegions returns the time intervals of matching regions // grouped by the goroutine id. If the filter is nil, returns nil without an error. -func pprofMatchingRegions(filter *regionFilter) (map[uint64][]interval, error) { - res, err := analyzeAnnotations() - if err != nil { - return nil, err - } +func pprofMatchingRegions(filter *regionFilter, t *parsedTrace) (map[tracev2.GoID][]interval, error) { if filter == nil { return nil, nil } - gToIntervals := make(map[uint64][]interval) - for id, regions := range res.regions { - for _, s := range regions { - if filter.match(id, s) { - gToIntervals[s.G] = append(gToIntervals[s.G], interval{begin: s.firstTimestamp(), end: s.lastTimestamp()}) + gToIntervals := make(map[tracev2.GoID][]interval) + for _, g := range t.summary.Goroutines { + for _, r := range g.Regions { + if !filter.match(t, r) { + continue } + gToIntervals[g.ID] = append(gToIntervals[g.ID], regionInterval(t, r)) } } for g, intervals := range gToIntervals { - // in order to remove nested regions and + // In order to remove nested regions and // consider only the outermost regions, // first, we sort based on the start time // and then scan through to select only the outermost regions. - sort.Slice(intervals, func(i, j int) bool { - x := intervals[i].begin - y := intervals[j].begin - if x == y { - return intervals[i].end < intervals[j].end + slices.SortFunc(intervals, func(a, b interval) int { + if c := cmp.Compare(a.start, b.start); c != 0 { + return c } - return x < y + return cmp.Compare(a.end, b.end) }) - var lastTimestamp int64 + var lastTimestamp tracev2.Time var n int - // select only the outermost regions. + // Select only the outermost regions. for _, i := range intervals { - if lastTimestamp <= i.begin { + if lastTimestamp <= i.start { intervals[n] = i // new non-overlapping region starts. lastTimestamp = i.end n++ - } // otherwise, skip because this region overlaps with a previous region. + } + // Otherwise, skip because this region overlaps with a previous region. } gToIntervals[g] = intervals[:n] } return gToIntervals, nil } -type computePprofFunc func(gToIntervals map[uint64][]interval, events []*trace.Event) ([]traceviewer.ProfileRecord, error) +type computePprofFunc func(gToIntervals map[tracev2.GoID][]interval, events []tracev2.Event) ([]traceviewer.ProfileRecord, error) -// computePprofIO generates IO pprof-like profile (time spent in IO wait, currently only network blocking event). -func computePprofIO(gToIntervals map[uint64][]interval, events []*trace.Event) ([]traceviewer.ProfileRecord, error) { - prof := make(map[uint64]traceviewer.ProfileRecord) - for _, ev := range events { - if ev.Type != trace.EvGoBlockNet || ev.Link == nil || ev.StkID == 0 || len(ev.Stk) == 0 { - continue - } - overlapping := pprofOverlappingDuration(gToIntervals, ev) - if overlapping > 0 { - rec := prof[ev.StkID] - rec.Stack = ev.Stk - rec.Count++ - rec.Time += overlapping - prof[ev.StkID] = rec - } - } - return recordsOf(prof), nil +// computePprofIO returns a computePprofFunc that generates IO pprof-like profile (time spent in +// IO wait, currently only network blocking event). +func computePprofIO() computePprofFunc { + return makeComputePprofFunc(tracev2.GoWaiting, func(reason string) bool { + return reason == "network" + }) } -// computePprofBlock generates blocking pprof-like profile (time spent blocked on synchronization primitives). -func computePprofBlock(gToIntervals map[uint64][]interval, events []*trace.Event) ([]traceviewer.ProfileRecord, error) { - prof := make(map[uint64]traceviewer.ProfileRecord) - for _, ev := range events { - switch ev.Type { - case trace.EvGoBlockSend, trace.EvGoBlockRecv, trace.EvGoBlockSelect, - trace.EvGoBlockSync, trace.EvGoBlockCond, trace.EvGoBlockGC: - // TODO(hyangah): figure out why EvGoBlockGC should be here. - // EvGoBlockGC indicates the goroutine blocks on GC assist, not - // on synchronization primitives. - default: - continue - } - if ev.Link == nil || ev.StkID == 0 || len(ev.Stk) == 0 { - continue - } - overlapping := pprofOverlappingDuration(gToIntervals, ev) - if overlapping > 0 { - rec := prof[ev.StkID] - rec.Stack = ev.Stk - rec.Count++ - rec.Time += overlapping - prof[ev.StkID] = rec - } - } - return recordsOf(prof), nil +// computePprofBlock returns a computePprofFunc that generates blocking pprof-like profile +// (time spent blocked on synchronization primitives). +func computePprofBlock() computePprofFunc { + return makeComputePprofFunc(tracev2.GoWaiting, func(reason string) bool { + return strings.Contains(reason, "chan") || strings.Contains(reason, "sync") || strings.Contains(reason, "select") + }) } -// computePprofSyscall generates syscall pprof-like profile (time spent blocked in syscalls). -func computePprofSyscall(gToIntervals map[uint64][]interval, events []*trace.Event) ([]traceviewer.ProfileRecord, error) { - prof := make(map[uint64]traceviewer.ProfileRecord) - for _, ev := range events { - if ev.Type != trace.EvGoSysCall || ev.Link == nil || ev.StkID == 0 || len(ev.Stk) == 0 { - continue - } - overlapping := pprofOverlappingDuration(gToIntervals, ev) - if overlapping > 0 { - rec := prof[ev.StkID] - rec.Stack = ev.Stk - rec.Count++ - rec.Time += overlapping - prof[ev.StkID] = rec - } - } - return recordsOf(prof), nil +// computePprofSyscall returns a computePprofFunc that generates a syscall pprof-like +// profile (time spent in syscalls). +func computePprofSyscall() computePprofFunc { + return makeComputePprofFunc(tracev2.GoSyscall, func(_ string) bool { + return true + }) } -// computePprofSched generates scheduler latency pprof-like profile +// computePprofSched returns a computePprofFunc that generates a scheduler latency pprof-like profile // (time between a goroutine become runnable and actually scheduled for execution). -func computePprofSched(gToIntervals map[uint64][]interval, events []*trace.Event) ([]traceviewer.ProfileRecord, error) { - prof := make(map[uint64]traceviewer.ProfileRecord) - for _, ev := range events { - if (ev.Type != trace.EvGoUnblock && ev.Type != trace.EvGoCreate) || - ev.Link == nil || ev.StkID == 0 || len(ev.Stk) == 0 { - continue - } - overlapping := pprofOverlappingDuration(gToIntervals, ev) - if overlapping > 0 { - rec := prof[ev.StkID] - rec.Stack = ev.Stk - rec.Count++ - rec.Time += overlapping - prof[ev.StkID] = rec +func computePprofSched() computePprofFunc { + return makeComputePprofFunc(tracev2.GoRunnable, func(_ string) bool { + return true + }) +} + +// makeComputePprofFunc returns a computePprofFunc that generates a profile of time goroutines spend +// in a particular state for the specified reasons. +func makeComputePprofFunc(state tracev2.GoState, trackReason func(string) bool) computePprofFunc { + return func(gToIntervals map[tracev2.GoID][]interval, events []tracev2.Event) ([]traceviewer.ProfileRecord, error) { + stacks := newStackMap() + tracking := make(map[tracev2.GoID]*tracev2.Event) + for i := range events { + ev := &events[i] + + // Filter out any non-state-transitions and events without stacks. + if ev.Kind() != tracev2.EventStateTransition { + continue + } + stack := ev.Stack() + if stack == tracev2.NoStack { + continue + } + + // The state transition has to apply to a goroutine. + st := ev.StateTransition() + if st.Resource.Kind != tracev2.ResourceGoroutine { + continue + } + id := st.Resource.Goroutine() + _, new := st.Goroutine() + + // Check if we're tracking this goroutine. + startEv := tracking[id] + if startEv == nil { + // We're not. Start tracking if the new state + // matches what we want and the transition is + // for one of the reasons we care about. + if new == state && trackReason(st.Reason) { + tracking[id] = ev + } + continue + } + // We're tracking this goroutine. + if new == state { + // We're tracking this goroutine, but it's just transitioning + // to the same state (this is a no-ip + continue + } + // The goroutine has transitioned out of the state we care about, + // so remove it from tracking and record the stack. + delete(tracking, id) + + overlapping := pprofOverlappingDuration(gToIntervals, id, interval{startEv.Time(), ev.Time()}) + if overlapping > 0 { + rec := stacks.getOrAdd(startEv.Stack()) + rec.Count++ + rec.Time += overlapping + } } + return stacks.profile(), nil } - return recordsOf(prof), nil } // pprofOverlappingDuration returns the overlapping duration between // the time intervals in gToIntervals and the specified event. // If gToIntervals is nil, this simply returns the event's duration. -func pprofOverlappingDuration(gToIntervals map[uint64][]interval, ev *trace.Event) time.Duration { +func pprofOverlappingDuration(gToIntervals map[tracev2.GoID][]interval, id tracev2.GoID, sample interval) time.Duration { if gToIntervals == nil { // No filtering. - return time.Duration(ev.Link.Ts-ev.Ts) * time.Nanosecond + return sample.duration() } - intervals := gToIntervals[ev.G] + intervals := gToIntervals[id] if len(intervals) == 0 { return 0 } var overlapping time.Duration for _, i := range intervals { - if o := overlappingDuration(i.begin, i.end, ev.Ts, ev.Link.Ts); o > 0 { + if o := i.overlap(sample); o > 0 { overlapping += o } } return overlapping } -func recordsOf(records map[uint64]traceviewer.ProfileRecord) []traceviewer.ProfileRecord { - result := make([]traceviewer.ProfileRecord, 0, len(records)) - for _, record := range records { - result = append(result, record) +// interval represents a time interval in the trace. +type interval struct { + start, end tracev2.Time +} + +func (i interval) duration() time.Duration { + return i.end.Sub(i.start) +} + +func (i1 interval) overlap(i2 interval) time.Duration { + // Assume start1 <= end1 and start2 <= end2 + if i1.end < i2.start || i2.end < i1.start { + return 0 + } + if i1.start < i2.start { // choose the later one + i1.start = i2.start + } + if i1.end > i2.end { // choose the earlier one + i1.end = i2.end + } + return i1.duration() +} + +// pprofMaxStack is the extent of the deduplication we're willing to do. +// +// Because slices aren't comparable and we want to leverage maps for deduplication, +// we have to choose a fixed constant upper bound on the amount of frames we want +// to support. In practice this is fine because there's a maximum depth to these +// stacks anyway. +const pprofMaxStack = 128 + +// stackMap is a map of tracev2.Stack to some value V. +type stackMap struct { + // stacks contains the full list of stacks in the set, however + // it is insufficient for deduplication because tracev2.Stack + // equality is only optimistic. If two tracev2.Stacks are equal, + // then they are guaranteed to be equal in content. If they are + // not equal, then they might still be equal in content. + stacks map[tracev2.Stack]*traceviewer.ProfileRecord + + // pcs is the source-of-truth for deduplication. It is a map of + // the actual PCs in the stack to a tracev2.Stack. + pcs map[[pprofMaxStack]uint64]tracev2.Stack +} + +func newStackMap() *stackMap { + return &stackMap{ + stacks: make(map[tracev2.Stack]*traceviewer.ProfileRecord), + pcs: make(map[[pprofMaxStack]uint64]tracev2.Stack), + } +} + +func (m *stackMap) getOrAdd(stack tracev2.Stack) *traceviewer.ProfileRecord { + // Fast path: check to see if this exact stack is already in the map. + if rec, ok := m.stacks[stack]; ok { + return rec } - return result + // Slow path: the stack may still be in the map. + + // Grab the stack's PCs as the source-of-truth. + var pcs [pprofMaxStack]uint64 + pcsForStack(stack, &pcs) + + // Check the source-of-truth. + var rec *traceviewer.ProfileRecord + if existing, ok := m.pcs[pcs]; ok { + // In the map. + rec = m.stacks[existing] + delete(m.stacks, existing) + } else { + // Not in the map. + rec = new(traceviewer.ProfileRecord) + } + // Insert regardless of whether we have a match in m.pcs. + // Even if we have a match, we want to keep the newest version + // of that stack, since we're much more likely tos see it again + // as we iterate through the trace linearly. Simultaneously, we + // are likely to never see the old stack again. + m.pcs[pcs] = stack + m.stacks[stack] = rec + return rec +} + +func (m *stackMap) profile() []traceviewer.ProfileRecord { + prof := make([]traceviewer.ProfileRecord, 0, len(m.stacks)) + for stack, record := range m.stacks { + rec := *record + i := 0 + stack.Frames(func(frame tracev2.StackFrame) bool { + rec.Stack = append(rec.Stack, &trace.Frame{ + PC: frame.PC, + Fn: frame.Func, + File: frame.File, + Line: int(frame.Line), + }) + i++ + // Cut this off at pprofMaxStack because that's as far + // as our deduplication goes. + return i < pprofMaxStack + }) + prof = append(prof, rec) + } + return prof +} + +// pcsForStack extracts the first pprofMaxStack PCs from stack into pcs. +func pcsForStack(stack tracev2.Stack, pcs *[pprofMaxStack]uint64) { + i := 0 + stack.Frames(func(frame tracev2.StackFrame) bool { + pcs[i] = frame.PC + i++ + return i < len(pcs) + }) } diff --git a/src/cmd/trace/procgen.go b/src/cmd/trace/procgen.go new file mode 100644 index 0000000000..7dd724bb78 --- /dev/null +++ b/src/cmd/trace/procgen.go @@ -0,0 +1,212 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "internal/trace/traceviewer" + "internal/trace/traceviewer/format" + tracev2 "internal/trace/v2" +) + +var _ generator = &procGenerator{} + +type procGenerator struct { + globalRangeGenerator + globalMetricGenerator + procRangeGenerator + stackSampleGenerator[tracev2.ProcID] + logEventGenerator[tracev2.ProcID] + + gStates map[tracev2.GoID]*gState[tracev2.ProcID] + inSyscall map[tracev2.ProcID]*gState[tracev2.ProcID] + maxProc tracev2.ProcID +} + +func newProcGenerator() *procGenerator { + pg := new(procGenerator) + rg := func(ev *tracev2.Event) tracev2.ProcID { + return ev.Proc() + } + pg.stackSampleGenerator.getResource = rg + pg.logEventGenerator.getResource = rg + pg.gStates = make(map[tracev2.GoID]*gState[tracev2.ProcID]) + pg.inSyscall = make(map[tracev2.ProcID]*gState[tracev2.ProcID]) + return pg +} + +func (g *procGenerator) Sync() { + g.globalRangeGenerator.Sync() + g.procRangeGenerator.Sync() +} + +func (g *procGenerator) GoroutineLabel(ctx *traceContext, ev *tracev2.Event) { + l := ev.Label() + g.gStates[l.Resource.Goroutine()].setLabel(l.Label) +} + +func (g *procGenerator) GoroutineRange(ctx *traceContext, ev *tracev2.Event) { + r := ev.Range() + switch ev.Kind() { + case tracev2.EventRangeBegin: + g.gStates[r.Scope.Goroutine()].rangeBegin(ev.Time(), r.Name, ev.Stack()) + case tracev2.EventRangeActive: + g.gStates[r.Scope.Goroutine()].rangeActive(r.Name) + case tracev2.EventRangeEnd: + gs := g.gStates[r.Scope.Goroutine()] + gs.rangeEnd(ev.Time(), r.Name, ev.Stack(), ctx) + } +} + +func (g *procGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event) { + st := ev.StateTransition() + goID := st.Resource.Goroutine() + + // If we haven't seen this goroutine before, create a new + // gState for it. + gs, ok := g.gStates[goID] + if !ok { + gs = newGState[tracev2.ProcID](goID) + g.gStates[goID] = gs + } + // If we haven't already named this goroutine, try to name it. + gs.augmentName(st.Stack) + + // Handle the goroutine state transition. + from, to := st.Goroutine() + if from == to { + // Filter out no-op events. + return + } + if from == tracev2.GoRunning && !to.Executing() { + if to == tracev2.GoWaiting { + // Goroutine started blocking. + gs.block(ev.Time(), ev.Stack(), st.Reason, ctx) + } else { + gs.stop(ev.Time(), ev.Stack(), ctx) + } + } + if !from.Executing() && to == tracev2.GoRunning { + start := ev.Time() + if from == tracev2.GoUndetermined { + // Back-date the event to the start of the trace. + start = ctx.startTime + } + gs.start(start, ev.Proc(), ctx) + } + + if from == tracev2.GoWaiting { + // Goroutine was unblocked. + gs.unblock(ev.Time(), ev.Stack(), ev.Proc(), ctx) + } + if from == tracev2.GoNotExist && to == tracev2.GoRunnable { + // Goroutine was created. + gs.created(ev.Time(), ev.Proc(), ev.Stack()) + } + if from == tracev2.GoSyscall && to != tracev2.GoRunning { + // Goroutine exited a blocked syscall. + gs.blockedSyscallEnd(ev.Time(), ev.Stack(), ctx) + } + + // Handle syscalls. + if to == tracev2.GoSyscall && ev.Proc() != tracev2.NoProc { + start := ev.Time() + if from == tracev2.GoUndetermined { + // Back-date the event to the start of the trace. + start = ctx.startTime + } + // Write down that we've entered a syscall. Note: we might have no P here + // if we're in a cgo callback or this is a transition from GoUndetermined + // (i.e. the G has been blocked in a syscall). + gs.syscallBegin(start, ev.Proc(), ev.Stack()) + g.inSyscall[ev.Proc()] = gs + } + // Check if we're exiting a non-blocking syscall. + _, didNotBlock := g.inSyscall[ev.Proc()] + if from == tracev2.GoSyscall && didNotBlock { + gs.syscallEnd(ev.Time(), false, ctx) + delete(g.inSyscall, ev.Proc()) + } + + // Note down the goroutine transition. + _, inMarkAssist := gs.activeRanges["GC mark assist"] + ctx.GoroutineTransition(ctx.elapsed(ev.Time()), viewerGState(from, inMarkAssist), viewerGState(to, inMarkAssist)) +} + +func (g *procGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { + st := ev.StateTransition() + proc := st.Resource.Proc() + + g.maxProc = max(g.maxProc, proc) + viewerEv := traceviewer.InstantEvent{ + Resource: uint64(proc), + Stack: ctx.Stack(viewerFrames(ev.Stack())), + } + + from, to := st.Proc() + if from == to { + // Filter out no-op events. + return + } + if to.Executing() { + start := ev.Time() + if from == tracev2.ProcUndetermined { + start = ctx.startTime + } + viewerEv.Name = "proc start" + viewerEv.Arg = format.ThreadIDArg{ThreadID: uint64(ev.Thread())} + viewerEv.Ts = ctx.elapsed(start) + ctx.IncThreadStateCount(ctx.elapsed(start), traceviewer.ThreadStateRunning, 1) + } + if from.Executing() { + start := ev.Time() + viewerEv.Name = "proc stop" + viewerEv.Ts = ctx.elapsed(start) + ctx.IncThreadStateCount(ctx.elapsed(start), traceviewer.ThreadStateRunning, -1) + + // Check if this proc was in a syscall before it stopped. + // This means the syscall blocked. We need to emit it to the + // viewer at this point because we only display the time the + // syscall occupied a P when the viewer is in per-P mode. + // + // TODO(mknyszek): We could do better in a per-M mode because + // all events have to happen on *some* thread, and in v2 traces + // we know what that thread is. + gs, ok := g.inSyscall[proc] + if ok { + // Emit syscall slice for blocked syscall. + gs.syscallEnd(start, true, ctx) + gs.stop(start, ev.Stack(), ctx) + delete(g.inSyscall, proc) + } + } + // TODO(mknyszek): Consider modeling procs differently and have them be + // transition to and from NotExist when GOMAXPROCS changes. We can emit + // events for this to clearly delineate GOMAXPROCS changes. + + if viewerEv.Name != "" { + ctx.Instant(viewerEv) + } +} + +func (g *procGenerator) Finish(ctx *traceContext) { + ctx.SetResourceType("PROCS") + + // Finish off ranges first. It doesn't really matter for the global ranges, + // but the proc ranges need to either be a subset of a goroutine slice or + // their own slice entirely. If the former, it needs to end first. + g.procRangeGenerator.Finish(ctx) + g.globalRangeGenerator.Finish(ctx) + + // Finish off all the goroutine slices. + for _, gs := range g.gStates { + gs.finish(ctx) + } + + // Name all the procs to the emitter. + for i := uint64(0); i <= uint64(g.maxProc); i++ { + ctx.Resource(i, fmt.Sprintf("Proc %v", i)) + } +} diff --git a/src/cmd/trace/regions.go b/src/cmd/trace/regions.go new file mode 100644 index 0000000000..a85ed176f0 --- /dev/null +++ b/src/cmd/trace/regions.go @@ -0,0 +1,529 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "cmp" + "fmt" + "html/template" + "internal/trace" + "internal/trace/traceviewer" + tracev2 "internal/trace/v2" + "net/http" + "net/url" + "slices" + "sort" + "strconv" + "strings" + "time" +) + +// UserRegionsHandlerFunc returns a HandlerFunc that reports all regions found in the trace. +func UserRegionsHandlerFunc(t *parsedTrace) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Summarize all the regions. + summary := make(map[regionFingerprint]regionStats) + for _, g := range t.summary.Goroutines { + for _, r := range g.Regions { + id := fingerprintRegion(r) + stats, ok := summary[id] + if !ok { + stats.regionFingerprint = id + } + stats.add(t, r) + summary[id] = stats + } + } + // Sort regions by PC and name. + userRegions := make([]regionStats, 0, len(summary)) + for _, stats := range summary { + userRegions = append(userRegions, stats) + } + slices.SortFunc(userRegions, func(a, b regionStats) int { + if c := cmp.Compare(a.Type, b.Type); c != 0 { + return c + } + return cmp.Compare(a.Frame.PC, b.Frame.PC) + }) + // Emit table. + err := templUserRegionTypes.Execute(w, userRegions) + if err != nil { + http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) + return + } + } +} + +// regionFingerprint is a way to categorize regions that goes just one step beyond the region's Type +// by including the top stack frame. +type regionFingerprint struct { + Frame tracev2.StackFrame + Type string +} + +func fingerprintRegion(r *trace.UserRegionSummary) regionFingerprint { + return regionFingerprint{ + Frame: regionTopStackFrame(r), + Type: r.Name, + } +} + +func regionTopStackFrame(r *trace.UserRegionSummary) tracev2.StackFrame { + var frame tracev2.StackFrame + if r.Start != nil && r.Start.Stack() != tracev2.NoStack { + r.Start.Stack().Frames(func(f tracev2.StackFrame) bool { + frame = f + return false + }) + } + return frame +} + +type regionStats struct { + regionFingerprint + Histogram traceviewer.TimeHistogram +} + +func (s *regionStats) UserRegionURL() func(min, max time.Duration) string { + return func(min, max time.Duration) string { + return fmt.Sprintf("/userregion?type=%s&pc=%x&latmin=%v&latmax=%v", template.URLQueryEscaper(s.Type), s.Frame.PC, template.URLQueryEscaper(min), template.URLQueryEscaper(max)) + } +} + +func (s *regionStats) add(t *parsedTrace, region *trace.UserRegionSummary) { + s.Histogram.Add(regionInterval(t, region).duration()) +} + +var templUserRegionTypes = template.Must(template.New("").Parse(` + +Regions + + +

Regions

+ +Below is a table containing a summary of all the user-defined regions in the trace. +Regions are grouped by the region type and the point at which the region started. +The rightmost column of the table contains a latency histogram for each region group. +Note that this histogram only counts regions that began and ended within the traced +period. +However, the "Count" column includes all regions, including those that only started +or ended during the traced period. +Regions that were active through the trace period were not recorded, and so are not +accounted for at all. +Click on the links to explore a breakdown of time spent for each region by goroutine +and user-defined task. +
+
+ + + + + + + +{{range $}} + + + + + +{{end}} +
Region typeCountDuration distribution (complete tasks)
{{printf "%q" .Type}}
{{.Frame.Func}} @ {{printf "0x%x" .Frame.PC}}
{{.Frame.File}}:{{.Frame.Line}}
{{.Histogram.Count}}{{.Histogram.ToHTML (.UserRegionURL)}}
+ + +`)) + +// UserRegionHandlerFunc returns a HandlerFunc that presents the details of the selected regions. +func UserRegionHandlerFunc(t *parsedTrace) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // Construct the filter from the request. + filter, err := newRegionFilter(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + // Collect all the regions with their goroutines. + type region struct { + *trace.UserRegionSummary + Goroutine tracev2.GoID + NonOverlappingStats map[string]time.Duration + HasRangeTime bool + } + var regions []region + var maxTotal time.Duration + validNonOverlappingStats := make(map[string]struct{}) + validRangeStats := make(map[string]struct{}) + for _, g := range t.summary.Goroutines { + for _, r := range g.Regions { + if !filter.match(t, r) { + continue + } + nonOverlappingStats := r.NonOverlappingStats() + for name := range nonOverlappingStats { + validNonOverlappingStats[name] = struct{}{} + } + var totalRangeTime time.Duration + for name, dt := range r.RangeTime { + validRangeStats[name] = struct{}{} + totalRangeTime += dt + } + regions = append(regions, region{ + UserRegionSummary: r, + Goroutine: g.ID, + NonOverlappingStats: nonOverlappingStats, + HasRangeTime: totalRangeTime != 0, + }) + if maxTotal < r.TotalTime { + maxTotal = r.TotalTime + } + } + } + + // Sort. + sortBy := r.FormValue("sortby") + if _, ok := validNonOverlappingStats[sortBy]; ok { + slices.SortFunc(regions, func(a, b region) int { + return cmp.Compare(b.NonOverlappingStats[sortBy], a.NonOverlappingStats[sortBy]) + }) + } else { + // Sort by total time by default. + slices.SortFunc(regions, func(a, b region) int { + return cmp.Compare(b.TotalTime, a.TotalTime) + }) + } + + // Write down all the non-overlapping stats and sort them. + allNonOverlappingStats := make([]string, 0, len(validNonOverlappingStats)) + for name := range validNonOverlappingStats { + allNonOverlappingStats = append(allNonOverlappingStats, name) + } + slices.SortFunc(allNonOverlappingStats, func(a, b string) int { + if a == b { + return 0 + } + if a == "Execution time" { + return -1 + } + if b == "Execution time" { + return 1 + } + return cmp.Compare(a, b) + }) + + // Write down all the range stats and sort them. + allRangeStats := make([]string, 0, len(validRangeStats)) + for name := range validRangeStats { + allRangeStats = append(allRangeStats, name) + } + sort.Strings(allRangeStats) + + err = templUserRegionType.Execute(w, struct { + MaxTotal time.Duration + Regions []region + Name string + Filter *regionFilter + NonOverlappingStats []string + RangeStats []string + }{ + MaxTotal: maxTotal, + Regions: regions, + Name: filter.name, + Filter: filter, + NonOverlappingStats: allNonOverlappingStats, + RangeStats: allRangeStats, + }) + if err != nil { + http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) + return + } + } +} + +var templUserRegionType = template.Must(template.New("").Funcs(template.FuncMap{ + "headerStyle": func(statName string) template.HTMLAttr { + return template.HTMLAttr(fmt.Sprintf("style=\"background-color: %s;\"", stat2Color(statName))) + }, + "barStyle": func(statName string, dividend, divisor time.Duration) template.HTMLAttr { + width := "0" + if divisor != 0 { + width = fmt.Sprintf("%.2f%%", float64(dividend)/float64(divisor)*100) + } + return template.HTMLAttr(fmt.Sprintf("style=\"width: %s; background-color: %s;\"", width, stat2Color(statName))) + }, + "filterParams": func(f *regionFilter) template.URL { + return template.URL(f.params.Encode()) + }, +}).Parse(` + +Regions: {{.Name}} + + + + +

Regions: {{.Name}}

+ +Table of contents + + +

Summary

+ +{{ with $p := filterParams .Filter}} + + + + + + + + + + + + + + + + + +
Network wait profile: graph (download)
Sync block profile: graph (download)
Syscall profile: graph (download)
Scheduler wait profile: graph (download)
+{{ end }} + +

Breakdown

+ +The table below breaks down where each goroutine is spent its time during the +traced period. +All of the columns except total time are non-overlapping. +
+
+ + + + + + + +{{range $.NonOverlappingStats}} + +{{end}} + +{{range .Regions}} + + + + + + {{$Region := .}} + {{range $.NonOverlappingStats}} + {{$Time := index $Region.NonOverlappingStats .}} + + {{end}} + +{{end}} +
Goroutine Task Total {{.}}
{{.Goroutine}} {{if .TaskID}}{{.TaskID}}{{end}} {{ .TotalTime.String }} +
+ {{$Region := .}} + {{range $.NonOverlappingStats}} + {{$Time := index $Region.NonOverlappingStats .}} + {{if $Time}} +   + {{end}} + {{end}} +
+
{{$Time.String}}
+ +

Special ranges

+ +The table below describes how much of the traced period each goroutine spent in +certain special time ranges. +If a goroutine has spent no time in any special time ranges, it is excluded from +the table. +For example, how much time it spent helping the GC. Note that these times do +overlap with the times from the first table. +In general the goroutine may not be executing in these special time ranges. +For example, it may have blocked while trying to help the GC. +This must be taken into account when interpreting the data. +
+
+ + + + + + +{{range $.RangeStats}} + +{{end}} + +{{range .Regions}} + {{if .HasRangeTime}} + + + + + {{$Region := .}} + {{range $.RangeStats}} + {{$Time := index $Region.RangeTime .}} + + {{end}} + + {{end}} +{{end}} +
Goroutine Task Total {{.}}
{{.Goroutine}} {{if .TaskID}}{{.TaskID}}{{end}} {{ .TotalTime.String }} {{$Time.String}}
+`)) + +// regionFilter represents a region filter specified by a user of cmd/trace. +type regionFilter struct { + name string + params url.Values + cond []func(*parsedTrace, *trace.UserRegionSummary) bool +} + +// match returns true if a region, described by its ID and summary, matches +// the filter. +func (f *regionFilter) match(t *parsedTrace, s *trace.UserRegionSummary) bool { + for _, c := range f.cond { + if !c(t, s) { + return false + } + } + return true +} + +// newRegionFilter creates a new region filter from URL query variables. +func newRegionFilter(r *http.Request) (*regionFilter, error) { + if err := r.ParseForm(); err != nil { + return nil, err + } + + var name []string + var conditions []func(*parsedTrace, *trace.UserRegionSummary) bool + filterParams := make(url.Values) + + param := r.Form + if typ, ok := param["type"]; ok && len(typ) > 0 { + name = append(name, fmt.Sprintf("%q", typ[0])) + conditions = append(conditions, func(_ *parsedTrace, r *trace.UserRegionSummary) bool { + return r.Name == typ[0] + }) + filterParams.Add("type", typ[0]) + } + if pc, err := strconv.ParseUint(r.FormValue("pc"), 16, 64); err == nil { + encPC := fmt.Sprintf("0x%x", pc) + name = append(name, "@ "+encPC) + conditions = append(conditions, func(_ *parsedTrace, r *trace.UserRegionSummary) bool { + return regionTopStackFrame(r).PC == pc + }) + filterParams.Add("pc", encPC) + } + + if lat, err := time.ParseDuration(r.FormValue("latmin")); err == nil { + name = append(name, fmt.Sprintf("(latency >= %s)", lat)) + conditions = append(conditions, func(t *parsedTrace, r *trace.UserRegionSummary) bool { + return regionInterval(t, r).duration() >= lat + }) + filterParams.Add("latmin", lat.String()) + } + if lat, err := time.ParseDuration(r.FormValue("latmax")); err == nil { + name = append(name, fmt.Sprintf("(latency <= %s)", lat)) + conditions = append(conditions, func(t *parsedTrace, r *trace.UserRegionSummary) bool { + return regionInterval(t, r).duration() <= lat + }) + filterParams.Add("latmax", lat.String()) + } + + return ®ionFilter{ + name: strings.Join(name, " "), + cond: conditions, + params: filterParams, + }, nil +} + +func regionInterval(t *parsedTrace, s *trace.UserRegionSummary) interval { + var i interval + if s.Start != nil { + i.start = s.Start.Time() + } else { + i.start = t.startTime() + } + if s.End != nil { + i.end = s.End.Time() + } else { + i.end = t.endTime() + } + return i +} diff --git a/src/cmd/trace/tasks.go b/src/cmd/trace/tasks.go new file mode 100644 index 0000000000..8c7b6bad88 --- /dev/null +++ b/src/cmd/trace/tasks.go @@ -0,0 +1,477 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bytes" + "cmp" + "fmt" + "html/template" + "internal/trace" + "internal/trace/traceviewer" + tracev2 "internal/trace/v2" + "log" + "net/http" + "slices" + "strings" + "time" +) + +// UserTasksHandlerFunc returns a HandlerFunc that reports all tasks found in the trace. +func UserTasksHandlerFunc(t *parsedTrace) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + tasks := t.summary.Tasks + + // Summarize groups of tasks with the same name. + summary := make(map[string]taskStats) + for _, task := range tasks { + stats, ok := summary[task.Name] + if !ok { + stats.Type = task.Name + } + stats.add(task) + summary[task.Name] = stats + } + + // Sort tasks by type. + userTasks := make([]taskStats, 0, len(summary)) + for _, stats := range summary { + userTasks = append(userTasks, stats) + } + slices.SortFunc(userTasks, func(a, b taskStats) int { + return cmp.Compare(a.Type, b.Type) + }) + + // Emit table. + err := templUserTaskTypes.Execute(w, userTasks) + if err != nil { + http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) + return + } + } +} + +type taskStats struct { + Type string + Count int // Complete + incomplete tasks + Histogram traceviewer.TimeHistogram // Complete tasks only +} + +func (s *taskStats) UserTaskURL(complete bool) func(min, max time.Duration) string { + return func(min, max time.Duration) string { + return fmt.Sprintf("/usertask?type=%s&complete=%v&latmin=%v&latmax=%v", template.URLQueryEscaper(s.Type), template.URLQueryEscaper(complete), template.URLQueryEscaper(min), template.URLQueryEscaper(max)) + } +} + +func (s *taskStats) add(task *trace.UserTaskSummary) { + s.Count++ + if task.Complete() { + s.Histogram.Add(task.End.Time().Sub(task.Start.Time())) + } +} + +var templUserTaskTypes = template.Must(template.New("").Parse(` + +Tasks + + +Search log text:

+ + + + + + +{{range $}} + + + + + +{{end}} +
Task typeCountDuration distribution (complete tasks)
{{.Type}}{{.Count}}{{.Histogram.ToHTML (.UserTaskURL true)}}
+ + +`)) + +// UserTaskHandlerFunc returns a HandlerFunc that presents the details of the selected tasks. +func UserTaskHandlerFunc(t *parsedTrace) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + filter, err := newTaskFilter(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + type event struct { + WhenString string + Elapsed time.Duration + Goroutine tracev2.GoID + What string + // TODO: include stack trace of creation time + } + type task struct { + WhenString string + ID tracev2.TaskID + Duration time.Duration + Complete bool + Events []event + Start, End time.Duration // Time since the beginning of the trace + GCTime time.Duration + } + var tasks []task + for _, summary := range t.summary.Tasks { + if !filter.match(t, summary) { + continue + } + + // Collect all the events for the task. + var rawEvents []*tracev2.Event + if summary.Start != nil { + rawEvents = append(rawEvents, summary.Start) + } + if summary.End != nil { + rawEvents = append(rawEvents, summary.End) + } + rawEvents = append(rawEvents, summary.Logs...) + for _, r := range summary.Regions { + if r.Start != nil { + rawEvents = append(rawEvents, r.Start) + } + if r.End != nil { + rawEvents = append(rawEvents, r.End) + } + } + + // Sort them. + slices.SortStableFunc(rawEvents, func(a, b *tracev2.Event) int { + return cmp.Compare(a.Time(), b.Time()) + }) + + // Summarize them. + var events []event + last := t.startTime() + for _, ev := range rawEvents { + what := describeEvent(ev) + if what == "" { + continue + } + sinceStart := ev.Time().Sub(t.startTime()) + events = append(events, event{ + WhenString: fmt.Sprintf("%2.9f", sinceStart.Seconds()), + Elapsed: ev.Time().Sub(last), + What: what, + Goroutine: primaryGoroutine(ev), + }) + last = ev.Time() + } + taskSpan := taskInterval(t, summary) + taskStart := taskSpan.start.Sub(t.startTime()) + + // Produce the task summary. + tasks = append(tasks, task{ + WhenString: fmt.Sprintf("%2.9fs", taskStart.Seconds()), + Duration: taskSpan.duration(), + ID: summary.ID, + Complete: summary.Complete(), + Events: events, + Start: taskStart, + End: taskStart + taskSpan.duration(), + }) + } + // Sort the tasks by duration. + slices.SortFunc(tasks, func(a, b task) int { + return cmp.Compare(a.Duration, b.Duration) + }) + + // Emit table. + err = templUserTaskType.Execute(w, struct { + Name string + Tasks []task + }{ + Name: filter.name, + Tasks: tasks, + }) + if err != nil { + log.Printf("failed to execute template: %v", err) + http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) + return + } + } +} + +var templUserTaskType = template.Must(template.New("userTask").Funcs(template.FuncMap{ + "elapsed": elapsed, + "asMillisecond": asMillisecond, + "trimSpace": strings.TrimSpace, +}).Parse(` + +Tasks: {{.Name}} + + + +

User Task: {{.Name}}

+ +Search log text:
+ +

+ + + + + + + + + {{range $el := $.Tasks}} + + + + + + + {{range $el.Events}} + + + + + + + {{end}} + {{end}} + + +`)) + +// taskFilter represents a task filter specified by a user of cmd/trace. +type taskFilter struct { + name string + cond []func(*parsedTrace, *trace.UserTaskSummary) bool +} + +// match returns true if a task, described by its ID and summary, matches +// the filter. +func (f *taskFilter) match(t *parsedTrace, task *trace.UserTaskSummary) bool { + if t == nil { + return false + } + for _, c := range f.cond { + if !c(t, task) { + return false + } + } + return true +} + +// newTaskFilter creates a new task filter from URL query variables. +func newTaskFilter(r *http.Request) (*taskFilter, error) { + if err := r.ParseForm(); err != nil { + return nil, err + } + + var name []string + var conditions []func(*parsedTrace, *trace.UserTaskSummary) bool + + param := r.Form + if typ, ok := param["type"]; ok && len(typ) > 0 { + name = append(name, fmt.Sprintf("%q", typ[0])) + conditions = append(conditions, func(_ *parsedTrace, task *trace.UserTaskSummary) bool { + return task.Name == typ[0] + }) + } + if complete := r.FormValue("complete"); complete == "1" { + name = append(name, "complete") + conditions = append(conditions, func(_ *parsedTrace, task *trace.UserTaskSummary) bool { + return task.Complete() + }) + } else if complete == "0" { + name = append(name, "incomplete") + conditions = append(conditions, func(_ *parsedTrace, task *trace.UserTaskSummary) bool { + return !task.Complete() + }) + } + if lat, err := time.ParseDuration(r.FormValue("latmin")); err == nil { + name = append(name, fmt.Sprintf("latency >= %s", lat)) + conditions = append(conditions, func(t *parsedTrace, task *trace.UserTaskSummary) bool { + return task.Complete() && taskInterval(t, task).duration() >= lat + }) + } + if lat, err := time.ParseDuration(r.FormValue("latmax")); err == nil { + name = append(name, fmt.Sprintf("latency <= %s", lat)) + conditions = append(conditions, func(t *parsedTrace, task *trace.UserTaskSummary) bool { + return task.Complete() && taskInterval(t, task).duration() <= lat + }) + } + if text := r.FormValue("logtext"); text != "" { + name = append(name, fmt.Sprintf("log contains %q", text)) + conditions = append(conditions, func(_ *parsedTrace, task *trace.UserTaskSummary) bool { + return taskMatches(task, text) + }) + } + + return &taskFilter{name: strings.Join(name, ","), cond: conditions}, nil +} + +func taskInterval(t *parsedTrace, s *trace.UserTaskSummary) interval { + var i interval + if s.Start != nil { + i.start = s.Start.Time() + } else { + i.start = t.startTime() + } + if s.End != nil { + i.end = s.End.Time() + } else { + i.end = t.endTime() + } + return i +} + +func taskMatches(t *trace.UserTaskSummary, text string) bool { + matches := func(s string) bool { + return strings.Contains(s, text) + } + if matches(t.Name) { + return true + } + for _, r := range t.Regions { + if matches(r.Name) { + return true + } + } + for _, ev := range t.Logs { + log := ev.Log() + if matches(log.Category) { + return true + } + if matches(log.Message) { + return true + } + } + return false +} + +func describeEvent(ev *tracev2.Event) string { + switch ev.Kind() { + case tracev2.EventStateTransition: + st := ev.StateTransition() + if st.Resource.Kind != tracev2.ResourceGoroutine { + return "" + } + old, new := st.Goroutine() + return fmt.Sprintf("%s -> %s", old, new) + case tracev2.EventRegionBegin: + return fmt.Sprintf("region %q begin", ev.Region().Type) + case tracev2.EventRegionEnd: + return fmt.Sprintf("region %q end", ev.Region().Type) + case tracev2.EventTaskBegin: + t := ev.Task() + return fmt.Sprintf("task %q (D %d, parent %d) begin", t.Type, t.ID, t.Parent) + case tracev2.EventTaskEnd: + return "task end" + case tracev2.EventLog: + log := ev.Log() + if log.Category != "" { + return fmt.Sprintf("log %q", log.Message) + } + return fmt.Sprintf("log (category: %s): %q", log.Category, log.Message) + } + return "" +} + +func primaryGoroutine(ev *tracev2.Event) tracev2.GoID { + if ev.Kind() != tracev2.EventStateTransition { + return ev.Goroutine() + } + st := ev.StateTransition() + if st.Resource.Kind != tracev2.ResourceGoroutine { + return tracev2.NoGoroutine + } + return st.Resource.Goroutine() +} + +func elapsed(d time.Duration) string { + b := fmt.Appendf(nil, "%.9f", d.Seconds()) + + // For subsecond durations, blank all zeros before decimal point, + // and all zeros between the decimal point and the first non-zero digit. + if d < time.Second { + dot := bytes.IndexByte(b, '.') + for i := 0; i < dot; i++ { + b[i] = ' ' + } + for i := dot + 1; i < len(b); i++ { + if b[i] == '0' { + b[i] = ' ' + } else { + break + } + } + } + return string(b) +} + +func asMillisecond(d time.Duration) float64 { + return float64(d.Nanoseconds()) / float64(time.Millisecond) +} diff --git a/src/cmd/trace/testdata/generate.go b/src/cmd/trace/testdata/generate.go new file mode 100644 index 0000000000..c0658b2329 --- /dev/null +++ b/src/cmd/trace/testdata/generate.go @@ -0,0 +1,6 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run mktests.go +package testdata diff --git a/src/cmd/trace/testdata/go122.test b/src/cmd/trace/testdata/go122.test new file mode 100644 index 0000000000..2ec9e88f4f --- /dev/null +++ b/src/cmd/trace/testdata/go122.test @@ -0,0 +1,4639 @@ +Trace Go1.22 +EventBatch gen=1 m=18446744073709551615 time=7689672466239 size=5 +Frequency freq=15625000 +EventBatch gen=1 m=1709048 time=7689670869319 size=423 +ProcStart dt=409 p=7 p_seq=1 +GoStart dt=31 g=34 g_seq=1 +GoStop dt=291990 reason_string=16 stack=50 +GoStart dt=21 g=34 g_seq=2 +GoStop dt=315853 reason_string=16 stack=50 +GoStart dt=30 g=34 g_seq=3 +GoUnblock dt=173432 g=1 g_seq=73 stack=52 +GoDestroy dt=96 +GoStart dt=22 g=1 g_seq=74 +HeapAlloc dt=79 heapalloc_value=26397576 +HeapAlloc dt=51 heapalloc_value=26405640 +GoCreate dt=62 new_g=50 new_stack=53 stack=54 +GoBlock dt=23 reason_string=12 stack=55 +GoStart dt=7 g=50 g_seq=1 +HeapAlloc dt=301 heapalloc_value=26413776 +HeapAlloc dt=30 heapalloc_value=26421680 +GoSyscallBegin dt=35 p_seq=2 stack=56 +GoSyscallEnd dt=39 +GoSyscallBegin dt=13 p_seq=3 stack=57 +GoSyscallEnd dt=16 +GoSyscallBegin dt=396 p_seq=4 stack=58 +GoSyscallEnd dt=16 +GoSyscallBegin dt=15 p_seq=5 stack=59 +GoSyscallEnd dt=14 +HeapAlloc dt=305 heapalloc_value=26429872 +HeapAlloc dt=34 heapalloc_value=26437248 +HeapAlloc dt=42 heapalloc_value=26445120 +GoSyscallBegin dt=42 p_seq=6 stack=60 +GoSyscallEnd dt=18 +GoSyscallBegin dt=10 p_seq=7 stack=61 +GoSyscallEnd dt=14 +GoSyscallBegin dt=23 p_seq=8 stack=62 +ProcStart dt=787251 p=7 p_seq=15 +GoSyscallEndBlocked dt=7 +GoStart dt=1 g=50 g_seq=2 +GoUnblock dt=48 g=1 g_seq=75 stack=65 +GoDestroy dt=143 +GoStart dt=30 g=1 g_seq=76 +HeapAlloc dt=621 heapalloc_value=26468232 +GoStop dt=656 reason_string=16 stack=66 +GoStart dt=103 g=1 g_seq=77 +HeapAlloc dt=42 heapalloc_value=26476424 +HeapAlloc dt=87 heapalloc_value=26484360 +GoSyscallBegin dt=18 p_seq=16 stack=67 +GoSyscallEnd dt=456 +GoSyscallBegin dt=41 p_seq=17 stack=68 +GoSyscallEnd dt=25 +GoSyscallBegin dt=16 p_seq=18 stack=69 +GoSyscallEnd dt=18 +HeapAlloc dt=193 heapalloc_value=26549896 +GoSyscallBegin dt=69 p_seq=19 stack=70 +GoSyscallEnd dt=227 +GoSyscallBegin dt=12 p_seq=20 stack=70 +GoSyscallEnd dt=105 +GoSyscallBegin dt=87 p_seq=21 stack=71 +GoSyscallEnd dt=48 +GoSyscallBegin dt=37 p_seq=22 stack=72 +GoSyscallEnd dt=51 +GoSyscallBegin dt=49 p_seq=23 stack=73 +GoSyscallEnd dt=158 +GoSyscallBegin dt=12 p_seq=24 stack=74 +GoSyscallEnd dt=67 +HeapAlloc dt=126 heapalloc_value=26558088 +HeapAlloc dt=30 heapalloc_value=26566160 +GoCreate dt=34 new_g=52 new_stack=75 stack=76 +HeapAlloc dt=205 heapalloc_value=26573872 +GoSyscallBegin dt=890 p_seq=25 stack=77 +GoSyscallEnd dt=1128 +GoBlock dt=96 reason_string=7 stack=80 +ProcStop dt=29 +ProcStart dt=384 p=6 p_seq=7 +GoStart dt=14 g=52 g_seq=4 +GoSyscallBegin dt=16 p_seq=8 stack=78 +ProcStart dt=160 p=5 p_seq=13 +GoSyscallEndBlocked dt=3 +GoStart dt=1 g=52 g_seq=5 +HeapAlloc dt=297 heapalloc_value=26581840 +HeapAlloc dt=31 heapalloc_value=26590032 +HeapAlloc dt=164 heapalloc_value=26598224 +GoSyscallBegin dt=34 p_seq=14 stack=88 +GoSyscallEnd dt=33 +GoSyscallBegin dt=14 p_seq=15 stack=89 +GoSyscallEnd dt=36 +GoSyscallBegin dt=12 p_seq=16 stack=90 +GoSyscallEnd dt=22 +GoSyscallBegin dt=15 p_seq=17 stack=91 +GoSyscallEnd dt=28 +HeapAlloc dt=18 heapalloc_value=26606416 +HeapAlloc dt=20 heapalloc_value=26614608 +GoBlock dt=16 reason_string=19 stack=92 +ProcStop dt=136 +ProcStart dt=17788 p=6 p_seq=12 +GoUnblock dt=41 g=1 g_seq=80 stack=0 +GoStart dt=136 g=1 g_seq=81 +GoSyscallBegin dt=14 p_seq=13 stack=86 +GoSyscallEnd dt=65 +GoSyscallBegin dt=72 p_seq=14 stack=95 +GoSyscallEnd dt=534 +HeapAlloc dt=284 heapalloc_value=26630992 +HeapAlloc dt=38 heapalloc_value=26639120 +EventBatch gen=1 m=1709047 time=7689670866279 size=202 +ProcStart dt=437 p=6 p_seq=2 +HeapAlloc dt=131 heapalloc_value=26373928 +HeapAlloc dt=368 heapalloc_value=26382120 +HeapAlloc dt=55 heapalloc_value=26390056 +GoStart dt=1030 g=36 g_seq=1 +GoStop dt=293329 reason_string=16 stack=50 +GoStart dt=25 g=36 g_seq=2 +GoStop dt=315834 reason_string=16 stack=50 +GoStart dt=24 g=36 g_seq=3 +GoDestroy dt=172079 +ProcStop dt=60 +ProcStart dt=1749 p=6 p_seq=3 +ProcStop dt=1621 +ProcStart dt=64901 p=5 p_seq=4 +ProcStop dt=24 +ProcStart dt=722061 p=5 p_seq=5 +ProcStop dt=31 +ProcStart dt=2847 p=5 p_seq=8 +ProcStop dt=20 +ProcStart dt=3166 p=7 p_seq=26 +GoUnblock dt=6 g=52 g_seq=3 stack=0 +GoUnblock dt=90 g=1 g_seq=78 stack=0 +GoStart dt=5 g=1 g_seq=79 +GoSyscallBegin dt=31 p_seq=27 stack=81 +GoSyscallEnd dt=35 +GoSyscallBegin dt=134 p_seq=28 stack=82 +GoSyscallEnd dt=29 +GoSyscallBegin dt=17 p_seq=29 stack=83 +GoSyscallEnd dt=30 +GoSyscallBegin dt=8 p_seq=30 stack=84 +GoSyscallEnd dt=19 +GoSyscallBegin dt=11 p_seq=31 stack=85 +GoSyscallEnd dt=24 +GoSyscallBegin dt=65 p_seq=32 stack=86 +GoSyscallEnd dt=57 +GoBlock dt=19 reason_string=7 stack=87 +ProcStop dt=38 +ProcStart dt=458 p=6 p_seq=11 +ProcStop dt=30 +ProcStart dt=377 p=5 p_seq=18 +ProcStop dt=23 +ProcStart dt=17141 p=5 p_seq=19 +GoUnblock dt=19 g=52 g_seq=6 stack=0 +GoStart dt=111 g=52 g_seq=7 +HeapAlloc dt=38 heapalloc_value=26622800 +GoSyscallBegin dt=36 p_seq=20 stack=93 +GoSyscallEnd dt=554 +GoSyscallBegin dt=83 p_seq=21 stack=94 +GoSyscallEnd dt=196 +GoDestroy dt=15 +ProcStop dt=37 +EventBatch gen=1 m=1709046 time=7689670697530 size=167 +ProcStart dt=236 p=5 p_seq=1 +ProcStop dt=281 +ProcStart dt=1683 p=2 p_seq=14 +ProcStop dt=33 +ProcStart dt=147800 p=2 p_seq=16 +ProcStop dt=29 +ProcStart dt=3880 p=1 p_seq=28 +ProcStop dt=30 +ProcStart dt=801175 p=5 p_seq=3 +ProcStop dt=19 +ProcStart dt=47961 p=6 p_seq=4 +ProcStop dt=15 +ProcStart dt=16716 p=6 p_seq=5 +GoUnblock dt=60 g=6 g_seq=2 stack=0 +GoStart dt=90 g=6 g_seq=3 +HeapAlloc dt=193 heapalloc_value=26453304 +GoBlock dt=29 reason_string=12 stack=15 +ProcStop dt=12 +ProcStart dt=704555 p=7 p_seq=10 +ProcStop dt=25 +ProcStart dt=16755 p=7 p_seq=11 +HeapAlloc dt=61 heapalloc_value=26461496 +GoCreate dt=72 new_g=51 new_stack=63 stack=0 +GoStart dt=98 g=51 g_seq=1 +GoSyscallBegin dt=45 p_seq=12 stack=64 +ProcStart dt=206 p=7 p_seq=14 +GoSyscallEndBlocked dt=3 +GoStart dt=1 g=51 g_seq=2 +GoDestroy dt=12 +ProcStop dt=18 +ProcStart dt=849 p=5 p_seq=6 +ProcStop dt=16 +ProcStart dt=1359 p=5 p_seq=7 +ProcStop dt=12 +ProcStart dt=2079 p=5 p_seq=9 +GoStart dt=1134 g=52 g_seq=1 +GoSyscallBegin dt=39 p_seq=10 stack=78 +ProcStart dt=232 p=5 p_seq=12 +GoSyscallEndBlocked dt=2 +GoStart dt=1 g=52 g_seq=2 +GoBlock dt=27 reason_string=7 stack=79 +ProcStop dt=20 +EventBatch gen=1 m=1709045 time=7689670544102 size=3297 +ProcStart dt=84 p=4 p_seq=5 +GoUnblock dt=91 g=1 g_seq=34 stack=0 +GoStart dt=157 g=1 g_seq=35 +HeapAlloc dt=117 heapalloc_value=8105520 +HeapAlloc dt=67 heapalloc_value=8113712 +HeapAlloc dt=36 heapalloc_value=8121904 +HeapAlloc dt=25 heapalloc_value=8130096 +HeapAlloc dt=25 heapalloc_value=8138288 +HeapAlloc dt=25 heapalloc_value=8146480 +HeapAlloc dt=21 heapalloc_value=8154672 +HeapAlloc dt=26 heapalloc_value=8162864 +HeapAlloc dt=18 heapalloc_value=8171056 +HeapAlloc dt=24 heapalloc_value=8179248 +HeapAlloc dt=15 heapalloc_value=8187440 +HeapAlloc dt=133 heapalloc_value=8195632 +HeapAlloc dt=105 heapalloc_value=8203824 +HeapAlloc dt=20 heapalloc_value=8212016 +HeapAlloc dt=18 heapalloc_value=8220208 +HeapAlloc dt=8 heapalloc_value=8228400 +HeapAlloc dt=8 heapalloc_value=8236592 +HeapAlloc dt=9 heapalloc_value=8244784 +GCMarkAssistBegin dt=27 stack=31 +HeapAlloc dt=69 heapalloc_value=8252784 +GoBlock dt=31 reason_string=10 stack=36 +ProcStop dt=156 +ProcStart dt=993 p=0 p_seq=11 +GoStart dt=192 g=1 g_seq=37 +GCMarkAssistEnd dt=12 +HeapAlloc dt=35 heapalloc_value=8746312 +GCSweepBegin dt=26 stack=42 +GCSweepEnd dt=777 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=22 heapalloc_value=8754504 +GCSweepBegin dt=47 stack=42 +GCSweepEnd dt=662 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=11 heapalloc_value=8762696 +GCSweepBegin dt=25 stack=42 +GCSweepEnd dt=712 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=39 heapalloc_value=8770888 +GCSweepBegin dt=27 stack=42 +GCSweepEnd dt=630 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=9 heapalloc_value=8779080 +GCSweepBegin dt=25 stack=42 +GCSweepEnd dt=1256 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=8 heapalloc_value=8787272 +GCSweepBegin dt=40 stack=42 +GCSweepEnd dt=529 swept_value=360448 reclaimed_value=0 +HeapAlloc dt=9 heapalloc_value=8795464 +HeapAlloc dt=24 heapalloc_value=8803656 +HeapAlloc dt=24 heapalloc_value=8811848 +HeapAlloc dt=25 heapalloc_value=8820040 +HeapAlloc dt=23 heapalloc_value=8828232 +HeapAlloc dt=18 heapalloc_value=8836424 +HeapAlloc dt=95 heapalloc_value=8844616 +HeapAlloc dt=25 heapalloc_value=8852808 +HeapAlloc dt=23 heapalloc_value=8861000 +HeapAlloc dt=19 heapalloc_value=8869192 +HeapAlloc dt=93 heapalloc_value=8877384 +HeapAlloc dt=23 heapalloc_value=8885576 +HeapAlloc dt=23 heapalloc_value=8893768 +HeapAlloc dt=23 heapalloc_value=8901960 +HeapAlloc dt=22 heapalloc_value=8910152 +HeapAlloc dt=18 heapalloc_value=8918344 +HeapAlloc dt=174 heapalloc_value=8926536 +HeapAlloc dt=31 heapalloc_value=8934728 +HeapAlloc dt=38 heapalloc_value=8942920 +HeapAlloc dt=31 heapalloc_value=8951112 +HeapAlloc dt=57 heapalloc_value=8959304 +HeapAlloc dt=58 heapalloc_value=8967496 +HeapAlloc dt=60 heapalloc_value=8975688 +HeapAlloc dt=44 heapalloc_value=8983880 +HeapAlloc dt=53 heapalloc_value=8992072 +HeapAlloc dt=57 heapalloc_value=9000264 +HeapAlloc dt=63 heapalloc_value=9008456 +HeapAlloc dt=55 heapalloc_value=9016648 +HeapAlloc dt=28 heapalloc_value=9024840 +HeapAlloc dt=12 heapalloc_value=9033032 +HeapAlloc dt=9 heapalloc_value=9041224 +HeapAlloc dt=8 heapalloc_value=9049416 +HeapAlloc dt=7 heapalloc_value=9057608 +HeapAlloc dt=8 heapalloc_value=9065800 +HeapAlloc dt=14 heapalloc_value=9073992 +HeapAlloc dt=8 heapalloc_value=9082184 +HeapAlloc dt=45 heapalloc_value=9090376 +HeapAlloc dt=10 heapalloc_value=9098568 +HeapAlloc dt=14 heapalloc_value=9106760 +HeapAlloc dt=8 heapalloc_value=9114952 +HeapAlloc dt=10 heapalloc_value=9123144 +HeapAlloc dt=15 heapalloc_value=9131336 +HeapAlloc dt=53 heapalloc_value=9139528 +HeapAlloc dt=27 heapalloc_value=9147720 +HeapAlloc dt=38 heapalloc_value=9155912 +HeapAlloc dt=33 heapalloc_value=9164104 +HeapAlloc dt=33 heapalloc_value=9172296 +HeapAlloc dt=34 heapalloc_value=9180488 +HeapAlloc dt=36 heapalloc_value=9188680 +HeapAlloc dt=39 heapalloc_value=9196872 +HeapAlloc dt=40 heapalloc_value=9205064 +HeapAlloc dt=59 heapalloc_value=9213256 +HeapAlloc dt=28 heapalloc_value=9221448 +HeapAlloc dt=22 heapalloc_value=9229640 +HeapAlloc dt=20 heapalloc_value=9237832 +HeapAlloc dt=25 heapalloc_value=9246024 +HeapAlloc dt=20 heapalloc_value=9254216 +HeapAlloc dt=16 heapalloc_value=9262408 +HeapAlloc dt=14 heapalloc_value=9270600 +HeapAlloc dt=18 heapalloc_value=9278792 +HeapAlloc dt=32 heapalloc_value=9286984 +HeapAlloc dt=21 heapalloc_value=9295176 +HeapAlloc dt=49 heapalloc_value=9303368 +HeapAlloc dt=23 heapalloc_value=9311560 +HeapAlloc dt=16 heapalloc_value=9319752 +HeapAlloc dt=15 heapalloc_value=9327944 +HeapAlloc dt=13 heapalloc_value=9336136 +HeapAlloc dt=15 heapalloc_value=9344328 +HeapAlloc dt=14 heapalloc_value=9352520 +HeapAlloc dt=16 heapalloc_value=9360712 +HeapAlloc dt=14 heapalloc_value=9368904 +HeapAlloc dt=19 heapalloc_value=9377096 +HeapAlloc dt=16 heapalloc_value=9385288 +HeapAlloc dt=15 heapalloc_value=9393480 +HeapAlloc dt=14 heapalloc_value=9401672 +HeapAlloc dt=16 heapalloc_value=9409864 +HeapAlloc dt=15 heapalloc_value=9418056 +HeapAlloc dt=15 heapalloc_value=9426248 +HeapAlloc dt=15 heapalloc_value=9434440 +HeapAlloc dt=18 heapalloc_value=9442632 +HeapAlloc dt=94 heapalloc_value=9450824 +HeapAlloc dt=17 heapalloc_value=9459016 +HeapAlloc dt=14 heapalloc_value=9467208 +HeapAlloc dt=16 heapalloc_value=9475400 +HeapAlloc dt=15 heapalloc_value=9483592 +HeapAlloc dt=15 heapalloc_value=9491784 +HeapAlloc dt=15 heapalloc_value=9499976 +HeapAlloc dt=49 heapalloc_value=9508168 +HeapAlloc dt=16 heapalloc_value=9516360 +HeapAlloc dt=14 heapalloc_value=9524552 +HeapAlloc dt=15 heapalloc_value=9532744 +HeapAlloc dt=15 heapalloc_value=9540936 +HeapAlloc dt=15 heapalloc_value=9549128 +HeapAlloc dt=17 heapalloc_value=9557320 +HeapAlloc dt=15 heapalloc_value=9565512 +HeapAlloc dt=21 heapalloc_value=9573704 +HeapAlloc dt=15 heapalloc_value=9581896 +HeapAlloc dt=16 heapalloc_value=9590088 +HeapAlloc dt=14 heapalloc_value=9598280 +HeapAlloc dt=16 heapalloc_value=9606472 +HeapAlloc dt=14 heapalloc_value=9614664 +HeapAlloc dt=16 heapalloc_value=9622856 +GoBlock dt=21 reason_string=19 stack=21 +ProcStop dt=157 +ProcStart dt=17320 p=2 p_seq=6 +ProcStop dt=15 +ProcStart dt=2411 p=0 p_seq=14 +ProcStop dt=8 +ProcStart dt=16766 p=0 p_seq=15 +GoUnblock dt=9 g=1 g_seq=40 stack=0 +GoStart dt=91 g=1 g_seq=41 +HeapAlloc dt=19 heapalloc_value=10859848 +HeapAlloc dt=9 heapalloc_value=10868040 +HeapAlloc dt=7 heapalloc_value=10876232 +HeapAlloc dt=6 heapalloc_value=10884424 +HeapAlloc dt=6 heapalloc_value=10892616 +HeapAlloc dt=6 heapalloc_value=10900808 +HeapAlloc dt=6 heapalloc_value=10909000 +HeapAlloc dt=6 heapalloc_value=10917192 +HeapAlloc dt=6 heapalloc_value=10925384 +HeapAlloc dt=6 heapalloc_value=10933576 +HeapAlloc dt=6 heapalloc_value=10941768 +HeapAlloc dt=6 heapalloc_value=10949960 +HeapAlloc dt=6 heapalloc_value=10958152 +HeapAlloc dt=5 heapalloc_value=10966344 +HeapAlloc dt=6 heapalloc_value=10974536 +HeapAlloc dt=6 heapalloc_value=10982728 +HeapAlloc dt=6 heapalloc_value=10990920 +HeapAlloc dt=6 heapalloc_value=10999112 +HeapAlloc dt=6 heapalloc_value=11007304 +HeapAlloc dt=5 heapalloc_value=11015496 +HeapAlloc dt=7 heapalloc_value=11023688 +HeapAlloc dt=6 heapalloc_value=11031880 +HeapAlloc dt=14 heapalloc_value=11040072 +HeapAlloc dt=7 heapalloc_value=11048264 +HeapAlloc dt=6 heapalloc_value=11056456 +HeapAlloc dt=6 heapalloc_value=11064648 +HeapAlloc dt=5 heapalloc_value=11072840 +HeapAlloc dt=6 heapalloc_value=11081032 +HeapAlloc dt=6 heapalloc_value=11089224 +HeapAlloc dt=6 heapalloc_value=11097416 +HeapAlloc dt=6 heapalloc_value=11105608 +HeapAlloc dt=6 heapalloc_value=11113800 +HeapAlloc dt=59 heapalloc_value=11121992 +HeapAlloc dt=9 heapalloc_value=11130184 +HeapAlloc dt=7 heapalloc_value=11138376 +HeapAlloc dt=6 heapalloc_value=11146568 +HeapAlloc dt=6 heapalloc_value=11154760 +HeapAlloc dt=5 heapalloc_value=11162952 +HeapAlloc dt=6 heapalloc_value=11171144 +HeapAlloc dt=6 heapalloc_value=11179336 +HeapAlloc dt=6 heapalloc_value=11187528 +HeapAlloc dt=5 heapalloc_value=11195720 +HeapAlloc dt=6 heapalloc_value=11203912 +HeapAlloc dt=6 heapalloc_value=11212104 +HeapAlloc dt=84 heapalloc_value=11220296 +HeapAlloc dt=7 heapalloc_value=11228488 +HeapAlloc dt=6 heapalloc_value=11236680 +HeapAlloc dt=6 heapalloc_value=11244872 +HeapAlloc dt=5 heapalloc_value=11253064 +HeapAlloc dt=6 heapalloc_value=11261256 +HeapAlloc dt=6 heapalloc_value=11269448 +HeapAlloc dt=6 heapalloc_value=11277640 +HeapAlloc dt=5 heapalloc_value=11285832 +HeapAlloc dt=6 heapalloc_value=11294024 +HeapAlloc dt=6 heapalloc_value=11302216 +HeapAlloc dt=5 heapalloc_value=11310408 +HeapAlloc dt=6 heapalloc_value=11318600 +HeapAlloc dt=38 heapalloc_value=11326792 +HeapAlloc dt=7 heapalloc_value=11334984 +HeapAlloc dt=6 heapalloc_value=11343176 +HeapAlloc dt=6 heapalloc_value=11351368 +HeapAlloc dt=5 heapalloc_value=11359560 +HeapAlloc dt=6 heapalloc_value=11367752 +HeapAlloc dt=6 heapalloc_value=11375944 +HeapAlloc dt=6 heapalloc_value=11384136 +HeapAlloc dt=6 heapalloc_value=11392328 +HeapAlloc dt=5 heapalloc_value=11400520 +HeapAlloc dt=6 heapalloc_value=11408712 +HeapAlloc dt=6 heapalloc_value=11416904 +HeapAlloc dt=5 heapalloc_value=11425096 +HeapAlloc dt=6 heapalloc_value=11433288 +HeapAlloc dt=6 heapalloc_value=11441480 +HeapAlloc dt=6 heapalloc_value=11449672 +HeapAlloc dt=5 heapalloc_value=11457864 +HeapAlloc dt=6 heapalloc_value=11466056 +HeapAlloc dt=79 heapalloc_value=11474248 +HeapAlloc dt=6 heapalloc_value=11482440 +HeapAlloc dt=5 heapalloc_value=11490632 +HeapAlloc dt=6 heapalloc_value=11498824 +HeapAlloc dt=6 heapalloc_value=11507016 +HeapAlloc dt=6 heapalloc_value=11515208 +HeapAlloc dt=5 heapalloc_value=11523400 +HeapAlloc dt=6 heapalloc_value=11531592 +HeapAlloc dt=5 heapalloc_value=11539784 +HeapAlloc dt=6 heapalloc_value=11547976 +HeapAlloc dt=6 heapalloc_value=11556168 +HeapAlloc dt=10 heapalloc_value=11564360 +HeapAlloc dt=6 heapalloc_value=11572552 +HeapAlloc dt=24 heapalloc_value=11580744 +HeapAlloc dt=7 heapalloc_value=11588936 +HeapAlloc dt=5 heapalloc_value=11597128 +HeapAlloc dt=6 heapalloc_value=11605320 +HeapAlloc dt=6 heapalloc_value=11613512 +HeapAlloc dt=6 heapalloc_value=11621704 +HeapAlloc dt=5 heapalloc_value=11629896 +HeapAlloc dt=6 heapalloc_value=11638088 +HeapAlloc dt=6 heapalloc_value=11646280 +HeapAlloc dt=5 heapalloc_value=11654472 +HeapAlloc dt=6 heapalloc_value=11662664 +HeapAlloc dt=6 heapalloc_value=11670856 +HeapAlloc dt=6 heapalloc_value=11679048 +HeapAlloc dt=5 heapalloc_value=11687240 +HeapAlloc dt=6 heapalloc_value=11695432 +HeapAlloc dt=6 heapalloc_value=11703624 +HeapAlloc dt=6 heapalloc_value=11711816 +HeapAlloc dt=5 heapalloc_value=11720008 +HeapAlloc dt=6 heapalloc_value=11728200 +HeapAlloc dt=6 heapalloc_value=11736392 +HeapAlloc dt=70 heapalloc_value=11744584 +HeapAlloc dt=8 heapalloc_value=11752776 +HeapAlloc dt=5 heapalloc_value=11760968 +HeapAlloc dt=6 heapalloc_value=11769160 +HeapAlloc dt=5 heapalloc_value=11777352 +HeapAlloc dt=6 heapalloc_value=11785544 +HeapAlloc dt=6 heapalloc_value=11793736 +HeapAlloc dt=6 heapalloc_value=11801928 +HeapAlloc dt=5 heapalloc_value=11810120 +HeapAlloc dt=6 heapalloc_value=11818312 +HeapAlloc dt=6 heapalloc_value=11826504 +HeapAlloc dt=6 heapalloc_value=11834696 +HeapAlloc dt=6 heapalloc_value=11842888 +HeapAlloc dt=5 heapalloc_value=11851080 +HeapAlloc dt=6 heapalloc_value=11859272 +HeapAlloc dt=5 heapalloc_value=11867464 +HeapAlloc dt=6 heapalloc_value=11875656 +GoBlock dt=9 reason_string=19 stack=21 +ProcStop dt=105 +ProcStart dt=17283 p=2 p_seq=8 +ProcStop dt=12 +ProcStart dt=4008 p=0 p_seq=18 +ProcStop dt=9 +ProcStart dt=16692 p=0 p_seq=19 +GoUnblock dt=9 g=1 g_seq=44 stack=0 +GoStart dt=76 g=1 g_seq=45 +HeapAlloc dt=16 heapalloc_value=13169992 +HeapAlloc dt=9 heapalloc_value=13178184 +HeapAlloc dt=7 heapalloc_value=13186376 +HeapAlloc dt=5 heapalloc_value=13194568 +HeapAlloc dt=6 heapalloc_value=13202760 +HeapAlloc dt=6 heapalloc_value=13210952 +HeapAlloc dt=5 heapalloc_value=13219144 +HeapAlloc dt=6 heapalloc_value=13227336 +HeapAlloc dt=6 heapalloc_value=13235528 +HeapAlloc dt=6 heapalloc_value=13243720 +HeapAlloc dt=6 heapalloc_value=13251912 +HeapAlloc dt=59 heapalloc_value=13260104 +HeapAlloc dt=8 heapalloc_value=13268296 +HeapAlloc dt=6 heapalloc_value=13276488 +HeapAlloc dt=5 heapalloc_value=13284680 +HeapAlloc dt=6 heapalloc_value=13292872 +HeapAlloc dt=5 heapalloc_value=13301064 +HeapAlloc dt=6 heapalloc_value=13309256 +HeapAlloc dt=5 heapalloc_value=13317448 +HeapAlloc dt=6 heapalloc_value=13325640 +HeapAlloc dt=6 heapalloc_value=13333832 +HeapAlloc dt=6 heapalloc_value=13342024 +HeapAlloc dt=5 heapalloc_value=13350216 +HeapAlloc dt=6 heapalloc_value=13358408 +HeapAlloc dt=6 heapalloc_value=13366600 +HeapAlloc dt=5 heapalloc_value=13374792 +HeapAlloc dt=6 heapalloc_value=13382984 +HeapAlloc dt=6 heapalloc_value=13391176 +HeapAlloc dt=6 heapalloc_value=13399368 +HeapAlloc dt=5 heapalloc_value=13407560 +HeapAlloc dt=8 heapalloc_value=13415752 +HeapAlloc dt=6 heapalloc_value=13423944 +HeapAlloc dt=7 heapalloc_value=13432136 +HeapAlloc dt=5 heapalloc_value=13440328 +HeapAlloc dt=6 heapalloc_value=13448520 +HeapAlloc dt=5 heapalloc_value=13456712 +HeapAlloc dt=6 heapalloc_value=13464904 +HeapAlloc dt=6 heapalloc_value=13473096 +HeapAlloc dt=6 heapalloc_value=13481288 +HeapAlloc dt=5 heapalloc_value=13489480 +HeapAlloc dt=5 heapalloc_value=13497672 +HeapAlloc dt=6 heapalloc_value=13505864 +HeapAlloc dt=5 heapalloc_value=13514056 +HeapAlloc dt=6 heapalloc_value=13522248 +HeapAlloc dt=5 heapalloc_value=13530440 +HeapAlloc dt=6 heapalloc_value=13538632 +HeapAlloc dt=5 heapalloc_value=13546824 +HeapAlloc dt=6 heapalloc_value=13555016 +HeapAlloc dt=6 heapalloc_value=13563208 +HeapAlloc dt=48 heapalloc_value=13571400 +HeapAlloc dt=7 heapalloc_value=13579592 +HeapAlloc dt=6 heapalloc_value=13587784 +HeapAlloc dt=5 heapalloc_value=13595976 +HeapAlloc dt=6 heapalloc_value=13604168 +HeapAlloc dt=5 heapalloc_value=13612360 +HeapAlloc dt=6 heapalloc_value=13620552 +HeapAlloc dt=5 heapalloc_value=13628744 +HeapAlloc dt=6 heapalloc_value=13636936 +HeapAlloc dt=5 heapalloc_value=13645128 +HeapAlloc dt=6 heapalloc_value=13653320 +HeapAlloc dt=14 heapalloc_value=13661512 +HeapAlloc dt=6 heapalloc_value=13669704 +HeapAlloc dt=6 heapalloc_value=13677896 +HeapAlloc dt=35 heapalloc_value=13686088 +HeapAlloc dt=7 heapalloc_value=13694280 +HeapAlloc dt=6 heapalloc_value=13702472 +HeapAlloc dt=6 heapalloc_value=13710664 +HeapAlloc dt=5 heapalloc_value=13718856 +HeapAlloc dt=6 heapalloc_value=13727048 +HeapAlloc dt=6 heapalloc_value=13735240 +HeapAlloc dt=5 heapalloc_value=13743432 +HeapAlloc dt=6 heapalloc_value=13751624 +HeapAlloc dt=5 heapalloc_value=13759816 +HeapAlloc dt=6 heapalloc_value=13768008 +HeapAlloc dt=5 heapalloc_value=13776200 +HeapAlloc dt=5 heapalloc_value=13784392 +HeapAlloc dt=6 heapalloc_value=13792584 +HeapAlloc dt=6 heapalloc_value=13800776 +HeapAlloc dt=5 heapalloc_value=13808968 +HeapAlloc dt=6 heapalloc_value=13817160 +HeapAlloc dt=5 heapalloc_value=13825352 +HeapAlloc dt=6 heapalloc_value=13833544 +HeapAlloc dt=5 heapalloc_value=13841736 +HeapAlloc dt=6 heapalloc_value=13849928 +HeapAlloc dt=5 heapalloc_value=13858120 +HeapAlloc dt=6 heapalloc_value=13866312 +HeapAlloc dt=5 heapalloc_value=13874504 +HeapAlloc dt=5 heapalloc_value=13882696 +HeapAlloc dt=6 heapalloc_value=13890888 +HeapAlloc dt=5 heapalloc_value=13899080 +HeapAlloc dt=6 heapalloc_value=13907272 +HeapAlloc dt=5 heapalloc_value=13915464 +HeapAlloc dt=6 heapalloc_value=13923656 +HeapAlloc dt=21 heapalloc_value=13931848 +HeapAlloc dt=6 heapalloc_value=13940040 +HeapAlloc dt=6 heapalloc_value=13948232 +HeapAlloc dt=6 heapalloc_value=13956424 +HeapAlloc dt=6 heapalloc_value=13964616 +HeapAlloc dt=5 heapalloc_value=13972808 +HeapAlloc dt=5 heapalloc_value=13981000 +HeapAlloc dt=6 heapalloc_value=13989192 +HeapAlloc dt=6 heapalloc_value=13997384 +HeapAlloc dt=5 heapalloc_value=14005576 +HeapAlloc dt=6 heapalloc_value=14013768 +HeapAlloc dt=5 heapalloc_value=14021960 +HeapAlloc dt=6 heapalloc_value=14030152 +HeapAlloc dt=6 heapalloc_value=14038344 +HeapAlloc dt=5 heapalloc_value=14046536 +HeapAlloc dt=6 heapalloc_value=14054728 +HeapAlloc dt=5 heapalloc_value=14062920 +HeapAlloc dt=6 heapalloc_value=14071112 +HeapAlloc dt=5 heapalloc_value=14079304 +HeapAlloc dt=5 heapalloc_value=14087496 +HeapAlloc dt=76 heapalloc_value=14095688 +HeapAlloc dt=35 heapalloc_value=14103880 +HeapAlloc dt=7 heapalloc_value=14112072 +HeapAlloc dt=5 heapalloc_value=14120264 +HeapAlloc dt=6 heapalloc_value=14128456 +HeapAlloc dt=7 heapalloc_value=14136648 +HeapAlloc dt=5 heapalloc_value=14144840 +HeapAlloc dt=5 heapalloc_value=14153032 +HeapAlloc dt=6 heapalloc_value=14161224 +HeapAlloc dt=5 heapalloc_value=14169416 +HeapAlloc dt=6 heapalloc_value=14177608 +HeapAlloc dt=10 heapalloc_value=14185800 +GoBlock dt=9 reason_string=19 stack=21 +ProcStop dt=108 +ProcStart dt=17296 p=2 p_seq=10 +ProcStop dt=12 +ProcStart dt=3626 p=0 p_seq=22 +ProcStop dt=8 +ProcStart dt=16715 p=0 p_seq=23 +GoUnblock dt=6 g=1 g_seq=48 stack=0 +GoStart dt=79 g=1 g_seq=49 +HeapAlloc dt=15 heapalloc_value=15553864 +HeapAlloc dt=13 heapalloc_value=15562056 +HeapAlloc dt=15 heapalloc_value=15570248 +HeapAlloc dt=7 heapalloc_value=15578440 +HeapAlloc dt=6 heapalloc_value=15586632 +HeapAlloc dt=6 heapalloc_value=15594824 +HeapAlloc dt=6 heapalloc_value=15603016 +HeapAlloc dt=6 heapalloc_value=15611208 +HeapAlloc dt=5 heapalloc_value=15619400 +HeapAlloc dt=6 heapalloc_value=15627592 +HeapAlloc dt=6 heapalloc_value=15635784 +HeapAlloc dt=5 heapalloc_value=15643976 +HeapAlloc dt=6 heapalloc_value=15652168 +HeapAlloc dt=5 heapalloc_value=15660360 +HeapAlloc dt=6 heapalloc_value=15668552 +HeapAlloc dt=6 heapalloc_value=15676744 +HeapAlloc dt=57 heapalloc_value=15684936 +HeapAlloc dt=7 heapalloc_value=15693128 +HeapAlloc dt=6 heapalloc_value=15701320 +HeapAlloc dt=6 heapalloc_value=15709512 +HeapAlloc dt=5 heapalloc_value=15717704 +HeapAlloc dt=6 heapalloc_value=15725896 +HeapAlloc dt=5 heapalloc_value=15734088 +HeapAlloc dt=6 heapalloc_value=15742280 +HeapAlloc dt=6 heapalloc_value=15750472 +HeapAlloc dt=10 heapalloc_value=15758664 +HeapAlloc dt=6 heapalloc_value=15766856 +HeapAlloc dt=6 heapalloc_value=15775048 +HeapAlloc dt=5 heapalloc_value=15783240 +HeapAlloc dt=6 heapalloc_value=15791432 +HeapAlloc dt=6 heapalloc_value=15799624 +HeapAlloc dt=6 heapalloc_value=15807816 +HeapAlloc dt=6 heapalloc_value=15816008 +HeapAlloc dt=7 heapalloc_value=15824200 +HeapAlloc dt=6 heapalloc_value=15832392 +HeapAlloc dt=6 heapalloc_value=15840584 +HeapAlloc dt=5 heapalloc_value=15848776 +HeapAlloc dt=6 heapalloc_value=15856968 +HeapAlloc dt=6 heapalloc_value=15865160 +HeapAlloc dt=6 heapalloc_value=15873352 +HeapAlloc dt=5 heapalloc_value=15881544 +HeapAlloc dt=6 heapalloc_value=15889736 +HeapAlloc dt=6 heapalloc_value=15897928 +HeapAlloc dt=5 heapalloc_value=15906120 +HeapAlloc dt=6 heapalloc_value=15914312 +HeapAlloc dt=5 heapalloc_value=15922504 +HeapAlloc dt=6 heapalloc_value=15930696 +HeapAlloc dt=5 heapalloc_value=15938888 +HeapAlloc dt=6 heapalloc_value=15947080 +HeapAlloc dt=5 heapalloc_value=15955272 +HeapAlloc dt=6 heapalloc_value=15963464 +HeapAlloc dt=6 heapalloc_value=15971656 +HeapAlloc dt=5 heapalloc_value=15979848 +HeapAlloc dt=6 heapalloc_value=15988040 +HeapAlloc dt=44 heapalloc_value=15996232 +HeapAlloc dt=8 heapalloc_value=16004424 +HeapAlloc dt=5 heapalloc_value=16012616 +HeapAlloc dt=6 heapalloc_value=16020808 +HeapAlloc dt=5 heapalloc_value=16029000 +HeapAlloc dt=6 heapalloc_value=16037192 +HeapAlloc dt=5 heapalloc_value=16045384 +HeapAlloc dt=6 heapalloc_value=16053576 +HeapAlloc dt=5 heapalloc_value=16061768 +HeapAlloc dt=6 heapalloc_value=16069960 +HeapAlloc dt=5 heapalloc_value=16078152 +HeapAlloc dt=6 heapalloc_value=16086344 +HeapAlloc dt=5 heapalloc_value=16094536 +HeapAlloc dt=6 heapalloc_value=16102728 +HeapAlloc dt=36 heapalloc_value=16110920 +HeapAlloc dt=8 heapalloc_value=16119112 +HeapAlloc dt=6 heapalloc_value=16127304 +HeapAlloc dt=5 heapalloc_value=16135496 +HeapAlloc dt=6 heapalloc_value=16143688 +HeapAlloc dt=5 heapalloc_value=16151880 +HeapAlloc dt=5 heapalloc_value=16160072 +HeapAlloc dt=5 heapalloc_value=16168264 +HeapAlloc dt=5 heapalloc_value=16176456 +HeapAlloc dt=5 heapalloc_value=16184648 +HeapAlloc dt=6 heapalloc_value=16192840 +HeapAlloc dt=5 heapalloc_value=16201032 +HeapAlloc dt=5 heapalloc_value=16209224 +HeapAlloc dt=5 heapalloc_value=16217416 +HeapAlloc dt=5 heapalloc_value=16225608 +HeapAlloc dt=6 heapalloc_value=16233800 +HeapAlloc dt=5 heapalloc_value=16241992 +HeapAlloc dt=73 heapalloc_value=16250184 +HeapAlloc dt=6 heapalloc_value=16258376 +HeapAlloc dt=5 heapalloc_value=16266568 +HeapAlloc dt=6 heapalloc_value=16274760 +HeapAlloc dt=371 heapalloc_value=16282952 +HeapAlloc dt=13 heapalloc_value=16291144 +HeapAlloc dt=7 heapalloc_value=16299336 +HeapAlloc dt=6 heapalloc_value=16307528 +HeapAlloc dt=6 heapalloc_value=16315720 +HeapAlloc dt=5 heapalloc_value=16323912 +HeapAlloc dt=6 heapalloc_value=16332104 +HeapAlloc dt=5 heapalloc_value=16340296 +HeapAlloc dt=5 heapalloc_value=16348488 +HeapAlloc dt=22 heapalloc_value=16356680 +HeapAlloc dt=6 heapalloc_value=16364872 +HeapAlloc dt=5 heapalloc_value=16373064 +HeapAlloc dt=6 heapalloc_value=16381256 +HeapAlloc dt=5 heapalloc_value=16389448 +HeapAlloc dt=5 heapalloc_value=16397640 +HeapAlloc dt=5 heapalloc_value=16405832 +HeapAlloc dt=5 heapalloc_value=16414024 +HeapAlloc dt=5 heapalloc_value=16422216 +HeapAlloc dt=6 heapalloc_value=16430408 +HeapAlloc dt=5 heapalloc_value=16438600 +HeapAlloc dt=6 heapalloc_value=16446792 +HeapAlloc dt=5 heapalloc_value=16454984 +HeapAlloc dt=5 heapalloc_value=16463176 +HeapAlloc dt=6 heapalloc_value=16471368 +HeapAlloc dt=5 heapalloc_value=16479560 +HeapAlloc dt=5 heapalloc_value=16487752 +HeapAlloc dt=5 heapalloc_value=16495944 +HeapAlloc dt=6 heapalloc_value=16504136 +HeapAlloc dt=5 heapalloc_value=16512328 +HeapAlloc dt=45 heapalloc_value=16520520 +HeapAlloc dt=38 heapalloc_value=16528712 +HeapAlloc dt=7 heapalloc_value=16536904 +HeapAlloc dt=5 heapalloc_value=16545096 +HeapAlloc dt=5 heapalloc_value=16553288 +HeapAlloc dt=6 heapalloc_value=16561480 +HeapAlloc dt=5 heapalloc_value=16569672 +GoBlock dt=11 reason_string=19 stack=21 +ProcStop dt=109 +ProcStart dt=18122 p=2 p_seq=12 +ProcStop dt=23 +ProcStart dt=803 p=1 p_seq=12 +GoUnblock dt=12 g=24 g_seq=10 stack=0 +GoStart dt=143 g=24 g_seq=11 +GoLabel dt=2 label_string=2 +GoBlock dt=3389 reason_string=15 stack=27 +ProcStop dt=2403 +ProcStart dt=161103 p=4 p_seq=8 +GoStart dt=172 g=38 g_seq=1 +GoStop dt=304901 reason_string=16 stack=50 +GoStart dt=21 g=38 g_seq=2 +GoStop dt=315468 reason_string=16 stack=50 +GoStart dt=20 g=38 g_seq=3 +GoDestroy dt=160861 +ProcStop dt=34 +EventBatch gen=1 m=1709044 time=7689670489757 size=2312 +ProcStart dt=310 p=3 p_seq=2 +ProcStop dt=39 +ProcStart dt=1386 p=3 p_seq=3 +ProcStop dt=138 +ProcStart dt=3920 p=0 p_seq=5 +GoStart dt=266 g=24 g_seq=7 +GoUnblock dt=50 g=1 g_seq=25 stack=41 +GoBlock dt=13 reason_string=15 stack=27 +GoStart dt=7 g=1 g_seq=26 +GCMarkAssistEnd dt=6 +HeapAlloc dt=29 heapalloc_value=3843824 +GCSweepBegin dt=57 stack=42 +GCSweepEnd dt=816 swept_value=827392 reclaimed_value=0 +GCSweepBegin dt=310 stack=43 +GCSweepEnd dt=63 swept_value=67108864 reclaimed_value=0 +HeapAlloc dt=23 heapalloc_value=3852016 +HeapAlloc dt=46 heapalloc_value=3860208 +HeapAlloc dt=27 heapalloc_value=3868400 +HeapAlloc dt=16 heapalloc_value=3876592 +HeapAlloc dt=109 heapalloc_value=3884784 +HeapAlloc dt=32 heapalloc_value=3892976 +HeapAlloc dt=33 heapalloc_value=3901168 +HeapAlloc dt=26 heapalloc_value=3909360 +HeapAlloc dt=35 heapalloc_value=3917552 +HeapAlloc dt=16 heapalloc_value=3925744 +HeapAlloc dt=16 heapalloc_value=3933936 +HeapAlloc dt=16 heapalloc_value=3942128 +HeapAlloc dt=68 heapalloc_value=3950320 +HeapAlloc dt=21 heapalloc_value=3958512 +HeapAlloc dt=20 heapalloc_value=3966704 +HeapAlloc dt=15 heapalloc_value=3974896 +HeapAlloc dt=24 heapalloc_value=3983088 +HeapAlloc dt=15 heapalloc_value=3991280 +HeapAlloc dt=16 heapalloc_value=3999472 +HeapAlloc dt=15 heapalloc_value=4007664 +HeapAlloc dt=18 heapalloc_value=4015856 +HeapAlloc dt=15 heapalloc_value=4024048 +HeapAlloc dt=21 heapalloc_value=4032240 +HeapAlloc dt=26 heapalloc_value=4040432 +HeapAlloc dt=28 heapalloc_value=4048624 +HeapAlloc dt=16 heapalloc_value=4056816 +HeapAlloc dt=16 heapalloc_value=4065008 +HeapAlloc dt=16 heapalloc_value=4073200 +HeapAlloc dt=17 heapalloc_value=4081392 +HeapAlloc dt=15 heapalloc_value=4089584 +HeapAlloc dt=19 heapalloc_value=4097776 +HeapAlloc dt=15 heapalloc_value=4105968 +HeapAlloc dt=20 heapalloc_value=4114160 +HeapAlloc dt=15 heapalloc_value=4122352 +HeapAlloc dt=16 heapalloc_value=4130544 +HeapAlloc dt=16 heapalloc_value=4138736 +HeapAlloc dt=17 heapalloc_value=4146928 +HeapAlloc dt=15 heapalloc_value=4155120 +HeapAlloc dt=20 heapalloc_value=4163312 +HeapAlloc dt=18 heapalloc_value=4171504 +HeapAlloc dt=23 heapalloc_value=4179696 +HeapAlloc dt=18 heapalloc_value=4187888 +HeapAlloc dt=20 heapalloc_value=4196080 +HeapAlloc dt=19 heapalloc_value=4204272 +HeapAlloc dt=19 heapalloc_value=4212464 +HeapAlloc dt=105 heapalloc_value=4220656 +HeapAlloc dt=45 heapalloc_value=4228848 +HeapAlloc dt=22 heapalloc_value=4237040 +HeapAlloc dt=23 heapalloc_value=4245232 +HeapAlloc dt=29 heapalloc_value=4253424 +HeapAlloc dt=21 heapalloc_value=4261616 +HeapAlloc dt=56 heapalloc_value=4269808 +HeapAlloc dt=21 heapalloc_value=4278000 +HeapAlloc dt=25 heapalloc_value=4286192 +HeapAlloc dt=15 heapalloc_value=4294384 +HeapAlloc dt=60 heapalloc_value=4302576 +HeapAlloc dt=40 heapalloc_value=4359920 +HeapAlloc dt=152 heapalloc_value=4368112 +HeapAlloc dt=30 heapalloc_value=4376304 +HeapAlloc dt=27 heapalloc_value=4384496 +HeapAlloc dt=20 heapalloc_value=4392688 +HeapAlloc dt=32 heapalloc_value=4400880 +HeapAlloc dt=25 heapalloc_value=4409072 +HeapAlloc dt=48 heapalloc_value=4417264 +HeapAlloc dt=58 heapalloc_value=4425456 +HeapAlloc dt=30 heapalloc_value=4433648 +HeapAlloc dt=23 heapalloc_value=4441840 +HeapAlloc dt=16 heapalloc_value=4450032 +HeapAlloc dt=17 heapalloc_value=4458224 +HeapAlloc dt=16 heapalloc_value=4466416 +HeapAlloc dt=19 heapalloc_value=4474608 +HeapAlloc dt=16 heapalloc_value=4482800 +HeapAlloc dt=15 heapalloc_value=4490992 +HeapAlloc dt=16 heapalloc_value=4499184 +HeapAlloc dt=16 heapalloc_value=4507376 +HeapAlloc dt=15 heapalloc_value=4515568 +HeapAlloc dt=16 heapalloc_value=4523760 +HeapAlloc dt=16 heapalloc_value=4531952 +HeapAlloc dt=21 heapalloc_value=4540144 +HeapAlloc dt=25 heapalloc_value=4548336 +HeapAlloc dt=22 heapalloc_value=4556528 +HeapAlloc dt=59 heapalloc_value=4564720 +HeapAlloc dt=21 heapalloc_value=4572912 +HeapAlloc dt=16 heapalloc_value=4581104 +HeapAlloc dt=16 heapalloc_value=4589296 +HeapAlloc dt=15 heapalloc_value=4597488 +HeapAlloc dt=24 heapalloc_value=4605680 +HeapAlloc dt=12 heapalloc_value=4613872 +HeapAlloc dt=8 heapalloc_value=4622064 +HeapAlloc dt=11 heapalloc_value=4630256 +HeapAlloc dt=7 heapalloc_value=4638448 +HeapAlloc dt=7 heapalloc_value=4646640 +HeapAlloc dt=7 heapalloc_value=4654832 +GoBlock dt=31 reason_string=19 stack=21 +ProcStop dt=34 +ProcStart dt=6196 p=4 p_seq=2 +ProcStop dt=26 +ProcStart dt=1578 p=0 p_seq=7 +ProcStop dt=12 +ProcStart dt=16743 p=0 p_seq=8 +GoUnblock dt=21 g=1 g_seq=29 stack=0 +GoStart dt=147 g=1 g_seq=30 +HeapAlloc dt=51 heapalloc_value=5768944 +HeapAlloc dt=22 heapalloc_value=5777136 +HeapAlloc dt=16 heapalloc_value=5785328 +HeapAlloc dt=15 heapalloc_value=5793520 +HeapAlloc dt=16 heapalloc_value=5801712 +HeapAlloc dt=18 heapalloc_value=5809904 +HeapAlloc dt=15 heapalloc_value=5818096 +HeapAlloc dt=15 heapalloc_value=5826288 +HeapAlloc dt=12 heapalloc_value=5834480 +HeapAlloc dt=12 heapalloc_value=5842672 +HeapAlloc dt=15 heapalloc_value=5850864 +HeapAlloc dt=16 heapalloc_value=5859056 +HeapAlloc dt=12 heapalloc_value=5867248 +HeapAlloc dt=12 heapalloc_value=5875440 +HeapAlloc dt=6 heapalloc_value=5883632 +HeapAlloc dt=8 heapalloc_value=5891824 +HeapAlloc dt=6 heapalloc_value=5900016 +HeapAlloc dt=6 heapalloc_value=5908208 +HeapAlloc dt=98 heapalloc_value=5916400 +HeapAlloc dt=21 heapalloc_value=5924592 +HeapAlloc dt=5 heapalloc_value=5932784 +HeapAlloc dt=7 heapalloc_value=5940976 +HeapAlloc dt=6 heapalloc_value=5949168 +HeapAlloc dt=9 heapalloc_value=5957360 +HeapAlloc dt=6 heapalloc_value=5965552 +HeapAlloc dt=5 heapalloc_value=5973744 +HeapAlloc dt=7 heapalloc_value=5981936 +HeapAlloc dt=5 heapalloc_value=5990128 +HeapAlloc dt=6 heapalloc_value=5998320 +HeapAlloc dt=5 heapalloc_value=6006512 +HeapAlloc dt=6 heapalloc_value=6014704 +HeapAlloc dt=9 heapalloc_value=6022896 +HeapAlloc dt=5 heapalloc_value=6031088 +HeapAlloc dt=6 heapalloc_value=6039280 +HeapAlloc dt=6 heapalloc_value=6047472 +HeapAlloc dt=40 heapalloc_value=6055664 +HeapAlloc dt=6 heapalloc_value=6063856 +HeapAlloc dt=35 heapalloc_value=6072048 +HeapAlloc dt=8 heapalloc_value=6080240 +HeapAlloc dt=9 heapalloc_value=6088432 +HeapAlloc dt=5 heapalloc_value=6096624 +HeapAlloc dt=6 heapalloc_value=6104816 +HeapAlloc dt=5 heapalloc_value=6113008 +HeapAlloc dt=6 heapalloc_value=6121200 +HeapAlloc dt=6 heapalloc_value=6129392 +HeapAlloc dt=6 heapalloc_value=6137584 +HeapAlloc dt=5 heapalloc_value=6145776 +HeapAlloc dt=9 heapalloc_value=6153968 +HeapAlloc dt=5 heapalloc_value=6162160 +HeapAlloc dt=6 heapalloc_value=6170352 +HeapAlloc dt=6 heapalloc_value=6178544 +HeapAlloc dt=8 heapalloc_value=6186736 +HeapAlloc dt=11 heapalloc_value=6301424 +HeapAlloc dt=2483 heapalloc_value=6309616 +HeapAlloc dt=9 heapalloc_value=6317808 +HeapAlloc dt=7 heapalloc_value=6326000 +HeapAlloc dt=11 heapalloc_value=6334192 +HeapAlloc dt=6 heapalloc_value=6342384 +HeapAlloc dt=6 heapalloc_value=6350576 +HeapAlloc dt=6 heapalloc_value=6358768 +HeapAlloc dt=7 heapalloc_value=6366960 +HeapAlloc dt=9 heapalloc_value=6375152 +HeapAlloc dt=5 heapalloc_value=6383344 +HeapAlloc dt=6 heapalloc_value=6391536 +HeapAlloc dt=6 heapalloc_value=6399728 +HeapAlloc dt=5 heapalloc_value=6407920 +HeapAlloc dt=5 heapalloc_value=6416112 +HeapAlloc dt=6 heapalloc_value=6424304 +HeapAlloc dt=9 heapalloc_value=6432496 +HeapAlloc dt=8 heapalloc_value=6440688 +HeapAlloc dt=9 heapalloc_value=6448880 +HeapAlloc dt=6 heapalloc_value=6457072 +HeapAlloc dt=13 heapalloc_value=6465264 +HeapAlloc dt=6 heapalloc_value=6473456 +HeapAlloc dt=5 heapalloc_value=6481648 +HeapAlloc dt=6 heapalloc_value=6489840 +HeapAlloc dt=5 heapalloc_value=6498032 +HeapAlloc dt=6 heapalloc_value=6506224 +HeapAlloc dt=8 heapalloc_value=6514416 +HeapAlloc dt=6 heapalloc_value=6522608 +HeapAlloc dt=6 heapalloc_value=6530800 +HeapAlloc dt=5 heapalloc_value=6538992 +HeapAlloc dt=81 heapalloc_value=6547184 +HeapAlloc dt=7 heapalloc_value=6555376 +HeapAlloc dt=6 heapalloc_value=6563568 +HeapAlloc dt=5 heapalloc_value=6571760 +HeapAlloc dt=20 heapalloc_value=6579952 +HeapAlloc dt=6 heapalloc_value=6588144 +HeapAlloc dt=56 heapalloc_value=6596336 +HeapAlloc dt=7 heapalloc_value=6604528 +HeapAlloc dt=7 heapalloc_value=6612720 +HeapAlloc dt=6 heapalloc_value=6620912 +HeapAlloc dt=5 heapalloc_value=6629104 +HeapAlloc dt=5 heapalloc_value=6637296 +HeapAlloc dt=6 heapalloc_value=6645488 +HeapAlloc dt=5 heapalloc_value=6653680 +HeapAlloc dt=5 heapalloc_value=6661872 +HeapAlloc dt=6 heapalloc_value=6670064 +HeapAlloc dt=5 heapalloc_value=6678256 +HeapAlloc dt=5 heapalloc_value=6686448 +HeapAlloc dt=6 heapalloc_value=6694640 +HeapAlloc dt=5 heapalloc_value=6702832 +HeapAlloc dt=5 heapalloc_value=6711024 +HeapAlloc dt=6 heapalloc_value=6719216 +HeapAlloc dt=9 heapalloc_value=6727408 +HeapAlloc dt=7 heapalloc_value=6735600 +HeapAlloc dt=5 heapalloc_value=6743792 +HeapAlloc dt=5 heapalloc_value=6751984 +HeapAlloc dt=6 heapalloc_value=6760176 +HeapAlloc dt=5 heapalloc_value=6768368 +HeapAlloc dt=5 heapalloc_value=6776560 +HeapAlloc dt=6 heapalloc_value=6784752 +HeapAlloc dt=5 heapalloc_value=6792944 +HeapAlloc dt=6 heapalloc_value=6801136 +HeapAlloc dt=36 heapalloc_value=6809328 +HeapAlloc dt=7 heapalloc_value=6817520 +HeapAlloc dt=5 heapalloc_value=6825712 +HeapAlloc dt=6 heapalloc_value=6833904 +HeapAlloc dt=6 heapalloc_value=6842096 +HeapAlloc dt=5 heapalloc_value=6850288 +HeapAlloc dt=6 heapalloc_value=6858480 +HeapAlloc dt=5 heapalloc_value=6866672 +HeapAlloc dt=5 heapalloc_value=6874864 +HeapAlloc dt=5 heapalloc_value=6883056 +HeapAlloc dt=5 heapalloc_value=6891248 +HeapAlloc dt=6 heapalloc_value=6899440 +GoBlock dt=14 reason_string=19 stack=21 +ProcStop dt=198 +ProcStart dt=2996 p=0 p_seq=10 +GoUnblock dt=12 g=1 g_seq=31 stack=0 +GoStart dt=135 g=1 g_seq=32 +HeapAlloc dt=25 heapalloc_value=6907632 +HeapAlloc dt=9 heapalloc_value=6915824 +HeapAlloc dt=6 heapalloc_value=6924016 +HeapAlloc dt=5 heapalloc_value=6932208 +HeapAlloc dt=6 heapalloc_value=6940400 +HeapAlloc dt=5 heapalloc_value=6948592 +HeapAlloc dt=5 heapalloc_value=6956784 +HeapAlloc dt=6 heapalloc_value=6964976 +HeapAlloc dt=5 heapalloc_value=6973168 +HeapAlloc dt=6 heapalloc_value=6981360 +HeapAlloc dt=5 heapalloc_value=6989552 +HeapAlloc dt=5 heapalloc_value=6997744 +HeapAlloc dt=5 heapalloc_value=7005936 +HeapAlloc dt=97 heapalloc_value=7014128 +HeapAlloc dt=7 heapalloc_value=7022320 +HeapAlloc dt=5 heapalloc_value=7030512 +HeapAlloc dt=6 heapalloc_value=7038704 +HeapAlloc dt=5 heapalloc_value=7046896 +HeapAlloc dt=5 heapalloc_value=7055088 +HeapAlloc dt=5 heapalloc_value=7063280 +HeapAlloc dt=50 heapalloc_value=7071472 +HeapAlloc dt=7 heapalloc_value=7079664 +HeapAlloc dt=6 heapalloc_value=7087856 +HeapAlloc dt=5 heapalloc_value=7096048 +HeapAlloc dt=20 heapalloc_value=7104240 +HeapAlloc dt=6 heapalloc_value=7112432 +HeapAlloc dt=8 heapalloc_value=7120624 +HeapAlloc dt=6 heapalloc_value=7128816 +HeapAlloc dt=5 heapalloc_value=7137008 +HeapAlloc dt=6 heapalloc_value=7145200 +HeapAlloc dt=8 heapalloc_value=7153392 +HeapAlloc dt=6 heapalloc_value=7161584 +HeapAlloc dt=5 heapalloc_value=7169776 +HeapAlloc dt=5 heapalloc_value=7177968 +HeapAlloc dt=6 heapalloc_value=7186160 +HeapAlloc dt=5 heapalloc_value=7194352 +HeapAlloc dt=5 heapalloc_value=7202544 +HeapAlloc dt=6 heapalloc_value=7210736 +HeapAlloc dt=5 heapalloc_value=7218928 +HeapAlloc dt=35 heapalloc_value=7227120 +HeapAlloc dt=10 heapalloc_value=7235312 +HeapAlloc dt=5 heapalloc_value=7243504 +HeapAlloc dt=5 heapalloc_value=7251696 +HeapAlloc dt=6 heapalloc_value=7259888 +HeapAlloc dt=5 heapalloc_value=7268080 +HeapAlloc dt=5 heapalloc_value=7276272 +HeapAlloc dt=5 heapalloc_value=7284464 +HeapAlloc dt=6 heapalloc_value=7292656 +HeapAlloc dt=6 heapalloc_value=7300848 +HeapAlloc dt=5 heapalloc_value=7309040 +HeapAlloc dt=13 heapalloc_value=7317232 +HeapAlloc dt=5 heapalloc_value=7325424 +HeapAlloc dt=6 heapalloc_value=7333616 +HeapAlloc dt=8 heapalloc_value=7341808 +HeapAlloc dt=5 heapalloc_value=7350000 +HeapAlloc dt=9 heapalloc_value=7358192 +HeapAlloc dt=5 heapalloc_value=7366384 +HeapAlloc dt=6 heapalloc_value=7374576 +HeapAlloc dt=5 heapalloc_value=7382768 +HeapAlloc dt=5 heapalloc_value=7390960 +HeapAlloc dt=5 heapalloc_value=7399152 +HeapAlloc dt=6 heapalloc_value=7407344 +HeapAlloc dt=5 heapalloc_value=7415536 +HeapAlloc dt=5 heapalloc_value=7423728 +HeapAlloc dt=6 heapalloc_value=7431920 +HeapAlloc dt=5 heapalloc_value=7440112 +HeapAlloc dt=5 heapalloc_value=7448304 +HeapAlloc dt=5 heapalloc_value=7456496 +HeapAlloc dt=6 heapalloc_value=7464688 +HeapAlloc dt=5 heapalloc_value=7472880 +HeapAlloc dt=5 heapalloc_value=7481072 +HeapAlloc dt=5 heapalloc_value=7489264 +HeapAlloc dt=6 heapalloc_value=7497456 +HeapAlloc dt=5 heapalloc_value=7505648 +HeapAlloc dt=5 heapalloc_value=7513840 +HeapAlloc dt=5 heapalloc_value=7522032 +HeapAlloc dt=5 heapalloc_value=7530224 +HeapAlloc dt=6 heapalloc_value=7538416 +HeapAlloc dt=5 heapalloc_value=7546608 +HeapAlloc dt=6 heapalloc_value=7554800 +HeapAlloc dt=5 heapalloc_value=7562992 +HeapAlloc dt=5 heapalloc_value=7571184 +HeapAlloc dt=6 heapalloc_value=7579376 +HeapAlloc dt=5 heapalloc_value=7587568 +HeapAlloc dt=45 heapalloc_value=7595760 +HeapAlloc dt=7 heapalloc_value=7603952 +HeapAlloc dt=5 heapalloc_value=7612144 +HeapAlloc dt=6 heapalloc_value=7620336 +HeapAlloc dt=376 heapalloc_value=7628528 +HeapAlloc dt=13 heapalloc_value=7636720 +HeapAlloc dt=7 heapalloc_value=7644912 +HeapAlloc dt=35 heapalloc_value=7653104 +GCBegin dt=23 gc_seq=3 stack=22 +STWBegin dt=73 kind_string=22 stack=28 +GoUnblock dt=258 g=4 g_seq=5 stack=29 +ProcsChange dt=80 procs_value=8 stack=30 +STWEnd dt=37 +GCMarkAssistBegin dt=96 stack=31 +GCMarkAssistEnd dt=4606 +HeapAlloc dt=187 heapalloc_value=7671600 +HeapAlloc dt=26 heapalloc_value=7679792 +HeapAlloc dt=17 heapalloc_value=7687984 +HeapAlloc dt=29 heapalloc_value=7696176 +HeapAlloc dt=16 heapalloc_value=7704368 +HeapAlloc dt=12 heapalloc_value=7712560 +HeapAlloc dt=48 heapalloc_value=7868208 +GoStop dt=4635 reason_string=16 stack=45 +GoStart dt=48 g=1 g_seq=33 +HeapAlloc dt=27 heapalloc_value=7884336 +HeapAlloc dt=11 heapalloc_value=7892528 +HeapAlloc dt=8 heapalloc_value=7900720 +HeapAlloc dt=12 heapalloc_value=7908912 +HeapAlloc dt=9 heapalloc_value=7917104 +HeapAlloc dt=9 heapalloc_value=7925296 +HeapAlloc dt=9 heapalloc_value=7933488 +HeapAlloc dt=8 heapalloc_value=7941680 +HeapAlloc dt=10 heapalloc_value=7949872 +HeapAlloc dt=8 heapalloc_value=7958064 +HeapAlloc dt=10 heapalloc_value=7966256 +HeapAlloc dt=12 heapalloc_value=7974448 +HeapAlloc dt=8 heapalloc_value=7982640 +HeapAlloc dt=8 heapalloc_value=7990832 +HeapAlloc dt=9 heapalloc_value=7999024 +HeapAlloc dt=8 heapalloc_value=8007216 +HeapAlloc dt=54 heapalloc_value=8015408 +HeapAlloc dt=10 heapalloc_value=8023600 +HeapAlloc dt=8 heapalloc_value=8031792 +HeapAlloc dt=9 heapalloc_value=8039984 +HeapAlloc dt=8 heapalloc_value=8048176 +HeapAlloc dt=9 heapalloc_value=8056368 +HeapAlloc dt=8 heapalloc_value=8064560 +HeapAlloc dt=9 heapalloc_value=8072752 +HeapAlloc dt=8 heapalloc_value=8080944 +HeapAlloc dt=9 heapalloc_value=8089136 +HeapAlloc dt=8 heapalloc_value=8097328 +GoBlock dt=20 reason_string=19 stack=21 +ProcStop dt=35 +ProcStart dt=147580 p=3 p_seq=6 +GoStart dt=144 g=4 g_seq=10 +GoBlock dt=38 reason_string=15 stack=32 +GoUnblock dt=41 g=25 g_seq=4 stack=0 +GoStart dt=6 g=25 g_seq=5 +GoLabel dt=1 label_string=4 +GoBlock dt=5825 reason_string=15 stack=27 +ProcStop dt=299 +ProcStart dt=158874 p=3 p_seq=7 +GoStart dt=231 g=35 g_seq=1 +GoStop dt=305629 reason_string=16 stack=51 +GoStart dt=79 g=35 g_seq=2 +GoStop dt=315206 reason_string=16 stack=50 +GoStart dt=36 g=35 g_seq=3 +GoDestroy dt=160337 +ProcStop dt=68 +EventBatch gen=1 m=1709042 time=7689670149213 size=4550 +ProcStart dt=287 p=2 p_seq=1 +GoStart dt=328 g=7 g_seq=1 +HeapAlloc dt=7006 heapalloc_value=2793472 +HeapAlloc dt=74 heapalloc_value=2801664 +GoBlock dt=275 reason_string=12 stack=18 +ProcStop dt=34 +ProcStart dt=327698 p=0 p_seq=3 +ProcStop dt=7 +ProcStart dt=2124 p=2 p_seq=3 +GoUnblock dt=32 g=24 g_seq=2 stack=0 +HeapAlloc dt=302 heapalloc_value=4038656 +HeapAlloc dt=104 heapalloc_value=4046848 +HeapAlloc dt=52 heapalloc_value=4055040 +GoStart dt=1147 g=24 g_seq=3 +GoLabel dt=5 label_string=2 +GoBlock dt=128 reason_string=15 stack=27 +GoUnblock dt=72 g=1 g_seq=21 stack=0 +GoStart dt=11 g=1 g_seq=22 +HeapAlloc dt=44 heapalloc_value=4063232 +HeapAlloc dt=43 heapalloc_value=4071424 +HeapAlloc dt=28 heapalloc_value=4079616 +HeapAlloc dt=24 heapalloc_value=4087808 +HeapAlloc dt=84 heapalloc_value=4096000 +HeapAlloc dt=25 heapalloc_value=4104192 +HeapAlloc dt=20 heapalloc_value=4112384 +HeapAlloc dt=24 heapalloc_value=4120576 +HeapAlloc dt=20 heapalloc_value=4128768 +HeapAlloc dt=19 heapalloc_value=4136960 +HeapAlloc dt=24 heapalloc_value=4145152 +HeapAlloc dt=20 heapalloc_value=4153344 +HeapAlloc dt=19 heapalloc_value=4161536 +HeapAlloc dt=20 heapalloc_value=4169728 +HeapAlloc dt=24 heapalloc_value=4177920 +HeapAlloc dt=33 heapalloc_value=4186112 +HeapAlloc dt=26 heapalloc_value=4194304 +HeapAlloc dt=31 heapalloc_value=4235264 +HeapAlloc dt=363 heapalloc_value=4243456 +HeapAlloc dt=61 heapalloc_value=4251648 +HeapAlloc dt=14 heapalloc_value=4259840 +HeapAlloc dt=12 heapalloc_value=4268032 +HeapAlloc dt=9 heapalloc_value=4276224 +HeapAlloc dt=9 heapalloc_value=4284416 +HeapAlloc dt=9 heapalloc_value=4292608 +HeapAlloc dt=8 heapalloc_value=4300800 +HeapAlloc dt=162 heapalloc_value=4308992 +HeapAlloc dt=14 heapalloc_value=4317184 +HeapAlloc dt=8 heapalloc_value=4325376 +HeapAlloc dt=53 heapalloc_value=4333568 +HeapAlloc dt=10 heapalloc_value=4341760 +HeapAlloc dt=16 heapalloc_value=4349952 +HeapAlloc dt=14 heapalloc_value=4358144 +GCMarkAssistBegin dt=27 stack=31 +GCMarkAssistEnd dt=18 +GCMarkAssistBegin dt=4 stack=31 +GoBlock dt=198 reason_string=13 stack=33 +ProcStop dt=19 +ProcStart dt=387 p=2 p_seq=4 +GoUnblock dt=265 g=24 g_seq=4 stack=0 +GoStart dt=69 g=24 g_seq=5 +GoLabel dt=1 label_string=2 +GoBlock dt=132 reason_string=10 stack=35 +GoStart dt=20 g=1 g_seq=24 +GCMarkAssistEnd dt=2 +HeapAlloc dt=13 heapalloc_value=4366336 +GCMarkAssistBegin dt=7 stack=31 +GoBlock dt=25 reason_string=10 stack=36 +ProcStop dt=24 +ProcStart dt=4689 p=1 p_seq=7 +ProcStop dt=23 +ProcStart dt=36183 p=1 p_seq=8 +ProcStop dt=24 +ProcStart dt=1076 p=1 p_seq=9 +GoUnblock dt=12 g=22 g_seq=4 stack=0 +GoStart dt=118 g=22 g_seq=5 +GoLabel dt=1 label_string=2 +GoBlock dt=7117 reason_string=15 stack=27 +ProcStop dt=41 +ProcStart dt=150567 p=4 p_seq=7 +GoUnblock dt=41 g=23 g_seq=4 stack=0 +HeapAlloc dt=108 heapalloc_value=17163592 +HeapAlloc dt=61 heapalloc_value=17166856 +HeapAlloc dt=2994 heapalloc_value=17608712 +GoStart dt=1008 g=23 g_seq=5 +GoLabel dt=4 label_string=4 +GoBlock dt=40 reason_string=15 stack=27 +GoUnblock dt=49 g=1 g_seq=52 stack=0 +GoStart dt=7 g=1 g_seq=53 +HeapAlloc dt=30 heapalloc_value=17616904 +HeapAlloc dt=52 heapalloc_value=17625096 +HeapAlloc dt=35 heapalloc_value=17633288 +HeapAlloc dt=27 heapalloc_value=17641480 +HeapAlloc dt=28 heapalloc_value=17649672 +HeapAlloc dt=87 heapalloc_value=17657864 +HeapAlloc dt=32 heapalloc_value=17666056 +HeapAlloc dt=24 heapalloc_value=17674248 +HeapAlloc dt=22 heapalloc_value=17682440 +HeapAlloc dt=16 heapalloc_value=17690632 +HeapAlloc dt=15 heapalloc_value=17698824 +HeapAlloc dt=20 heapalloc_value=17707016 +HeapAlloc dt=19 heapalloc_value=17715208 +HeapAlloc dt=15 heapalloc_value=17723400 +HeapAlloc dt=18 heapalloc_value=17731592 +HeapAlloc dt=20 heapalloc_value=17739784 +HeapAlloc dt=15 heapalloc_value=17747976 +HeapAlloc dt=17 heapalloc_value=17756168 +HeapAlloc dt=67 heapalloc_value=17764360 +HeapAlloc dt=28 heapalloc_value=17772552 +HeapAlloc dt=22 heapalloc_value=17780744 +HeapAlloc dt=19 heapalloc_value=17788936 +HeapAlloc dt=22 heapalloc_value=17797128 +HeapAlloc dt=19 heapalloc_value=17805320 +HeapAlloc dt=19 heapalloc_value=17813512 +HeapAlloc dt=19 heapalloc_value=17821704 +HeapAlloc dt=15 heapalloc_value=17829896 +HeapAlloc dt=21 heapalloc_value=17838088 +HeapAlloc dt=19 heapalloc_value=17846280 +HeapAlloc dt=16 heapalloc_value=17854472 +HeapAlloc dt=14 heapalloc_value=17862664 +HeapAlloc dt=18 heapalloc_value=17870856 +HeapAlloc dt=58 heapalloc_value=17879048 +HeapAlloc dt=19 heapalloc_value=17887240 +HeapAlloc dt=15 heapalloc_value=17895432 +HeapAlloc dt=19 heapalloc_value=17903624 +HeapAlloc dt=21 heapalloc_value=17911816 +HeapAlloc dt=17 heapalloc_value=17920008 +HeapAlloc dt=19 heapalloc_value=17928200 +HeapAlloc dt=19 heapalloc_value=17936392 +HeapAlloc dt=16 heapalloc_value=17944584 +HeapAlloc dt=15 heapalloc_value=17952776 +HeapAlloc dt=15 heapalloc_value=17960968 +HeapAlloc dt=19 heapalloc_value=17969160 +HeapAlloc dt=16 heapalloc_value=17977352 +HeapAlloc dt=16 heapalloc_value=17985544 +HeapAlloc dt=16 heapalloc_value=17993736 +HeapAlloc dt=19 heapalloc_value=18001928 +HeapAlloc dt=15 heapalloc_value=18010120 +HeapAlloc dt=16 heapalloc_value=18018312 +HeapAlloc dt=15 heapalloc_value=18026504 +HeapAlloc dt=19 heapalloc_value=18034696 +HeapAlloc dt=14 heapalloc_value=18042888 +HeapAlloc dt=17 heapalloc_value=18051080 +HeapAlloc dt=18 heapalloc_value=18059272 +HeapAlloc dt=20 heapalloc_value=18067464 +HeapAlloc dt=17 heapalloc_value=18075656 +HeapAlloc dt=125 heapalloc_value=18083848 +GoStop dt=20 reason_string=16 stack=46 +GoUnblock dt=288 g=25 g_seq=6 stack=0 +GoStart dt=7 g=25 g_seq=7 +GoLabel dt=1 label_string=2 +HeapAlloc dt=255 heapalloc_value=18091752 +GoBlock dt=30 reason_string=10 stack=35 +GoStart dt=5 g=1 g_seq=54 +HeapAlloc dt=25 heapalloc_value=18099944 +HeapAlloc dt=19 heapalloc_value=18108136 +HeapAlloc dt=45 heapalloc_value=18116328 +HeapAlloc dt=9 heapalloc_value=18124520 +HeapAlloc dt=80 heapalloc_value=18132712 +HeapAlloc dt=11 heapalloc_value=18140904 +HeapAlloc dt=6 heapalloc_value=18149096 +HeapAlloc dt=7 heapalloc_value=18157288 +HeapAlloc dt=7 heapalloc_value=18165480 +HeapAlloc dt=12 heapalloc_value=18173672 +HeapAlloc dt=11 heapalloc_value=18181864 +HeapAlloc dt=11 heapalloc_value=18190056 +HeapAlloc dt=7 heapalloc_value=18198248 +HeapAlloc dt=62 heapalloc_value=18206440 +HeapAlloc dt=8 heapalloc_value=18214632 +HeapAlloc dt=7 heapalloc_value=18222824 +HeapAlloc dt=6 heapalloc_value=18231016 +HeapAlloc dt=7 heapalloc_value=18239208 +HeapAlloc dt=11 heapalloc_value=18247400 +HeapAlloc dt=6 heapalloc_value=18255592 +HeapAlloc dt=7 heapalloc_value=18263784 +HeapAlloc dt=11 heapalloc_value=18271976 +HeapAlloc dt=6 heapalloc_value=18280168 +HeapAlloc dt=7 heapalloc_value=18288360 +HeapAlloc dt=7 heapalloc_value=18296552 +HeapAlloc dt=6 heapalloc_value=18304744 +HeapAlloc dt=10 heapalloc_value=18312936 +HeapAlloc dt=7 heapalloc_value=18321128 +HeapAlloc dt=7 heapalloc_value=18329320 +HeapAlloc dt=7 heapalloc_value=18337512 +HeapAlloc dt=31 heapalloc_value=18345704 +HeapAlloc dt=17 heapalloc_value=18353896 +HeapAlloc dt=7 heapalloc_value=18362088 +HeapAlloc dt=13 heapalloc_value=18370280 +HeapAlloc dt=6 heapalloc_value=18378472 +HeapAlloc dt=7 heapalloc_value=18386664 +HeapAlloc dt=7 heapalloc_value=18394856 +HeapAlloc dt=11 heapalloc_value=18403048 +HeapAlloc dt=6 heapalloc_value=18411240 +HeapAlloc dt=7 heapalloc_value=18419432 +HeapAlloc dt=7 heapalloc_value=18427624 +HeapAlloc dt=6 heapalloc_value=18435816 +HeapAlloc dt=7 heapalloc_value=18444008 +HeapAlloc dt=7 heapalloc_value=18452200 +GCMarkAssistBegin dt=13 stack=31 +GoBlock dt=35 reason_string=10 stack=36 +ProcStop dt=22 +ProcStart dt=936 p=1 p_seq=13 +GoStart dt=212 g=25 g_seq=9 +GoUnblock dt=31 g=1 g_seq=55 stack=41 +GoBlock dt=7 reason_string=15 stack=27 +GoStart dt=13 g=1 g_seq=56 +GCMarkAssistEnd dt=4 +HeapAlloc dt=30 heapalloc_value=16971400 +GCSweepBegin dt=41 stack=42 +GCSweepEnd dt=310 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=23 heapalloc_value=16979592 +GCSweepBegin dt=30 stack=42 +GCSweepEnd dt=934 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=80 heapalloc_value=16987784 +GCSweepBegin dt=43 stack=42 +GCSweepEnd dt=1671 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=6 heapalloc_value=16995976 +GCSweepBegin dt=41 stack=42 +GCSweepEnd dt=1680 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=13 heapalloc_value=17004168 +GCSweepBegin dt=44 stack=42 +GCSweepEnd dt=1555 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=12 heapalloc_value=17012360 +GCSweepBegin dt=46 stack=42 +GCSweepEnd dt=1914 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=16 heapalloc_value=17020552 +GCSweepBegin dt=47 stack=42 +GCSweepEnd dt=1545 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=10 heapalloc_value=17028744 +GCSweepBegin dt=37 stack=42 +GCSweepEnd dt=1763 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=9 heapalloc_value=17036936 +GCSweepBegin dt=37 stack=42 +GCSweepEnd dt=1712 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=18 heapalloc_value=17045128 +GCSweepBegin dt=34 stack=42 +GCSweepEnd dt=1009 swept_value=466944 reclaimed_value=0 +HeapAlloc dt=9 heapalloc_value=17053320 +HeapAlloc dt=28 heapalloc_value=17061512 +HeapAlloc dt=25 heapalloc_value=17069704 +HeapAlloc dt=34 heapalloc_value=17077896 +HeapAlloc dt=39 heapalloc_value=17086088 +HeapAlloc dt=72 heapalloc_value=17094280 +HeapAlloc dt=32 heapalloc_value=17102472 +HeapAlloc dt=16 heapalloc_value=17110664 +HeapAlloc dt=15 heapalloc_value=17118856 +HeapAlloc dt=14 heapalloc_value=17127048 +HeapAlloc dt=16 heapalloc_value=17135240 +HeapAlloc dt=15 heapalloc_value=17143432 +HeapAlloc dt=19 heapalloc_value=17151624 +HeapAlloc dt=15 heapalloc_value=17159816 +HeapAlloc dt=54 heapalloc_value=17585800 +GoBlock dt=482 reason_string=19 stack=21 +ProcStop dt=210 +ProcStart dt=17621 p=0 p_seq=26 +ProcStop dt=24 +ProcStart dt=5194 p=1 p_seq=16 +ProcStop dt=17 +ProcStart dt=16724 p=1 p_seq=17 +GoUnblock dt=27 g=1 g_seq=59 stack=0 +GoStart dt=127 g=1 g_seq=60 +HeapAlloc dt=55 heapalloc_value=18617992 +HeapAlloc dt=64 heapalloc_value=18626184 +HeapAlloc dt=65 heapalloc_value=18634376 +HeapAlloc dt=61 heapalloc_value=18642568 +HeapAlloc dt=54 heapalloc_value=18650760 +HeapAlloc dt=66 heapalloc_value=18658952 +HeapAlloc dt=67 heapalloc_value=18667144 +HeapAlloc dt=54 heapalloc_value=18675336 +HeapAlloc dt=57 heapalloc_value=18683528 +HeapAlloc dt=45 heapalloc_value=18691720 +HeapAlloc dt=84 heapalloc_value=18699912 +HeapAlloc dt=26 heapalloc_value=18708104 +HeapAlloc dt=18 heapalloc_value=18716296 +HeapAlloc dt=15 heapalloc_value=18724488 +HeapAlloc dt=24 heapalloc_value=18732680 +HeapAlloc dt=26 heapalloc_value=18740872 +HeapAlloc dt=21 heapalloc_value=18749064 +HeapAlloc dt=15 heapalloc_value=18757256 +HeapAlloc dt=31 heapalloc_value=18765448 +HeapAlloc dt=7 heapalloc_value=18773640 +HeapAlloc dt=7 heapalloc_value=18781832 +HeapAlloc dt=113 heapalloc_value=18790024 +HeapAlloc dt=8 heapalloc_value=18798216 +HeapAlloc dt=6 heapalloc_value=18806408 +HeapAlloc dt=7 heapalloc_value=18814600 +HeapAlloc dt=6 heapalloc_value=18822792 +HeapAlloc dt=6 heapalloc_value=18830984 +HeapAlloc dt=7 heapalloc_value=18839176 +HeapAlloc dt=6 heapalloc_value=18847368 +HeapAlloc dt=6 heapalloc_value=18855560 +HeapAlloc dt=6 heapalloc_value=18863752 +HeapAlloc dt=6 heapalloc_value=18871944 +HeapAlloc dt=6 heapalloc_value=18880136 +HeapAlloc dt=6 heapalloc_value=18888328 +HeapAlloc dt=6 heapalloc_value=18896520 +HeapAlloc dt=7 heapalloc_value=18904712 +HeapAlloc dt=6 heapalloc_value=18912904 +HeapAlloc dt=38 heapalloc_value=18921096 +HeapAlloc dt=7 heapalloc_value=18929288 +HeapAlloc dt=6 heapalloc_value=18937480 +HeapAlloc dt=14 heapalloc_value=18945672 +HeapAlloc dt=6 heapalloc_value=18953864 +HeapAlloc dt=6 heapalloc_value=18962056 +HeapAlloc dt=6 heapalloc_value=18970248 +HeapAlloc dt=7 heapalloc_value=18978440 +HeapAlloc dt=6 heapalloc_value=18986632 +HeapAlloc dt=6 heapalloc_value=18994824 +HeapAlloc dt=13 heapalloc_value=19003016 +HeapAlloc dt=7 heapalloc_value=19011208 +HeapAlloc dt=6 heapalloc_value=19019400 +HeapAlloc dt=6 heapalloc_value=19027592 +HeapAlloc dt=6 heapalloc_value=19035784 +HeapAlloc dt=7 heapalloc_value=19043976 +HeapAlloc dt=6 heapalloc_value=19052168 +HeapAlloc dt=6 heapalloc_value=19060360 +HeapAlloc dt=6 heapalloc_value=19068552 +HeapAlloc dt=6 heapalloc_value=19076744 +HeapAlloc dt=7 heapalloc_value=19084936 +HeapAlloc dt=6 heapalloc_value=19093128 +HeapAlloc dt=6 heapalloc_value=19101320 +HeapAlloc dt=6 heapalloc_value=19109512 +HeapAlloc dt=7 heapalloc_value=19117704 +HeapAlloc dt=5 heapalloc_value=19125896 +HeapAlloc dt=7 heapalloc_value=19134088 +HeapAlloc dt=6 heapalloc_value=19142280 +HeapAlloc dt=6 heapalloc_value=19150472 +HeapAlloc dt=6 heapalloc_value=19158664 +HeapAlloc dt=6 heapalloc_value=19166856 +HeapAlloc dt=7 heapalloc_value=19175048 +HeapAlloc dt=6 heapalloc_value=19183240 +HeapAlloc dt=6 heapalloc_value=19191432 +HeapAlloc dt=6 heapalloc_value=19199624 +HeapAlloc dt=7 heapalloc_value=19207816 +HeapAlloc dt=6 heapalloc_value=19216008 +HeapAlloc dt=6 heapalloc_value=19224200 +HeapAlloc dt=6 heapalloc_value=19232392 +HeapAlloc dt=7 heapalloc_value=19240584 +HeapAlloc dt=6 heapalloc_value=19248776 +HeapAlloc dt=6 heapalloc_value=19256968 +HeapAlloc dt=6 heapalloc_value=19265160 +HeapAlloc dt=6 heapalloc_value=19273352 +HeapAlloc dt=6 heapalloc_value=19281544 +HeapAlloc dt=6 heapalloc_value=19289736 +HeapAlloc dt=7 heapalloc_value=19297928 +HeapAlloc dt=6 heapalloc_value=19306120 +HeapAlloc dt=62 heapalloc_value=19314312 +HeapAlloc dt=7 heapalloc_value=19322504 +HeapAlloc dt=6 heapalloc_value=19330696 +HeapAlloc dt=6 heapalloc_value=19338888 +HeapAlloc dt=35 heapalloc_value=19347080 +HeapAlloc dt=7 heapalloc_value=19355272 +HeapAlloc dt=6 heapalloc_value=19363464 +HeapAlloc dt=6 heapalloc_value=19371656 +HeapAlloc dt=6 heapalloc_value=19379848 +HeapAlloc dt=6 heapalloc_value=19388040 +HeapAlloc dt=6 heapalloc_value=19396232 +HeapAlloc dt=7 heapalloc_value=19404424 +HeapAlloc dt=6 heapalloc_value=19412616 +HeapAlloc dt=7 heapalloc_value=19420808 +HeapAlloc dt=6 heapalloc_value=19429000 +HeapAlloc dt=6 heapalloc_value=19437192 +HeapAlloc dt=6 heapalloc_value=19445384 +HeapAlloc dt=7 heapalloc_value=19453576 +HeapAlloc dt=6 heapalloc_value=19461768 +HeapAlloc dt=10 heapalloc_value=19469960 +HeapAlloc dt=6 heapalloc_value=19478152 +HeapAlloc dt=6 heapalloc_value=19486344 +HeapAlloc dt=6 heapalloc_value=19494536 +HeapAlloc dt=6 heapalloc_value=19502728 +HeapAlloc dt=7 heapalloc_value=19510920 +HeapAlloc dt=6 heapalloc_value=19519112 +HeapAlloc dt=6 heapalloc_value=19527304 +HeapAlloc dt=6 heapalloc_value=19535496 +HeapAlloc dt=6 heapalloc_value=19543688 +HeapAlloc dt=35 heapalloc_value=19551880 +HeapAlloc dt=7 heapalloc_value=19560072 +HeapAlloc dt=6 heapalloc_value=19568264 +HeapAlloc dt=6 heapalloc_value=19576456 +HeapAlloc dt=6 heapalloc_value=19584648 +HeapAlloc dt=7 heapalloc_value=19592840 +HeapAlloc dt=7 heapalloc_value=19601032 +HeapAlloc dt=6 heapalloc_value=19609224 +HeapAlloc dt=6 heapalloc_value=19617416 +HeapAlloc dt=6 heapalloc_value=19625608 +HeapAlloc dt=6 heapalloc_value=19633800 +GoBlock dt=12 reason_string=19 stack=21 +ProcStop dt=171 +ProcStart dt=17527 p=0 p_seq=28 +ProcStop dt=24 +ProcStart dt=1830 p=1 p_seq=20 +ProcStop dt=13 +ProcStart dt=16742 p=1 p_seq=21 +GoUnblock dt=20 g=1 g_seq=63 stack=0 +GoStart dt=121 g=1 g_seq=64 +HeapAlloc dt=62 heapalloc_value=20665992 +HeapAlloc dt=21 heapalloc_value=20674184 +HeapAlloc dt=25 heapalloc_value=20682376 +HeapAlloc dt=20 heapalloc_value=20690568 +HeapAlloc dt=12 heapalloc_value=20698760 +HeapAlloc dt=16 heapalloc_value=20706952 +HeapAlloc dt=15 heapalloc_value=20715144 +HeapAlloc dt=18 heapalloc_value=20723336 +HeapAlloc dt=12 heapalloc_value=20731528 +HeapAlloc dt=16 heapalloc_value=20739720 +HeapAlloc dt=12 heapalloc_value=20747912 +HeapAlloc dt=12 heapalloc_value=20756104 +HeapAlloc dt=12 heapalloc_value=20764296 +HeapAlloc dt=12 heapalloc_value=20772488 +HeapAlloc dt=9 heapalloc_value=20780680 +HeapAlloc dt=5 heapalloc_value=20788872 +HeapAlloc dt=6 heapalloc_value=20797064 +HeapAlloc dt=9 heapalloc_value=20805256 +HeapAlloc dt=5 heapalloc_value=20813448 +HeapAlloc dt=6 heapalloc_value=20821640 +HeapAlloc dt=5 heapalloc_value=20829832 +HeapAlloc dt=6 heapalloc_value=20838024 +HeapAlloc dt=15 heapalloc_value=20846216 +HeapAlloc dt=12 heapalloc_value=20854408 +HeapAlloc dt=11 heapalloc_value=20862600 +HeapAlloc dt=13 heapalloc_value=20870792 +HeapAlloc dt=5 heapalloc_value=20878984 +HeapAlloc dt=106 heapalloc_value=20887176 +HeapAlloc dt=8 heapalloc_value=20895368 +HeapAlloc dt=5 heapalloc_value=20903560 +HeapAlloc dt=6 heapalloc_value=20911752 +HeapAlloc dt=6 heapalloc_value=20919944 +HeapAlloc dt=5 heapalloc_value=20928136 +HeapAlloc dt=9 heapalloc_value=20936328 +HeapAlloc dt=6 heapalloc_value=20944520 +HeapAlloc dt=5 heapalloc_value=20952712 +HeapAlloc dt=6 heapalloc_value=20960904 +HeapAlloc dt=5 heapalloc_value=20969096 +HeapAlloc dt=6 heapalloc_value=20977288 +HeapAlloc dt=5 heapalloc_value=20985480 +HeapAlloc dt=5 heapalloc_value=20993672 +HeapAlloc dt=10 heapalloc_value=21001864 +HeapAlloc dt=6 heapalloc_value=21010056 +HeapAlloc dt=37 heapalloc_value=21018248 +HeapAlloc dt=7 heapalloc_value=21026440 +HeapAlloc dt=6 heapalloc_value=21034632 +HeapAlloc dt=34 heapalloc_value=21042824 +HeapAlloc dt=6 heapalloc_value=21051016 +HeapAlloc dt=6 heapalloc_value=21059208 +HeapAlloc dt=11 heapalloc_value=21067400 +HeapAlloc dt=6 heapalloc_value=21075592 +HeapAlloc dt=5 heapalloc_value=21083784 +HeapAlloc dt=6 heapalloc_value=21091976 +HeapAlloc dt=5 heapalloc_value=21100168 +HeapAlloc dt=9 heapalloc_value=21108360 +HeapAlloc dt=6 heapalloc_value=21116552 +HeapAlloc dt=6 heapalloc_value=21124744 +HeapAlloc dt=10 heapalloc_value=21132936 +HeapAlloc dt=5 heapalloc_value=21141128 +HeapAlloc dt=6 heapalloc_value=21149320 +HeapAlloc dt=5 heapalloc_value=21157512 +HeapAlloc dt=6 heapalloc_value=21165704 +HeapAlloc dt=5 heapalloc_value=21173896 +HeapAlloc dt=6 heapalloc_value=21182088 +HeapAlloc dt=5 heapalloc_value=21190280 +HeapAlloc dt=9 heapalloc_value=21198472 +HeapAlloc dt=6 heapalloc_value=21206664 +HeapAlloc dt=6 heapalloc_value=21214856 +HeapAlloc dt=6 heapalloc_value=21223048 +HeapAlloc dt=5 heapalloc_value=21231240 +HeapAlloc dt=6 heapalloc_value=21239432 +HeapAlloc dt=5 heapalloc_value=21247624 +HeapAlloc dt=6 heapalloc_value=21255816 +HeapAlloc dt=5 heapalloc_value=21264008 +HeapAlloc dt=6 heapalloc_value=21272200 +HeapAlloc dt=5 heapalloc_value=21280392 +HeapAlloc dt=6 heapalloc_value=21288584 +HeapAlloc dt=5 heapalloc_value=21296776 +HeapAlloc dt=6 heapalloc_value=21304968 +HeapAlloc dt=5 heapalloc_value=21313160 +HeapAlloc dt=6 heapalloc_value=21321352 +HeapAlloc dt=6 heapalloc_value=21329544 +HeapAlloc dt=6 heapalloc_value=21337736 +HeapAlloc dt=6 heapalloc_value=21345928 +HeapAlloc dt=6 heapalloc_value=21354120 +HeapAlloc dt=5 heapalloc_value=21362312 +HeapAlloc dt=6 heapalloc_value=21370504 +HeapAlloc dt=6 heapalloc_value=21378696 +HeapAlloc dt=6 heapalloc_value=21386888 +HeapAlloc dt=5 heapalloc_value=21395080 +HeapAlloc dt=6 heapalloc_value=21403272 +HeapAlloc dt=96 heapalloc_value=21411464 +HeapAlloc dt=7 heapalloc_value=21419656 +HeapAlloc dt=6 heapalloc_value=21427848 +HeapAlloc dt=21 heapalloc_value=21968520 +HeapAlloc dt=1835 heapalloc_value=21976712 +HeapAlloc dt=11 heapalloc_value=21984904 +HeapAlloc dt=8 heapalloc_value=21993096 +HeapAlloc dt=7 heapalloc_value=22001288 +HeapAlloc dt=8 heapalloc_value=22009480 +HeapAlloc dt=7 heapalloc_value=22017672 +HeapAlloc dt=8 heapalloc_value=22025864 +HeapAlloc dt=7 heapalloc_value=22034056 +HeapAlloc dt=8 heapalloc_value=22042248 +HeapAlloc dt=7 heapalloc_value=22050440 +HeapAlloc dt=7 heapalloc_value=22058632 +HeapAlloc dt=8 heapalloc_value=22066824 +HeapAlloc dt=7 heapalloc_value=22075016 +HeapAlloc dt=8 heapalloc_value=22083208 +HeapAlloc dt=7 heapalloc_value=22091400 +HeapAlloc dt=7 heapalloc_value=22099592 +HeapAlloc dt=14 heapalloc_value=22107784 +HeapAlloc dt=5 heapalloc_value=22115976 +HeapAlloc dt=6 heapalloc_value=22124168 +HeapAlloc dt=6 heapalloc_value=22132360 +HeapAlloc dt=5 heapalloc_value=22140552 +HeapAlloc dt=6 heapalloc_value=22148744 +HeapAlloc dt=5 heapalloc_value=22156936 +HeapAlloc dt=6 heapalloc_value=22165128 +HeapAlloc dt=6 heapalloc_value=22173320 +HeapAlloc dt=38 heapalloc_value=22181512 +HeapAlloc dt=7 heapalloc_value=22189704 +HeapAlloc dt=5 heapalloc_value=22197896 +HeapAlloc dt=6 heapalloc_value=22206088 +HeapAlloc dt=6 heapalloc_value=22214280 +HeapAlloc dt=5 heapalloc_value=22222472 +GoBlock dt=9 reason_string=19 stack=21 +ProcStop dt=163 +ProcStart dt=16841 p=0 p_seq=30 +ProcStop dt=23 +ProcStart dt=1498 p=1 p_seq=24 +ProcStop dt=11 +ProcStart dt=16726 p=1 p_seq=25 +GoUnblock dt=19 g=1 g_seq=67 stack=0 +GoStart dt=117 g=1 g_seq=68 +HeapAlloc dt=46 heapalloc_value=23254664 +HeapAlloc dt=19 heapalloc_value=23262856 +HeapAlloc dt=20 heapalloc_value=23271048 +HeapAlloc dt=16 heapalloc_value=23279240 +HeapAlloc dt=12 heapalloc_value=23287432 +HeapAlloc dt=12 heapalloc_value=23295624 +HeapAlloc dt=13 heapalloc_value=23303816 +HeapAlloc dt=15 heapalloc_value=23312008 +HeapAlloc dt=13 heapalloc_value=23320200 +HeapAlloc dt=13 heapalloc_value=23328392 +HeapAlloc dt=12 heapalloc_value=23336584 +HeapAlloc dt=12 heapalloc_value=23344776 +HeapAlloc dt=5 heapalloc_value=23352968 +HeapAlloc dt=100 heapalloc_value=23361160 +HeapAlloc dt=14 heapalloc_value=23369352 +HeapAlloc dt=16 heapalloc_value=23377544 +HeapAlloc dt=13 heapalloc_value=23385736 +HeapAlloc dt=5 heapalloc_value=23393928 +HeapAlloc dt=6 heapalloc_value=23402120 +HeapAlloc dt=9 heapalloc_value=23410312 +HeapAlloc dt=6 heapalloc_value=23418504 +HeapAlloc dt=6 heapalloc_value=23426696 +HeapAlloc dt=5 heapalloc_value=23434888 +HeapAlloc dt=6 heapalloc_value=23443080 +HeapAlloc dt=5 heapalloc_value=23451272 +HeapAlloc dt=6 heapalloc_value=23459464 +HeapAlloc dt=6 heapalloc_value=23467656 +HeapAlloc dt=6 heapalloc_value=23475848 +HeapAlloc dt=6 heapalloc_value=23484040 +HeapAlloc dt=5 heapalloc_value=23492232 +HeapAlloc dt=6 heapalloc_value=23500424 +HeapAlloc dt=5 heapalloc_value=23508616 +HeapAlloc dt=83 heapalloc_value=23516808 +HeapAlloc dt=8 heapalloc_value=23525000 +HeapAlloc dt=5 heapalloc_value=23533192 +HeapAlloc dt=6 heapalloc_value=23541384 +HeapAlloc dt=6 heapalloc_value=23549576 +HeapAlloc dt=5 heapalloc_value=23557768 +HeapAlloc dt=7 heapalloc_value=23565960 +HeapAlloc dt=7 heapalloc_value=23574152 +HeapAlloc dt=6 heapalloc_value=23582344 +HeapAlloc dt=5 heapalloc_value=23590536 +HeapAlloc dt=6 heapalloc_value=23598728 +HeapAlloc dt=6 heapalloc_value=23606920 +HeapAlloc dt=5 heapalloc_value=23615112 +HeapAlloc dt=6 heapalloc_value=23623304 +HeapAlloc dt=6 heapalloc_value=23631496 +HeapAlloc dt=5 heapalloc_value=23639688 +HeapAlloc dt=38 heapalloc_value=23647880 +HeapAlloc dt=8 heapalloc_value=23656072 +HeapAlloc dt=37 heapalloc_value=23664264 +HeapAlloc dt=6 heapalloc_value=23672456 +HeapAlloc dt=6 heapalloc_value=23680648 +HeapAlloc dt=6 heapalloc_value=23688840 +HeapAlloc dt=6 heapalloc_value=23697032 +HeapAlloc dt=6 heapalloc_value=23705224 +HeapAlloc dt=5 heapalloc_value=23713416 +HeapAlloc dt=6 heapalloc_value=23721608 +HeapAlloc dt=10 heapalloc_value=23729800 +HeapAlloc dt=5 heapalloc_value=23737992 +HeapAlloc dt=6 heapalloc_value=23746184 +HeapAlloc dt=6 heapalloc_value=23754376 +HeapAlloc dt=5 heapalloc_value=23762568 +HeapAlloc dt=6 heapalloc_value=23770760 +HeapAlloc dt=6 heapalloc_value=23778952 +HeapAlloc dt=5 heapalloc_value=23787144 +HeapAlloc dt=9 heapalloc_value=23795336 +HeapAlloc dt=6 heapalloc_value=23803528 +HeapAlloc dt=6 heapalloc_value=23811720 +HeapAlloc dt=5 heapalloc_value=23819912 +HeapAlloc dt=6 heapalloc_value=23828104 +HeapAlloc dt=6 heapalloc_value=23836296 +HeapAlloc dt=6 heapalloc_value=23844488 +HeapAlloc dt=5 heapalloc_value=23852680 +HeapAlloc dt=6 heapalloc_value=23860872 +HeapAlloc dt=6 heapalloc_value=23869064 +HeapAlloc dt=6 heapalloc_value=23877256 +HeapAlloc dt=6 heapalloc_value=23885448 +HeapAlloc dt=5 heapalloc_value=23893640 +HeapAlloc dt=6 heapalloc_value=23901832 +HeapAlloc dt=5 heapalloc_value=23910024 +HeapAlloc dt=6 heapalloc_value=23918216 +HeapAlloc dt=6 heapalloc_value=23926408 +HeapAlloc dt=6 heapalloc_value=23934600 +HeapAlloc dt=6 heapalloc_value=23942792 +HeapAlloc dt=5 heapalloc_value=23950984 +HeapAlloc dt=6 heapalloc_value=23959176 +HeapAlloc dt=5 heapalloc_value=23967368 +HeapAlloc dt=6 heapalloc_value=23975560 +HeapAlloc dt=7 heapalloc_value=23983752 +HeapAlloc dt=5 heapalloc_value=23991944 +HeapAlloc dt=6 heapalloc_value=24000136 +HeapAlloc dt=5 heapalloc_value=24008328 +HeapAlloc dt=6 heapalloc_value=24016520 +HeapAlloc dt=6 heapalloc_value=24024712 +HeapAlloc dt=5 heapalloc_value=24032904 +HeapAlloc dt=50 heapalloc_value=24041096 +HeapAlloc dt=7 heapalloc_value=24049288 +HeapAlloc dt=6 heapalloc_value=24057480 +HeapAlloc dt=5 heapalloc_value=24065672 +HeapAlloc dt=34 heapalloc_value=24073864 +HeapAlloc dt=7 heapalloc_value=24082056 +HeapAlloc dt=6 heapalloc_value=24090248 +HeapAlloc dt=6 heapalloc_value=24098440 +HeapAlloc dt=6 heapalloc_value=24106632 +HeapAlloc dt=5 heapalloc_value=24114824 +HeapAlloc dt=6 heapalloc_value=24123016 +HeapAlloc dt=6 heapalloc_value=24131208 +HeapAlloc dt=6 heapalloc_value=24139400 +HeapAlloc dt=6 heapalloc_value=24147592 +HeapAlloc dt=5 heapalloc_value=24155784 +HeapAlloc dt=6 heapalloc_value=24163976 +HeapAlloc dt=5 heapalloc_value=24172168 +HeapAlloc dt=6 heapalloc_value=24180360 +HeapAlloc dt=365 heapalloc_value=24188552 +HeapAlloc dt=13 heapalloc_value=24196744 +HeapAlloc dt=6 heapalloc_value=24204936 +HeapAlloc dt=6 heapalloc_value=24213128 +HeapAlloc dt=5 heapalloc_value=24221320 +HeapAlloc dt=6 heapalloc_value=24229512 +HeapAlloc dt=6 heapalloc_value=24237704 +HeapAlloc dt=6 heapalloc_value=24245896 +HeapAlloc dt=6 heapalloc_value=24254088 +HeapAlloc dt=6 heapalloc_value=24262280 +HeapAlloc dt=6 heapalloc_value=24270472 +GoBlock dt=10 reason_string=19 stack=21 +ProcStop dt=157 +ProcStart dt=12778 p=1 p_seq=27 +GoUnblock dt=12 g=1 g_seq=69 stack=0 +GoStart dt=143 g=1 g_seq=70 +HeapAlloc dt=61 heapalloc_value=24278664 +HeapAlloc dt=11 heapalloc_value=24286856 +HeapAlloc dt=5 heapalloc_value=24295048 +HeapAlloc dt=6 heapalloc_value=24303240 +HeapAlloc dt=5 heapalloc_value=24311432 +HeapAlloc dt=6 heapalloc_value=24319624 +HeapAlloc dt=6 heapalloc_value=24327816 +HeapAlloc dt=6 heapalloc_value=24336008 +HeapAlloc dt=7 heapalloc_value=24344200 +HeapAlloc dt=5 heapalloc_value=24352392 +HeapAlloc dt=7 heapalloc_value=24360584 +HeapAlloc dt=5 heapalloc_value=24368776 +HeapAlloc dt=6 heapalloc_value=24376968 +HeapAlloc dt=6 heapalloc_value=24385160 +HeapAlloc dt=5 heapalloc_value=24393352 +HeapAlloc dt=6 heapalloc_value=24401544 +HeapAlloc dt=6 heapalloc_value=24409736 +HeapAlloc dt=6 heapalloc_value=24417928 +HeapAlloc dt=6 heapalloc_value=24426120 +HeapAlloc dt=5 heapalloc_value=24434312 +HeapAlloc dt=6 heapalloc_value=24442504 +HeapAlloc dt=6 heapalloc_value=24450696 +HeapAlloc dt=6 heapalloc_value=24458888 +HeapAlloc dt=6 heapalloc_value=24467080 +HeapAlloc dt=5 heapalloc_value=24475272 +HeapAlloc dt=6 heapalloc_value=24483464 +HeapAlloc dt=5 heapalloc_value=24491656 +HeapAlloc dt=6 heapalloc_value=24499848 +HeapAlloc dt=6 heapalloc_value=24508040 +HeapAlloc dt=5 heapalloc_value=24516232 +HeapAlloc dt=6 heapalloc_value=24524424 +HeapAlloc dt=6 heapalloc_value=24532616 +HeapAlloc dt=5 heapalloc_value=24540808 +HeapAlloc dt=6 heapalloc_value=24549000 +HeapAlloc dt=5 heapalloc_value=24557192 +HeapAlloc dt=49 heapalloc_value=24565384 +HeapAlloc dt=7 heapalloc_value=24573576 +HeapAlloc dt=5 heapalloc_value=24581768 +HeapAlloc dt=6 heapalloc_value=24589960 +HeapAlloc dt=17 heapalloc_value=24598152 +HeapAlloc dt=12 heapalloc_value=24606344 +HeapAlloc dt=5 heapalloc_value=24614536 +HeapAlloc dt=6 heapalloc_value=24622728 +HeapAlloc dt=5 heapalloc_value=24630920 +HeapAlloc dt=6 heapalloc_value=24639112 +HeapAlloc dt=6 heapalloc_value=24647304 +HeapAlloc dt=5 heapalloc_value=24655496 +HeapAlloc dt=6 heapalloc_value=24663688 +HeapAlloc dt=37 heapalloc_value=24671880 +HeapAlloc dt=6 heapalloc_value=24680072 +HeapAlloc dt=6 heapalloc_value=24688264 +HeapAlloc dt=36 heapalloc_value=24696456 +HeapAlloc dt=7 heapalloc_value=24704648 +HeapAlloc dt=12 heapalloc_value=24712840 +HeapAlloc dt=6 heapalloc_value=24721032 +HeapAlloc dt=17 heapalloc_value=24729224 +HeapAlloc dt=5 heapalloc_value=24737416 +HeapAlloc dt=6 heapalloc_value=24745608 +HeapAlloc dt=19 heapalloc_value=24753800 +HeapAlloc dt=5 heapalloc_value=24761992 +HeapAlloc dt=6 heapalloc_value=24770184 +HeapAlloc dt=79 heapalloc_value=24778376 +HeapAlloc dt=7 heapalloc_value=24786568 +HeapAlloc dt=6 heapalloc_value=24794760 +HeapAlloc dt=5 heapalloc_value=24802952 +HeapAlloc dt=6 heapalloc_value=24811144 +HeapAlloc dt=6 heapalloc_value=24819336 +HeapAlloc dt=6 heapalloc_value=24827528 +HeapAlloc dt=5 heapalloc_value=24835720 +HeapAlloc dt=6 heapalloc_value=24843912 +HeapAlloc dt=6 heapalloc_value=24852104 +HeapAlloc dt=6 heapalloc_value=24860296 +HeapAlloc dt=6 heapalloc_value=24868488 +HeapAlloc dt=5 heapalloc_value=24876680 +HeapAlloc dt=6 heapalloc_value=24884872 +HeapAlloc dt=6 heapalloc_value=24893064 +HeapAlloc dt=5 heapalloc_value=24901256 +HeapAlloc dt=6 heapalloc_value=24909448 +HeapAlloc dt=6 heapalloc_value=24917640 +HeapAlloc dt=5 heapalloc_value=24925832 +HeapAlloc dt=6 heapalloc_value=24934024 +HeapAlloc dt=5 heapalloc_value=24942216 +HeapAlloc dt=6 heapalloc_value=24950408 +HeapAlloc dt=6 heapalloc_value=24958600 +HeapAlloc dt=6 heapalloc_value=24966792 +HeapAlloc dt=5 heapalloc_value=24974984 +HeapAlloc dt=6 heapalloc_value=24983176 +HeapAlloc dt=6 heapalloc_value=24991368 +HeapAlloc dt=6 heapalloc_value=24999560 +HeapAlloc dt=5 heapalloc_value=25007752 +HeapAlloc dt=6 heapalloc_value=25015944 +HeapAlloc dt=5 heapalloc_value=25024136 +HeapAlloc dt=6 heapalloc_value=25032328 +HeapAlloc dt=6 heapalloc_value=25040520 +HeapAlloc dt=6 heapalloc_value=25048712 +HeapAlloc dt=6 heapalloc_value=25056904 +HeapAlloc dt=5 heapalloc_value=25065096 +HeapAlloc dt=6 heapalloc_value=25073288 +HeapAlloc dt=6 heapalloc_value=25081480 +HeapAlloc dt=46 heapalloc_value=25089672 +HeapAlloc dt=7 heapalloc_value=25097864 +HeapAlloc dt=6 heapalloc_value=25106056 +HeapAlloc dt=5 heapalloc_value=25114248 +HeapAlloc dt=36 heapalloc_value=25122440 +HeapAlloc dt=7 heapalloc_value=25130632 +HeapAlloc dt=6 heapalloc_value=25138824 +HeapAlloc dt=6 heapalloc_value=25147016 +HeapAlloc dt=5 heapalloc_value=25155208 +HeapAlloc dt=6 heapalloc_value=25163400 +HeapAlloc dt=5 heapalloc_value=25171592 +HeapAlloc dt=6 heapalloc_value=25179784 +HeapAlloc dt=5 heapalloc_value=25187976 +HeapAlloc dt=6 heapalloc_value=25196168 +HeapAlloc dt=5 heapalloc_value=25204360 +HeapAlloc dt=6 heapalloc_value=25212552 +HeapAlloc dt=5 heapalloc_value=25220744 +HeapAlloc dt=6 heapalloc_value=25228936 +HeapAlloc dt=10 heapalloc_value=25237128 +HeapAlloc dt=5 heapalloc_value=25245320 +HeapAlloc dt=6 heapalloc_value=25253512 +HeapAlloc dt=5 heapalloc_value=25261704 +HeapAlloc dt=6 heapalloc_value=25269896 +HeapAlloc dt=6 heapalloc_value=25278088 +HeapAlloc dt=5 heapalloc_value=25286280 +HeapAlloc dt=6 heapalloc_value=25294472 +GoBlock dt=10 reason_string=19 stack=21 +ProcStop dt=14 +ProcStart dt=7152 p=1 p_seq=29 +GoStart dt=199 g=37 g_seq=1 +GoStop dt=306782 reason_string=16 stack=50 +GoStart dt=57 g=37 g_seq=2 +GoStop dt=315218 reason_string=16 stack=50 +GoStart dt=17 g=37 g_seq=3 +GoDestroy dt=159214 +ProcStop dt=60 +EventBatch gen=1 m=1709041 time=7689670150297 size=5255 +ProcStart dt=316 p=3 p_seq=1 +ProcStop dt=37 +ProcStart dt=311299 p=1 p_seq=5 +ProcStop dt=17 +ProcStart dt=16759 p=1 p_seq=6 +GoUnblock dt=47 g=1 g_seq=3 stack=0 +GoStart dt=137 g=1 g_seq=4 +HeapAlloc dt=56 heapalloc_value=2809856 +HeapAlloc dt=29 heapalloc_value=2818048 +HeapAlloc dt=19 heapalloc_value=2826240 +HeapAlloc dt=22 heapalloc_value=2834432 +HeapAlloc dt=91 heapalloc_value=2842624 +HeapAlloc dt=21 heapalloc_value=2850816 +HeapAlloc dt=24 heapalloc_value=2859008 +HeapAlloc dt=7 heapalloc_value=2867200 +HeapAlloc dt=15 heapalloc_value=2875392 +HeapAlloc dt=16 heapalloc_value=2883584 +HeapAlloc dt=12 heapalloc_value=2899968 +HeapAlloc dt=9 heapalloc_value=2908160 +HeapAlloc dt=16 heapalloc_value=2916352 +HeapAlloc dt=15 heapalloc_value=2924544 +HeapAlloc dt=12 heapalloc_value=2932736 +HeapAlloc dt=12 heapalloc_value=2940928 +HeapAlloc dt=7 heapalloc_value=2949120 +HeapAlloc dt=18 heapalloc_value=2957312 +HeapAlloc dt=14 heapalloc_value=2965504 +HeapAlloc dt=12 heapalloc_value=2973696 +HeapAlloc dt=13 heapalloc_value=2981888 +HeapAlloc dt=12 heapalloc_value=2990080 +HeapAlloc dt=11 heapalloc_value=2998272 +HeapAlloc dt=12 heapalloc_value=3006464 +HeapAlloc dt=13 heapalloc_value=3014656 +HeapAlloc dt=12 heapalloc_value=3022848 +HeapAlloc dt=11 heapalloc_value=3031040 +HeapAlloc dt=11 heapalloc_value=3039232 +HeapAlloc dt=13 heapalloc_value=3047424 +HeapAlloc dt=11 heapalloc_value=3055616 +HeapAlloc dt=20 heapalloc_value=3063808 +HeapAlloc dt=12 heapalloc_value=3072000 +HeapAlloc dt=12 heapalloc_value=3080192 +HeapAlloc dt=11 heapalloc_value=3088384 +HeapAlloc dt=12 heapalloc_value=3096576 +HeapAlloc dt=11 heapalloc_value=3104768 +HeapAlloc dt=11 heapalloc_value=3112960 +HeapAlloc dt=12 heapalloc_value=3121152 +HeapAlloc dt=11 heapalloc_value=3129344 +HeapAlloc dt=15 heapalloc_value=3137536 +HeapAlloc dt=15 heapalloc_value=3145728 +HeapAlloc dt=18 heapalloc_value=3153920 +HeapAlloc dt=13 heapalloc_value=3162112 +HeapAlloc dt=12 heapalloc_value=3170304 +HeapAlloc dt=16 heapalloc_value=3178496 +HeapAlloc dt=11 heapalloc_value=3186688 +HeapAlloc dt=12 heapalloc_value=3194880 +HeapAlloc dt=11 heapalloc_value=3203072 +HeapAlloc dt=13 heapalloc_value=3211264 +HeapAlloc dt=12 heapalloc_value=3219456 +HeapAlloc dt=11 heapalloc_value=3227648 +HeapAlloc dt=13 heapalloc_value=3244032 +HeapAlloc dt=734 heapalloc_value=3252224 +HeapAlloc dt=16 heapalloc_value=3260416 +HeapAlloc dt=8 heapalloc_value=3268608 +HeapAlloc dt=5 heapalloc_value=3276800 +HeapAlloc dt=8 heapalloc_value=3284992 +HeapAlloc dt=88 heapalloc_value=3293184 +HeapAlloc dt=7 heapalloc_value=3301376 +HeapAlloc dt=5 heapalloc_value=3309568 +HeapAlloc dt=6 heapalloc_value=3317760 +HeapAlloc dt=5 heapalloc_value=3325952 +HeapAlloc dt=5 heapalloc_value=3334144 +HeapAlloc dt=5 heapalloc_value=3342336 +HeapAlloc dt=5 heapalloc_value=3350528 +HeapAlloc dt=6 heapalloc_value=3358720 +HeapAlloc dt=5 heapalloc_value=3366912 +HeapAlloc dt=5 heapalloc_value=3375104 +HeapAlloc dt=7 heapalloc_value=3383296 +HeapAlloc dt=6 heapalloc_value=3391488 +HeapAlloc dt=5 heapalloc_value=3399680 +HeapAlloc dt=5 heapalloc_value=3407872 +HeapAlloc dt=5 heapalloc_value=3416064 +HeapAlloc dt=6 heapalloc_value=3424256 +HeapAlloc dt=5 heapalloc_value=3432448 +HeapAlloc dt=5 heapalloc_value=3440640 +HeapAlloc dt=5 heapalloc_value=3448832 +HeapAlloc dt=6 heapalloc_value=3457024 +HeapAlloc dt=5 heapalloc_value=3465216 +HeapAlloc dt=38 heapalloc_value=3473408 +HeapAlloc dt=6 heapalloc_value=3481600 +HeapAlloc dt=5 heapalloc_value=3489792 +HeapAlloc dt=6 heapalloc_value=3497984 +HeapAlloc dt=5 heapalloc_value=3506176 +HeapAlloc dt=6 heapalloc_value=3514368 +HeapAlloc dt=5 heapalloc_value=3522560 +HeapAlloc dt=5 heapalloc_value=3530752 +HeapAlloc dt=5 heapalloc_value=3538944 +HeapAlloc dt=5 heapalloc_value=3547136 +HeapAlloc dt=6 heapalloc_value=3555328 +HeapAlloc dt=5 heapalloc_value=3563520 +HeapAlloc dt=5 heapalloc_value=3571712 +HeapAlloc dt=5 heapalloc_value=3579904 +HeapAlloc dt=5 heapalloc_value=3588096 +HeapAlloc dt=6 heapalloc_value=3596288 +HeapAlloc dt=10 heapalloc_value=3678208 +HeapAlloc dt=2433 heapalloc_value=3686400 +HeapAlloc dt=6 heapalloc_value=3694592 +HeapAlloc dt=6 heapalloc_value=3702784 +HeapAlloc dt=6 heapalloc_value=3710976 +HeapAlloc dt=5 heapalloc_value=3719168 +HeapAlloc dt=6 heapalloc_value=3727360 +HeapAlloc dt=5 heapalloc_value=3735552 +HeapAlloc dt=5 heapalloc_value=3743744 +HeapAlloc dt=5 heapalloc_value=3751936 +HeapAlloc dt=6 heapalloc_value=3760128 +HeapAlloc dt=5 heapalloc_value=3768320 +HeapAlloc dt=11 heapalloc_value=3776512 +HeapAlloc dt=31 heapalloc_value=3784704 +HeapAlloc dt=7 heapalloc_value=3792896 +HeapAlloc dt=6 heapalloc_value=3801088 +HeapAlloc dt=5 heapalloc_value=3809280 +HeapAlloc dt=6 heapalloc_value=3817472 +HeapAlloc dt=5 heapalloc_value=3825664 +HeapAlloc dt=5 heapalloc_value=3833856 +HeapAlloc dt=6 heapalloc_value=3842048 +HeapAlloc dt=5 heapalloc_value=3850240 +HeapAlloc dt=5 heapalloc_value=3858432 +HeapAlloc dt=6 heapalloc_value=3866624 +HeapAlloc dt=5 heapalloc_value=3874816 +HeapAlloc dt=5 heapalloc_value=3883008 +HeapAlloc dt=78 heapalloc_value=3891200 +HeapAlloc dt=7 heapalloc_value=3899392 +HeapAlloc dt=6 heapalloc_value=3907584 +HeapAlloc dt=5 heapalloc_value=3915776 +HeapAlloc dt=5 heapalloc_value=3923968 +HeapAlloc dt=5 heapalloc_value=3932160 +HeapAlloc dt=6 heapalloc_value=3940352 +HeapAlloc dt=5 heapalloc_value=3948544 +HeapAlloc dt=5 heapalloc_value=3956736 +HeapAlloc dt=5 heapalloc_value=3964928 +HeapAlloc dt=5 heapalloc_value=3973120 +HeapAlloc dt=6 heapalloc_value=3981312 +HeapAlloc dt=5 heapalloc_value=3989504 +HeapAlloc dt=6 heapalloc_value=3997696 +GCBegin dt=38 gc_seq=1 stack=22 +HeapAlloc dt=42 heapalloc_value=4005888 +HeapAlloc dt=14 heapalloc_value=4014080 +GoCreate dt=73 new_g=18 new_stack=23 stack=24 +GoBlock dt=235 reason_string=12 stack=25 +GoStart dt=11 g=18 g_seq=1 +HeapAlloc dt=16 heapalloc_value=4022272 +GoUnblock dt=15 g=1 g_seq=5 stack=26 +GoBlock dt=9 reason_string=15 stack=27 +GoStart dt=12 g=1 g_seq=6 +GoCreate dt=44 new_g=19 new_stack=23 stack=24 +GoBlock dt=4 reason_string=12 stack=25 +GoStart dt=3 g=19 g_seq=1 +GoUnblock dt=5 g=1 g_seq=7 stack=26 +GoBlock dt=2 reason_string=15 stack=27 +GoStart dt=2 g=1 g_seq=8 +GoCreate dt=8 new_g=20 new_stack=23 stack=24 +GoBlock dt=3 reason_string=12 stack=25 +GoStart dt=2 g=20 g_seq=1 +GoUnblock dt=3 g=1 g_seq=9 stack=26 +GoBlock dt=1 reason_string=15 stack=27 +GoStart dt=2 g=1 g_seq=10 +GoCreate dt=6 new_g=21 new_stack=23 stack=24 +GoBlock dt=3 reason_string=12 stack=25 +GoStart dt=1 g=21 g_seq=1 +GoUnblock dt=6 g=1 g_seq=11 stack=26 +GoBlock dt=1 reason_string=15 stack=27 +GoStart dt=8 g=1 g_seq=12 +GoCreate dt=7 new_g=22 new_stack=23 stack=24 +GoBlock dt=2 reason_string=12 stack=25 +GoStart dt=2 g=22 g_seq=1 +GoUnblock dt=2 g=1 g_seq=13 stack=26 +GoBlock dt=6 reason_string=15 stack=27 +GoStart dt=4 g=1 g_seq=14 +GoCreate dt=15 new_g=23 new_stack=23 stack=24 +GoBlock dt=166 reason_string=12 stack=25 +GoStart dt=4 g=23 g_seq=1 +GoUnblock dt=3 g=1 g_seq=15 stack=26 +GoBlock dt=3 reason_string=15 stack=27 +GoStart dt=3 g=1 g_seq=16 +HeapAlloc dt=18 heapalloc_value=4030464 +GoCreate dt=11 new_g=24 new_stack=23 stack=24 +GoBlock dt=3 reason_string=12 stack=25 +GoStart dt=1 g=24 g_seq=1 +GoUnblock dt=3 g=1 g_seq=17 stack=26 +GoBlock dt=2 reason_string=15 stack=27 +GoStart dt=1 g=1 g_seq=18 +GoCreate dt=6 new_g=25 new_stack=23 stack=24 +GoBlock dt=3 reason_string=12 stack=25 +GoStart dt=1 g=25 g_seq=1 +GoUnblock dt=2 g=1 g_seq=19 stack=26 +GoBlock dt=2 reason_string=15 stack=27 +GoStart dt=1 g=1 g_seq=20 +STWBegin dt=118 kind_string=22 stack=28 +GoStatus dt=1398 g=4 m=18446744073709551615 gstatus=4 +GoUnblock dt=83 g=4 g_seq=1 stack=29 +ProcsChange dt=91 procs_value=8 stack=30 +STWEnd dt=31 +GCMarkAssistBegin dt=149 stack=31 +GCMarkAssistEnd dt=1458 +GoBlock dt=23 reason_string=19 stack=21 +GoStart dt=166 g=4 g_seq=2 +GoBlock dt=22 reason_string=15 stack=32 +GoUnblock dt=35 g=23 g_seq=2 stack=0 +GoStart dt=4 g=23 g_seq=3 +GoLabel dt=1 label_string=4 +GoBlock dt=441 reason_string=15 stack=27 +ProcStop dt=23 +ProcStart dt=16781 p=0 p_seq=6 +GoUnblock dt=28 g=1 g_seq=27 stack=0 +GoStart dt=162 g=1 g_seq=28 +HeapAlloc dt=69 heapalloc_value=4663024 +HeapAlloc dt=23 heapalloc_value=4671216 +HeapAlloc dt=15 heapalloc_value=4679408 +HeapAlloc dt=10 heapalloc_value=4687600 +HeapAlloc dt=12 heapalloc_value=4695792 +HeapAlloc dt=8 heapalloc_value=4703984 +HeapAlloc dt=6 heapalloc_value=4712176 +HeapAlloc dt=12 heapalloc_value=4720368 +HeapAlloc dt=12 heapalloc_value=4728560 +HeapAlloc dt=12 heapalloc_value=4736752 +HeapAlloc dt=15 heapalloc_value=4744944 +HeapAlloc dt=9 heapalloc_value=4753136 +HeapAlloc dt=9 heapalloc_value=4761328 +HeapAlloc dt=7 heapalloc_value=4769520 +HeapAlloc dt=8 heapalloc_value=4777712 +HeapAlloc dt=9 heapalloc_value=4785904 +HeapAlloc dt=112 heapalloc_value=4794096 +HeapAlloc dt=7 heapalloc_value=4802288 +HeapAlloc dt=9 heapalloc_value=4810480 +HeapAlloc dt=13 heapalloc_value=4818672 +HeapAlloc dt=14 heapalloc_value=4826864 +HeapAlloc dt=6 heapalloc_value=4835056 +HeapAlloc dt=5 heapalloc_value=4843248 +HeapAlloc dt=6 heapalloc_value=4851440 +HeapAlloc dt=14 heapalloc_value=4859632 +HeapAlloc dt=10 heapalloc_value=4867824 +HeapAlloc dt=10 heapalloc_value=4876016 +HeapAlloc dt=6 heapalloc_value=4884208 +HeapAlloc dt=9 heapalloc_value=4892400 +HeapAlloc dt=72 heapalloc_value=4900592 +HeapAlloc dt=6 heapalloc_value=4908784 +HeapAlloc dt=5 heapalloc_value=4916976 +HeapAlloc dt=6 heapalloc_value=4925168 +HeapAlloc dt=6 heapalloc_value=4933360 +HeapAlloc dt=9 heapalloc_value=4941552 +HeapAlloc dt=46 heapalloc_value=4949744 +HeapAlloc dt=10 heapalloc_value=4957936 +HeapAlloc dt=6 heapalloc_value=4966128 +HeapAlloc dt=6 heapalloc_value=4974320 +HeapAlloc dt=6 heapalloc_value=4982512 +HeapAlloc dt=5 heapalloc_value=4990704 +HeapAlloc dt=6 heapalloc_value=4998896 +HeapAlloc dt=45 heapalloc_value=5007088 +HeapAlloc dt=6 heapalloc_value=5015280 +HeapAlloc dt=9 heapalloc_value=5023472 +HeapAlloc dt=6 heapalloc_value=5031664 +HeapAlloc dt=5 heapalloc_value=5039856 +HeapAlloc dt=6 heapalloc_value=5048048 +HeapAlloc dt=6 heapalloc_value=5056240 +HeapAlloc dt=15 heapalloc_value=5138160 +HeapAlloc dt=81 heapalloc_value=5146352 +HeapAlloc dt=6 heapalloc_value=5154544 +HeapAlloc dt=6 heapalloc_value=5162736 +HeapAlloc dt=5 heapalloc_value=5170928 +HeapAlloc dt=6 heapalloc_value=5179120 +HeapAlloc dt=5 heapalloc_value=5187312 +HeapAlloc dt=6 heapalloc_value=5195504 +HeapAlloc dt=7 heapalloc_value=5203696 +HeapAlloc dt=5 heapalloc_value=5211888 +HeapAlloc dt=6 heapalloc_value=5220080 +HeapAlloc dt=6 heapalloc_value=5228272 +HeapAlloc dt=37 heapalloc_value=5236464 +HeapAlloc dt=7 heapalloc_value=5244656 +HeapAlloc dt=6 heapalloc_value=5252848 +HeapAlloc dt=5 heapalloc_value=5261040 +HeapAlloc dt=8 heapalloc_value=5269232 +HeapAlloc dt=6 heapalloc_value=5277424 +HeapAlloc dt=6 heapalloc_value=5285616 +HeapAlloc dt=5 heapalloc_value=5293808 +HeapAlloc dt=7 heapalloc_value=5302000 +HeapAlloc dt=5 heapalloc_value=5310192 +HeapAlloc dt=5 heapalloc_value=5318384 +HeapAlloc dt=6 heapalloc_value=5326576 +HeapAlloc dt=7 heapalloc_value=5334768 +HeapAlloc dt=6 heapalloc_value=5342960 +HeapAlloc dt=5 heapalloc_value=5351152 +HeapAlloc dt=6 heapalloc_value=5359344 +HeapAlloc dt=5 heapalloc_value=5367536 +HeapAlloc dt=13 heapalloc_value=5375728 +HeapAlloc dt=6 heapalloc_value=5383920 +HeapAlloc dt=100 heapalloc_value=5392112 +HeapAlloc dt=8 heapalloc_value=5400304 +HeapAlloc dt=6 heapalloc_value=5408496 +HeapAlloc dt=6 heapalloc_value=5416688 +HeapAlloc dt=5 heapalloc_value=5424880 +HeapAlloc dt=6 heapalloc_value=5433072 +HeapAlloc dt=33 heapalloc_value=5441264 +HeapAlloc dt=7 heapalloc_value=5449456 +HeapAlloc dt=5 heapalloc_value=5457648 +HeapAlloc dt=8 heapalloc_value=5465840 +HeapAlloc dt=6 heapalloc_value=5474032 +HeapAlloc dt=5 heapalloc_value=5482224 +HeapAlloc dt=6 heapalloc_value=5490416 +HeapAlloc dt=5 heapalloc_value=5498608 +HeapAlloc dt=6 heapalloc_value=5506800 +HeapAlloc dt=6 heapalloc_value=5514992 +HeapAlloc dt=5 heapalloc_value=5523184 +HeapAlloc dt=12 heapalloc_value=5531376 +HeapAlloc dt=6 heapalloc_value=5539568 +HeapAlloc dt=6 heapalloc_value=5547760 +HeapAlloc dt=5 heapalloc_value=5555952 +HeapAlloc dt=6 heapalloc_value=5564144 +HeapAlloc dt=5 heapalloc_value=5572336 +HeapAlloc dt=6 heapalloc_value=5580528 +HeapAlloc dt=5 heapalloc_value=5588720 +HeapAlloc dt=7 heapalloc_value=5596912 +HeapAlloc dt=6 heapalloc_value=5605104 +HeapAlloc dt=5 heapalloc_value=5613296 +HeapAlloc dt=6 heapalloc_value=5621488 +HeapAlloc dt=5 heapalloc_value=5629680 +HeapAlloc dt=6 heapalloc_value=5637872 +HeapAlloc dt=6 heapalloc_value=5646064 +HeapAlloc dt=37 heapalloc_value=5654256 +HeapAlloc dt=7 heapalloc_value=5662448 +HeapAlloc dt=6 heapalloc_value=5670640 +HeapAlloc dt=5 heapalloc_value=5678832 +HeapAlloc dt=6 heapalloc_value=5687024 +HeapAlloc dt=5 heapalloc_value=5695216 +HeapAlloc dt=6 heapalloc_value=5703408 +HeapAlloc dt=6 heapalloc_value=5711600 +HeapAlloc dt=5 heapalloc_value=5719792 +HeapAlloc dt=5 heapalloc_value=5727984 +HeapAlloc dt=6 heapalloc_value=5736176 +HeapAlloc dt=6 heapalloc_value=5744368 +HeapAlloc dt=5 heapalloc_value=5752560 +HeapAlloc dt=5 heapalloc_value=5760752 +GoBlock dt=15 reason_string=19 stack=21 +ProcStop dt=178 +ProcStart dt=17613 p=4 p_seq=3 +ProcStop dt=26 +ProcStart dt=3944 p=0 p_seq=9 +ProcStop dt=12 +ProcStart dt=16762 p=4 p_seq=6 +ProcStop dt=14 +ProcStart dt=9275 p=0 p_seq=12 +ProcStop dt=9 +ProcStart dt=16732 p=0 p_seq=13 +GoUnblock dt=9 g=1 g_seq=38 stack=0 +GoStart dt=84 g=1 g_seq=39 +HeapAlloc dt=23 heapalloc_value=9631048 +HeapAlloc dt=24 heapalloc_value=9639240 +HeapAlloc dt=15 heapalloc_value=9647432 +HeapAlloc dt=15 heapalloc_value=9655624 +HeapAlloc dt=15 heapalloc_value=9663816 +HeapAlloc dt=16 heapalloc_value=9672008 +HeapAlloc dt=14 heapalloc_value=9680200 +HeapAlloc dt=18 heapalloc_value=9688392 +HeapAlloc dt=14 heapalloc_value=9696584 +HeapAlloc dt=19 heapalloc_value=9704776 +HeapAlloc dt=15 heapalloc_value=9712968 +HeapAlloc dt=76 heapalloc_value=9721160 +HeapAlloc dt=18 heapalloc_value=9729352 +HeapAlloc dt=17 heapalloc_value=9737544 +HeapAlloc dt=14 heapalloc_value=9745736 +HeapAlloc dt=15 heapalloc_value=9753928 +HeapAlloc dt=16 heapalloc_value=9762120 +HeapAlloc dt=28 heapalloc_value=9770312 +HeapAlloc dt=23 heapalloc_value=9778504 +HeapAlloc dt=19 heapalloc_value=9786696 +HeapAlloc dt=14 heapalloc_value=9794888 +HeapAlloc dt=26 heapalloc_value=9803080 +HeapAlloc dt=18 heapalloc_value=9811272 +HeapAlloc dt=16 heapalloc_value=9819464 +HeapAlloc dt=15 heapalloc_value=9827656 +HeapAlloc dt=19 heapalloc_value=9835848 +HeapAlloc dt=16 heapalloc_value=9844040 +HeapAlloc dt=15 heapalloc_value=9852232 +HeapAlloc dt=15 heapalloc_value=9860424 +HeapAlloc dt=15 heapalloc_value=9868616 +HeapAlloc dt=15 heapalloc_value=9876808 +HeapAlloc dt=15 heapalloc_value=9885000 +HeapAlloc dt=15 heapalloc_value=9893192 +HeapAlloc dt=15 heapalloc_value=9901384 +HeapAlloc dt=16 heapalloc_value=9909576 +HeapAlloc dt=16 heapalloc_value=9917768 +HeapAlloc dt=15 heapalloc_value=9925960 +HeapAlloc dt=15 heapalloc_value=9934152 +HeapAlloc dt=15 heapalloc_value=9942344 +HeapAlloc dt=15 heapalloc_value=9950536 +HeapAlloc dt=16 heapalloc_value=9958728 +HeapAlloc dt=15 heapalloc_value=9966920 +HeapAlloc dt=63 heapalloc_value=9975112 +HeapAlloc dt=20 heapalloc_value=9983304 +HeapAlloc dt=14 heapalloc_value=9991496 +HeapAlloc dt=15 heapalloc_value=9999688 +HeapAlloc dt=14 heapalloc_value=10007880 +HeapAlloc dt=15 heapalloc_value=10016072 +HeapAlloc dt=16 heapalloc_value=10024264 +HeapAlloc dt=16 heapalloc_value=10032456 +HeapAlloc dt=16 heapalloc_value=10040648 +HeapAlloc dt=16 heapalloc_value=10048840 +HeapAlloc dt=15 heapalloc_value=10057032 +HeapAlloc dt=16 heapalloc_value=10065224 +HeapAlloc dt=14 heapalloc_value=10073416 +HeapAlloc dt=16 heapalloc_value=10081608 +HeapAlloc dt=15 heapalloc_value=10089800 +HeapAlloc dt=16 heapalloc_value=10097992 +HeapAlloc dt=16 heapalloc_value=10106184 +HeapAlloc dt=17 heapalloc_value=10114376 +HeapAlloc dt=15 heapalloc_value=10122568 +HeapAlloc dt=33 heapalloc_value=10327368 +HeapAlloc dt=367 heapalloc_value=10335560 +HeapAlloc dt=21 heapalloc_value=10343752 +HeapAlloc dt=16 heapalloc_value=10351944 +HeapAlloc dt=15 heapalloc_value=10360136 +HeapAlloc dt=16 heapalloc_value=10368328 +HeapAlloc dt=16 heapalloc_value=10376520 +HeapAlloc dt=16 heapalloc_value=10384712 +HeapAlloc dt=15 heapalloc_value=10392904 +HeapAlloc dt=15 heapalloc_value=10401096 +HeapAlloc dt=15 heapalloc_value=10409288 +HeapAlloc dt=15 heapalloc_value=10417480 +HeapAlloc dt=15 heapalloc_value=10425672 +HeapAlloc dt=17 heapalloc_value=10433864 +HeapAlloc dt=15 heapalloc_value=10442056 +HeapAlloc dt=15 heapalloc_value=10450248 +HeapAlloc dt=15 heapalloc_value=10458440 +HeapAlloc dt=15 heapalloc_value=10466632 +HeapAlloc dt=15 heapalloc_value=10474824 +HeapAlloc dt=15 heapalloc_value=10483016 +HeapAlloc dt=14 heapalloc_value=10491208 +HeapAlloc dt=22 heapalloc_value=10499400 +HeapAlloc dt=7 heapalloc_value=10507592 +HeapAlloc dt=9 heapalloc_value=10515784 +HeapAlloc dt=7 heapalloc_value=10523976 +HeapAlloc dt=6 heapalloc_value=10532168 +HeapAlloc dt=5 heapalloc_value=10540360 +HeapAlloc dt=6 heapalloc_value=10548552 +HeapAlloc dt=6 heapalloc_value=10556744 +HeapAlloc dt=5 heapalloc_value=10564936 +HeapAlloc dt=6 heapalloc_value=10573128 +HeapAlloc dt=6 heapalloc_value=10581320 +HeapAlloc dt=5 heapalloc_value=10589512 +HeapAlloc dt=6 heapalloc_value=10597704 +HeapAlloc dt=6 heapalloc_value=10605896 +HeapAlloc dt=5 heapalloc_value=10614088 +HeapAlloc dt=6 heapalloc_value=10622280 +HeapAlloc dt=5 heapalloc_value=10630472 +HeapAlloc dt=6 heapalloc_value=10638664 +HeapAlloc dt=6 heapalloc_value=10646856 +HeapAlloc dt=5 heapalloc_value=10655048 +HeapAlloc dt=6 heapalloc_value=10663240 +HeapAlloc dt=5 heapalloc_value=10671432 +HeapAlloc dt=6 heapalloc_value=10679624 +HeapAlloc dt=5 heapalloc_value=10687816 +HeapAlloc dt=221 heapalloc_value=10696008 +HeapAlloc dt=9 heapalloc_value=10704200 +HeapAlloc dt=6 heapalloc_value=10712392 +HeapAlloc dt=5 heapalloc_value=10720584 +HeapAlloc dt=6 heapalloc_value=10728776 +HeapAlloc dt=6 heapalloc_value=10736968 +HeapAlloc dt=5 heapalloc_value=10745160 +HeapAlloc dt=6 heapalloc_value=10753352 +HeapAlloc dt=5 heapalloc_value=10761544 +HeapAlloc dt=6 heapalloc_value=10769736 +HeapAlloc dt=5 heapalloc_value=10777928 +HeapAlloc dt=5 heapalloc_value=10786120 +HeapAlloc dt=6 heapalloc_value=10794312 +HeapAlloc dt=6 heapalloc_value=10802504 +HeapAlloc dt=5 heapalloc_value=10810696 +HeapAlloc dt=6 heapalloc_value=10818888 +HeapAlloc dt=5 heapalloc_value=10827080 +HeapAlloc dt=6 heapalloc_value=10835272 +HeapAlloc dt=5 heapalloc_value=10843464 +HeapAlloc dt=6 heapalloc_value=10851656 +GoBlock dt=11 reason_string=19 stack=21 +ProcStop dt=119 +ProcStart dt=17350 p=2 p_seq=7 +ProcStop dt=13 +ProcStart dt=1133 p=0 p_seq=16 +ProcStop dt=8 +ProcStart dt=16748 p=0 p_seq=17 +GoUnblock dt=7 g=1 g_seq=42 stack=0 +GoStart dt=84 g=1 g_seq=43 +HeapAlloc dt=15 heapalloc_value=11883848 +HeapAlloc dt=10 heapalloc_value=11892040 +HeapAlloc dt=6 heapalloc_value=11900232 +HeapAlloc dt=6 heapalloc_value=11908424 +HeapAlloc dt=6 heapalloc_value=11916616 +HeapAlloc dt=6 heapalloc_value=11924808 +HeapAlloc dt=8 heapalloc_value=11933000 +HeapAlloc dt=5 heapalloc_value=11941192 +HeapAlloc dt=6 heapalloc_value=11949384 +HeapAlloc dt=62 heapalloc_value=11957576 +HeapAlloc dt=7 heapalloc_value=11965768 +HeapAlloc dt=6 heapalloc_value=11973960 +HeapAlloc dt=6 heapalloc_value=11982152 +HeapAlloc dt=5 heapalloc_value=11990344 +HeapAlloc dt=6 heapalloc_value=11998536 +HeapAlloc dt=6 heapalloc_value=12006728 +HeapAlloc dt=5 heapalloc_value=12014920 +HeapAlloc dt=6 heapalloc_value=12023112 +HeapAlloc dt=5 heapalloc_value=12031304 +HeapAlloc dt=6 heapalloc_value=12039496 +HeapAlloc dt=5 heapalloc_value=12047688 +HeapAlloc dt=6 heapalloc_value=12055880 +HeapAlloc dt=6 heapalloc_value=12064072 +HeapAlloc dt=6 heapalloc_value=12072264 +HeapAlloc dt=5 heapalloc_value=12080456 +HeapAlloc dt=352 heapalloc_value=12088648 +HeapAlloc dt=14 heapalloc_value=12096840 +HeapAlloc dt=7 heapalloc_value=12105032 +HeapAlloc dt=5 heapalloc_value=12113224 +HeapAlloc dt=6 heapalloc_value=12121416 +HeapAlloc dt=41 heapalloc_value=12129608 +HeapAlloc dt=7 heapalloc_value=12137800 +HeapAlloc dt=5 heapalloc_value=12145992 +HeapAlloc dt=6 heapalloc_value=12154184 +HeapAlloc dt=6 heapalloc_value=12162376 +HeapAlloc dt=6 heapalloc_value=12170568 +HeapAlloc dt=5 heapalloc_value=12178760 +HeapAlloc dt=6 heapalloc_value=12186952 +HeapAlloc dt=5 heapalloc_value=12195144 +HeapAlloc dt=7 heapalloc_value=12203336 +HeapAlloc dt=5 heapalloc_value=12211528 +HeapAlloc dt=6 heapalloc_value=12219720 +HeapAlloc dt=5 heapalloc_value=12227912 +HeapAlloc dt=6 heapalloc_value=12236104 +HeapAlloc dt=6 heapalloc_value=12244296 +HeapAlloc dt=6 heapalloc_value=12252488 +HeapAlloc dt=5 heapalloc_value=12260680 +HeapAlloc dt=46 heapalloc_value=12268872 +HeapAlloc dt=6 heapalloc_value=12277064 +HeapAlloc dt=6 heapalloc_value=12285256 +HeapAlloc dt=6 heapalloc_value=12293448 +HeapAlloc dt=5 heapalloc_value=12301640 +HeapAlloc dt=6 heapalloc_value=12309832 +HeapAlloc dt=5 heapalloc_value=12318024 +HeapAlloc dt=6 heapalloc_value=12326216 +HeapAlloc dt=5 heapalloc_value=12334408 +HeapAlloc dt=6 heapalloc_value=12342600 +HeapAlloc dt=5 heapalloc_value=12350792 +HeapAlloc dt=6 heapalloc_value=12358984 +HeapAlloc dt=5 heapalloc_value=12367176 +HeapAlloc dt=6 heapalloc_value=12375368 +HeapAlloc dt=37 heapalloc_value=12383560 +HeapAlloc dt=7 heapalloc_value=12391752 +HeapAlloc dt=6 heapalloc_value=12399944 +HeapAlloc dt=5 heapalloc_value=12408136 +HeapAlloc dt=6 heapalloc_value=12416328 +HeapAlloc dt=6 heapalloc_value=12424520 +HeapAlloc dt=13 heapalloc_value=12686664 +HeapAlloc dt=2516 heapalloc_value=12694856 +HeapAlloc dt=9 heapalloc_value=12703048 +HeapAlloc dt=8 heapalloc_value=12711240 +HeapAlloc dt=7 heapalloc_value=12719432 +HeapAlloc dt=8 heapalloc_value=12727624 +HeapAlloc dt=7 heapalloc_value=12735816 +HeapAlloc dt=8 heapalloc_value=12744008 +HeapAlloc dt=7 heapalloc_value=12752200 +HeapAlloc dt=8 heapalloc_value=12760392 +HeapAlloc dt=7 heapalloc_value=12768584 +HeapAlloc dt=7 heapalloc_value=12776776 +HeapAlloc dt=8 heapalloc_value=12784968 +HeapAlloc dt=7 heapalloc_value=12793160 +HeapAlloc dt=8 heapalloc_value=12801352 +HeapAlloc dt=8 heapalloc_value=12809544 +HeapAlloc dt=7 heapalloc_value=12817736 +HeapAlloc dt=7 heapalloc_value=12825928 +HeapAlloc dt=8 heapalloc_value=12834120 +HeapAlloc dt=7 heapalloc_value=12842312 +HeapAlloc dt=8 heapalloc_value=12850504 +HeapAlloc dt=8 heapalloc_value=12858696 +HeapAlloc dt=7 heapalloc_value=12866888 +HeapAlloc dt=13 heapalloc_value=12875080 +HeapAlloc dt=8 heapalloc_value=12883272 +HeapAlloc dt=5 heapalloc_value=12891464 +HeapAlloc dt=6 heapalloc_value=12899656 +HeapAlloc dt=6 heapalloc_value=12907848 +HeapAlloc dt=5 heapalloc_value=12916040 +HeapAlloc dt=6 heapalloc_value=12924232 +HeapAlloc dt=6 heapalloc_value=12932424 +HeapAlloc dt=5 heapalloc_value=12940616 +HeapAlloc dt=6 heapalloc_value=12948808 +HeapAlloc dt=5 heapalloc_value=12957000 +HeapAlloc dt=6 heapalloc_value=12965192 +HeapAlloc dt=5 heapalloc_value=12973384 +HeapAlloc dt=6 heapalloc_value=12981576 +HeapAlloc dt=6 heapalloc_value=12989768 +HeapAlloc dt=5 heapalloc_value=12997960 +HeapAlloc dt=6 heapalloc_value=13006152 +HeapAlloc dt=6 heapalloc_value=13014344 +HeapAlloc dt=5 heapalloc_value=13022536 +HeapAlloc dt=6 heapalloc_value=13030728 +HeapAlloc dt=5 heapalloc_value=13038920 +HeapAlloc dt=62 heapalloc_value=13047112 +HeapAlloc dt=39 heapalloc_value=13055304 +HeapAlloc dt=7 heapalloc_value=13063496 +HeapAlloc dt=6 heapalloc_value=13071688 +HeapAlloc dt=6 heapalloc_value=13079880 +HeapAlloc dt=6 heapalloc_value=13088072 +HeapAlloc dt=5 heapalloc_value=13096264 +HeapAlloc dt=5 heapalloc_value=13104456 +HeapAlloc dt=6 heapalloc_value=13112648 +HeapAlloc dt=6 heapalloc_value=13120840 +HeapAlloc dt=5 heapalloc_value=13129032 +HeapAlloc dt=10 heapalloc_value=13137224 +HeapAlloc dt=6 heapalloc_value=13145416 +HeapAlloc dt=5 heapalloc_value=13153608 +HeapAlloc dt=6 heapalloc_value=13161800 +GoBlock dt=12 reason_string=19 stack=21 +ProcStop dt=124 +ProcStart dt=17212 p=2 p_seq=9 +ProcStop dt=13 +ProcStart dt=1068 p=0 p_seq=20 +ProcStop dt=8 +ProcStart dt=16756 p=0 p_seq=21 +GoUnblock dt=11 g=1 g_seq=46 stack=0 +GoStart dt=92 g=1 g_seq=47 +HeapAlloc dt=19 heapalloc_value=14193992 +HeapAlloc dt=10 heapalloc_value=14202184 +HeapAlloc dt=6 heapalloc_value=14210376 +HeapAlloc dt=6 heapalloc_value=14218568 +HeapAlloc dt=6 heapalloc_value=14226760 +HeapAlloc dt=6 heapalloc_value=14234952 +HeapAlloc dt=6 heapalloc_value=14243144 +HeapAlloc dt=6 heapalloc_value=14251336 +HeapAlloc dt=6 heapalloc_value=14259528 +HeapAlloc dt=6 heapalloc_value=14267720 +HeapAlloc dt=5 heapalloc_value=14275912 +HeapAlloc dt=6 heapalloc_value=14284104 +HeapAlloc dt=6 heapalloc_value=14292296 +HeapAlloc dt=6 heapalloc_value=14300488 +HeapAlloc dt=60 heapalloc_value=14308680 +HeapAlloc dt=8 heapalloc_value=14316872 +HeapAlloc dt=6 heapalloc_value=14325064 +HeapAlloc dt=6 heapalloc_value=14333256 +HeapAlloc dt=6 heapalloc_value=14341448 +HeapAlloc dt=5 heapalloc_value=14349640 +HeapAlloc dt=6 heapalloc_value=14357832 +HeapAlloc dt=6 heapalloc_value=14366024 +HeapAlloc dt=6 heapalloc_value=14374216 +HeapAlloc dt=6 heapalloc_value=14382408 +HeapAlloc dt=8 heapalloc_value=14390600 +HeapAlloc dt=6 heapalloc_value=14398792 +HeapAlloc dt=6 heapalloc_value=14406984 +HeapAlloc dt=6 heapalloc_value=14415176 +HeapAlloc dt=6 heapalloc_value=14423368 +HeapAlloc dt=5 heapalloc_value=14431560 +HeapAlloc dt=6 heapalloc_value=14439752 +HeapAlloc dt=7 heapalloc_value=14447944 +HeapAlloc dt=5 heapalloc_value=14456136 +HeapAlloc dt=6 heapalloc_value=14464328 +HeapAlloc dt=6 heapalloc_value=14472520 +HeapAlloc dt=5 heapalloc_value=14480712 +HeapAlloc dt=6 heapalloc_value=14488904 +HeapAlloc dt=6 heapalloc_value=14497096 +HeapAlloc dt=6 heapalloc_value=14505288 +HeapAlloc dt=6 heapalloc_value=14513480 +HeapAlloc dt=6 heapalloc_value=14521672 +HeapAlloc dt=6 heapalloc_value=14529864 +HeapAlloc dt=5 heapalloc_value=14538056 +HeapAlloc dt=6 heapalloc_value=14546248 +HeapAlloc dt=6 heapalloc_value=14554440 +HeapAlloc dt=5 heapalloc_value=14562632 +HeapAlloc dt=6 heapalloc_value=14570824 +HeapAlloc dt=6 heapalloc_value=14579016 +HeapAlloc dt=6 heapalloc_value=14587208 +HeapAlloc dt=6 heapalloc_value=14595400 +HeapAlloc dt=5 heapalloc_value=14603592 +HeapAlloc dt=6 heapalloc_value=14611784 +HeapAlloc dt=45 heapalloc_value=14619976 +HeapAlloc dt=7 heapalloc_value=14628168 +HeapAlloc dt=6 heapalloc_value=14636360 +HeapAlloc dt=7 heapalloc_value=14644552 +HeapAlloc dt=5 heapalloc_value=14652744 +HeapAlloc dt=6 heapalloc_value=14660936 +HeapAlloc dt=6 heapalloc_value=14669128 +HeapAlloc dt=5 heapalloc_value=14677320 +HeapAlloc dt=6 heapalloc_value=14685512 +HeapAlloc dt=6 heapalloc_value=14693704 +HeapAlloc dt=6 heapalloc_value=14701896 +HeapAlloc dt=15 heapalloc_value=14710088 +HeapAlloc dt=6 heapalloc_value=14718280 +HeapAlloc dt=5 heapalloc_value=14726472 +HeapAlloc dt=35 heapalloc_value=14734664 +HeapAlloc dt=7 heapalloc_value=14742856 +HeapAlloc dt=6 heapalloc_value=14751048 +HeapAlloc dt=6 heapalloc_value=14759240 +HeapAlloc dt=6 heapalloc_value=14767432 +HeapAlloc dt=6 heapalloc_value=14775624 +HeapAlloc dt=6 heapalloc_value=14783816 +HeapAlloc dt=6 heapalloc_value=14792008 +HeapAlloc dt=5 heapalloc_value=14800200 +HeapAlloc dt=6 heapalloc_value=14808392 +HeapAlloc dt=5 heapalloc_value=14816584 +HeapAlloc dt=6 heapalloc_value=14824776 +HeapAlloc dt=6 heapalloc_value=14832968 +HeapAlloc dt=6 heapalloc_value=14841160 +HeapAlloc dt=6 heapalloc_value=14849352 +HeapAlloc dt=45 heapalloc_value=14857544 +HeapAlloc dt=6 heapalloc_value=14865736 +HeapAlloc dt=5 heapalloc_value=14873928 +HeapAlloc dt=6 heapalloc_value=14882120 +HeapAlloc dt=6 heapalloc_value=14890312 +HeapAlloc dt=6 heapalloc_value=14898504 +HeapAlloc dt=6 heapalloc_value=14906696 +HeapAlloc dt=6 heapalloc_value=14914888 +HeapAlloc dt=5 heapalloc_value=14923080 +HeapAlloc dt=6 heapalloc_value=14931272 +HeapAlloc dt=6 heapalloc_value=14939464 +HeapAlloc dt=5 heapalloc_value=14947656 +HeapAlloc dt=6 heapalloc_value=14955848 +HeapAlloc dt=6 heapalloc_value=14964040 +HeapAlloc dt=6 heapalloc_value=14972232 +HeapAlloc dt=5 heapalloc_value=14980424 +HeapAlloc dt=6 heapalloc_value=14988616 +HeapAlloc dt=6 heapalloc_value=14996808 +HeapAlloc dt=5 heapalloc_value=15005000 +HeapAlloc dt=6 heapalloc_value=15013192 +HeapAlloc dt=6 heapalloc_value=15021384 +HeapAlloc dt=6 heapalloc_value=15029576 +HeapAlloc dt=6 heapalloc_value=15037768 +HeapAlloc dt=6 heapalloc_value=15045960 +HeapAlloc dt=5 heapalloc_value=15054152 +HeapAlloc dt=6 heapalloc_value=15062344 +HeapAlloc dt=6 heapalloc_value=15070536 +HeapAlloc dt=6 heapalloc_value=15078728 +HeapAlloc dt=5 heapalloc_value=15086920 +HeapAlloc dt=6 heapalloc_value=15095112 +HeapAlloc dt=6 heapalloc_value=15103304 +HeapAlloc dt=5 heapalloc_value=15111496 +HeapAlloc dt=6 heapalloc_value=15119688 +HeapAlloc dt=6 heapalloc_value=15127880 +HeapAlloc dt=5 heapalloc_value=15136072 +HeapAlloc dt=51 heapalloc_value=15471944 +HeapAlloc dt=2533 heapalloc_value=15480136 +HeapAlloc dt=11 heapalloc_value=15488328 +HeapAlloc dt=9 heapalloc_value=15496520 +HeapAlloc dt=7 heapalloc_value=15504712 +HeapAlloc dt=9 heapalloc_value=15512904 +HeapAlloc dt=9 heapalloc_value=15521096 +HeapAlloc dt=7 heapalloc_value=15529288 +HeapAlloc dt=8 heapalloc_value=15537480 +HeapAlloc dt=8 heapalloc_value=15545672 +GoBlock dt=13 reason_string=19 stack=21 +ProcStop dt=116 +ProcStart dt=17265 p=2 p_seq=11 +ProcStop dt=10 +ProcStart dt=1450 p=0 p_seq=24 +ProcStop dt=9 +ProcStart dt=17026 p=0 p_seq=25 +GoUnblock dt=12 g=1 g_seq=50 stack=0 +GoStart dt=148 g=1 g_seq=51 +HeapAlloc dt=20 heapalloc_value=16577864 +HeapAlloc dt=15 heapalloc_value=16586056 +HeapAlloc dt=10 heapalloc_value=16594248 +HeapAlloc dt=11 heapalloc_value=16602440 +HeapAlloc dt=9 heapalloc_value=16610632 +HeapAlloc dt=9 heapalloc_value=16618824 +HeapAlloc dt=10 heapalloc_value=16627016 +HeapAlloc dt=9 heapalloc_value=16635208 +HeapAlloc dt=11 heapalloc_value=16643400 +HeapAlloc dt=11 heapalloc_value=16651592 +HeapAlloc dt=9 heapalloc_value=16659784 +HeapAlloc dt=11 heapalloc_value=16667976 +HeapAlloc dt=9 heapalloc_value=16676168 +HeapAlloc dt=10 heapalloc_value=16684360 +HeapAlloc dt=10 heapalloc_value=16692552 +HeapAlloc dt=10 heapalloc_value=16700744 +HeapAlloc dt=11 heapalloc_value=16708936 +HeapAlloc dt=11 heapalloc_value=16717128 +HeapAlloc dt=9 heapalloc_value=16725320 +HeapAlloc dt=78 heapalloc_value=16733512 +HeapAlloc dt=14 heapalloc_value=16741704 +HeapAlloc dt=10 heapalloc_value=16749896 +HeapAlloc dt=11 heapalloc_value=16758088 +HeapAlloc dt=11 heapalloc_value=16766280 +HeapAlloc dt=10 heapalloc_value=16774472 +HeapAlloc dt=9 heapalloc_value=16782664 +HeapAlloc dt=10 heapalloc_value=16790856 +HeapAlloc dt=9 heapalloc_value=16799048 +HeapAlloc dt=21 heapalloc_value=16807240 +HeapAlloc dt=11 heapalloc_value=16815432 +HeapAlloc dt=9 heapalloc_value=16823624 +HeapAlloc dt=9 heapalloc_value=16831816 +HeapAlloc dt=9 heapalloc_value=16840008 +HeapAlloc dt=10 heapalloc_value=16848200 +HeapAlloc dt=11 heapalloc_value=16856392 +HeapAlloc dt=9 heapalloc_value=16864584 +HeapAlloc dt=6 heapalloc_value=16872776 +HeapAlloc dt=9 heapalloc_value=16880968 +HeapAlloc dt=6 heapalloc_value=16889160 +HeapAlloc dt=6 heapalloc_value=16897352 +HeapAlloc dt=5 heapalloc_value=16905544 +HeapAlloc dt=6 heapalloc_value=16913736 +HeapAlloc dt=6 heapalloc_value=16921928 +HeapAlloc dt=5 heapalloc_value=16930120 +HeapAlloc dt=6 heapalloc_value=16938312 +HeapAlloc dt=5 heapalloc_value=16946504 +HeapAlloc dt=6 heapalloc_value=16954696 +HeapAlloc dt=5 heapalloc_value=16962888 +HeapAlloc dt=5 heapalloc_value=16971080 +HeapAlloc dt=5 heapalloc_value=16979272 +HeapAlloc dt=6 heapalloc_value=16987464 +HeapAlloc dt=5 heapalloc_value=16995656 +HeapAlloc dt=5 heapalloc_value=17003848 +HeapAlloc dt=6 heapalloc_value=17012040 +HeapAlloc dt=5 heapalloc_value=17020232 +HeapAlloc dt=6 heapalloc_value=17028424 +HeapAlloc dt=5 heapalloc_value=17036616 +HeapAlloc dt=53 heapalloc_value=17044808 +HeapAlloc dt=7 heapalloc_value=17053000 +HeapAlloc dt=5 heapalloc_value=17061192 +HeapAlloc dt=6 heapalloc_value=17069384 +HeapAlloc dt=11 heapalloc_value=17077576 +HeapAlloc dt=10 heapalloc_value=17085768 +HeapAlloc dt=5 heapalloc_value=17093960 +HeapAlloc dt=5 heapalloc_value=17102152 +HeapAlloc dt=6 heapalloc_value=17110344 +HeapAlloc dt=5 heapalloc_value=17118536 +HeapAlloc dt=5 heapalloc_value=17126728 +HeapAlloc dt=6 heapalloc_value=17134920 +HeapAlloc dt=5 heapalloc_value=17143112 +HeapAlloc dt=6 heapalloc_value=17151304 +HeapAlloc dt=37 heapalloc_value=17159496 +GCBegin dt=15 gc_seq=5 stack=22 +STWBegin dt=37 kind_string=22 stack=28 +GoUnblock dt=288 g=4 g_seq=9 stack=29 +ProcsChange dt=56 procs_value=8 stack=30 +STWEnd dt=23 +GCMarkAssistBegin dt=90 stack=31 +GCMarkAssistEnd dt=3424 +HeapAlloc dt=523 heapalloc_value=17175048 +HeapAlloc dt=21 heapalloc_value=17183240 +HeapAlloc dt=46 heapalloc_value=17191432 +HeapAlloc dt=96 heapalloc_value=17199624 +HeapAlloc dt=12 heapalloc_value=17207816 +HeapAlloc dt=12 heapalloc_value=17216008 +HeapAlloc dt=13 heapalloc_value=17224200 +HeapAlloc dt=10 heapalloc_value=17232392 +HeapAlloc dt=12 heapalloc_value=17240584 +HeapAlloc dt=13 heapalloc_value=17248776 +HeapAlloc dt=12 heapalloc_value=17256968 +HeapAlloc dt=14 heapalloc_value=17265160 +HeapAlloc dt=12 heapalloc_value=17273352 +HeapAlloc dt=12 heapalloc_value=17281544 +HeapAlloc dt=11 heapalloc_value=17289736 +HeapAlloc dt=13 heapalloc_value=17297928 +HeapAlloc dt=36 heapalloc_value=17306120 +HeapAlloc dt=12 heapalloc_value=17314312 +HeapAlloc dt=10 heapalloc_value=17322504 +HeapAlloc dt=12 heapalloc_value=17330696 +HeapAlloc dt=10 heapalloc_value=17338888 +HeapAlloc dt=11 heapalloc_value=17347080 +HeapAlloc dt=10 heapalloc_value=17355272 +HeapAlloc dt=10 heapalloc_value=17363464 +HeapAlloc dt=10 heapalloc_value=17371656 +HeapAlloc dt=11 heapalloc_value=17379848 +HeapAlloc dt=8 heapalloc_value=17388040 +HeapAlloc dt=13 heapalloc_value=17396232 +HeapAlloc dt=10 heapalloc_value=17404424 +HeapAlloc dt=13 heapalloc_value=17412616 +HeapAlloc dt=13 heapalloc_value=17420808 +HeapAlloc dt=10 heapalloc_value=17429000 +HeapAlloc dt=31 heapalloc_value=17437192 +HeapAlloc dt=6 heapalloc_value=17445384 +HeapAlloc dt=7 heapalloc_value=17453576 +HeapAlloc dt=6 heapalloc_value=17461768 +HeapAlloc dt=7 heapalloc_value=17469960 +HeapAlloc dt=7 heapalloc_value=17478152 +HeapAlloc dt=7 heapalloc_value=17486344 +HeapAlloc dt=7 heapalloc_value=17494536 +HeapAlloc dt=12 heapalloc_value=17502728 +HeapAlloc dt=7 heapalloc_value=17510920 +HeapAlloc dt=12 heapalloc_value=17519112 +HeapAlloc dt=13 heapalloc_value=17527304 +HeapAlloc dt=20 heapalloc_value=17535496 +HeapAlloc dt=15 heapalloc_value=17543688 +HeapAlloc dt=6 heapalloc_value=17551880 +HeapAlloc dt=7 heapalloc_value=17560072 +HeapAlloc dt=72 heapalloc_value=17568264 +HeapAlloc dt=37 heapalloc_value=17576456 +HeapAlloc dt=7 heapalloc_value=17584648 +HeapAlloc dt=7 heapalloc_value=17592840 +HeapAlloc dt=6 heapalloc_value=17601032 +GoBlock dt=13 reason_string=19 stack=21 +GoUnblock dt=157 g=24 g_seq=12 stack=0 +GoStart dt=7 g=24 g_seq=13 +GoLabel dt=1 label_string=2 +STWBegin dt=4128 kind_string=23 stack=37 +GoUnblock dt=64 g=25 g_seq=8 stack=38 +HeapAlloc dt=25 heapalloc_value=16970376 +GoUnblock dt=24 g=3 g_seq=5 stack=39 +GCEnd dt=6 gc_seq=6 +HeapGoal dt=7 heapgoal_value=34360936 +ProcsChange dt=46 procs_value=8 stack=40 +STWEnd dt=49 +GoBlock dt=756 reason_string=15 stack=27 +GoStart dt=10 g=3 g_seq=6 +GoBlock dt=14862 reason_string=14 stack=44 +ProcStop dt=25 +ProcStart dt=132428 p=0 p_seq=32 +GoStart dt=162 g=4 g_seq=12 +GoBlock dt=19 reason_string=15 stack=32 +ProcStop dt=20 +ProcStart dt=8304 p=0 p_seq=33 +GoStart dt=191 g=39 g_seq=1 +GoStop dt=306173 reason_string=16 stack=50 +GoStart dt=17 g=39 g_seq=2 +GoStop dt=315175 reason_string=16 stack=50 +GoStart dt=7 g=39 g_seq=3 +GoDestroy dt=159902 +ProcStop dt=50 +EventBatch gen=1 m=1709040 time=7689670148204 size=3534 +ProcStart dt=256 p=1 p_seq=1 +GoStart dt=186 g=6 g_seq=1 +HeapAlloc dt=320 heapalloc_value=2768896 +HeapAlloc dt=22 heapalloc_value=2777088 +GoBlock dt=229 reason_string=12 stack=15 +GoStart dt=12 g=8 g_seq=1 +HeapAlloc dt=15 heapalloc_value=2785280 +GoSyscallBegin dt=16 p_seq=2 stack=16 +GoSyscallEnd dt=254 +GoBlock dt=293 reason_string=15 stack=17 +GoStart dt=19 g=9 g_seq=1 +GoDestroy dt=156265 +ProcStop dt=44 +ProcStart dt=67218 p=1 p_seq=3 +ProcStop dt=19 +ProcStart dt=88214 p=1 p_seq=4 +ProcStop dt=13 +ProcStart dt=17539 p=0 p_seq=1 +ProcStop dt=14 +ProcStart dt=9071 p=4 p_seq=1 +GoUnblock dt=33 g=22 g_seq=2 stack=0 +GoStart dt=6 g=22 g_seq=3 +GoLabel dt=1 label_string=4 +GoUnblock dt=2321 g=1 g_seq=23 stack=34 +STWBegin dt=1205 kind_string=23 stack=37 +GoUnblock dt=78 g=24 g_seq=6 stack=38 +HeapAlloc dt=26 heapalloc_value=3840752 +GoStatus dt=14 g=3 m=18446744073709551615 gstatus=4 +GoUnblock dt=7 g=3 g_seq=1 stack=39 +GCEnd dt=3 gc_seq=2 +HeapGoal dt=6 heapgoal_value=8101720 +ProcsChange dt=43 procs_value=8 stack=40 +STWEnd dt=31 +GoBlock dt=4030 reason_string=15 stack=27 +GoStart dt=12 g=3 g_seq=2 +GoBlock dt=1406 reason_string=14 stack=44 +ProcStop dt=24 +ProcStart dt=34332 p=4 p_seq=4 +GoStart dt=153 g=4 g_seq=4 +GoBlock dt=20 reason_string=15 stack=32 +ProcStop dt=19 +ProcStart dt=1832 p=2 p_seq=5 +GoUnblock dt=22 g=24 g_seq=8 stack=0 +GoStart dt=102 g=24 g_seq=9 +GoLabel dt=1 label_string=2 +STWBegin dt=11769 kind_string=23 stack=37 +GoUnblock dt=60 g=1 g_seq=36 stack=38 +HeapAlloc dt=23 heapalloc_value=8744264 +GoUnblock dt=17 g=3 g_seq=3 stack=39 +GCEnd dt=6 gc_seq=4 +HeapGoal dt=7 heapgoal_value=17908728 +ProcsChange dt=47 procs_value=8 stack=40 +STWEnd dt=28 +GoBlock dt=572 reason_string=15 stack=27 +GoStart dt=13 g=3 g_seq=4 +GoBlock dt=5707 reason_string=14 stack=44 +ProcStop dt=16 +ProcStart dt=136502 p=1 p_seq=11 +GoStart dt=17 g=4 g_seq=8 +GoBlock dt=12 reason_string=15 stack=32 +ProcStop dt=22 +ProcStart dt=5977 p=6 p_seq=1 +ProcStop dt=34 +ProcStart dt=16775 p=2 p_seq=15 +ProcStop dt=23 +ProcStart dt=3966 p=1 p_seq=14 +ProcStop dt=15 +ProcStart dt=16753 p=1 p_seq=15 +GoUnblock dt=35 g=1 g_seq=57 stack=0 +GoStart dt=139 g=1 g_seq=58 +HeapAlloc dt=71 heapalloc_value=17593992 +HeapAlloc dt=47 heapalloc_value=17602184 +HeapAlloc dt=24 heapalloc_value=17610376 +HeapAlloc dt=97 heapalloc_value=17618568 +HeapAlloc dt=23 heapalloc_value=17626760 +HeapAlloc dt=18 heapalloc_value=17634952 +HeapAlloc dt=15 heapalloc_value=17643144 +HeapAlloc dt=18 heapalloc_value=17651336 +HeapAlloc dt=21 heapalloc_value=17659528 +HeapAlloc dt=28 heapalloc_value=17667720 +HeapAlloc dt=26 heapalloc_value=17675912 +HeapAlloc dt=23 heapalloc_value=17684104 +HeapAlloc dt=12 heapalloc_value=17692296 +HeapAlloc dt=12 heapalloc_value=17700488 +HeapAlloc dt=11 heapalloc_value=17708680 +HeapAlloc dt=15 heapalloc_value=17716872 +HeapAlloc dt=18 heapalloc_value=17725064 +HeapAlloc dt=15 heapalloc_value=17733256 +HeapAlloc dt=165 heapalloc_value=17741448 +HeapAlloc dt=16 heapalloc_value=17749640 +HeapAlloc dt=12 heapalloc_value=17757832 +HeapAlloc dt=15 heapalloc_value=17766024 +HeapAlloc dt=12 heapalloc_value=17774216 +HeapAlloc dt=12 heapalloc_value=17782408 +HeapAlloc dt=15 heapalloc_value=17790600 +HeapAlloc dt=11 heapalloc_value=17798792 +HeapAlloc dt=11 heapalloc_value=17806984 +HeapAlloc dt=12 heapalloc_value=17815176 +HeapAlloc dt=12 heapalloc_value=17823368 +HeapAlloc dt=15 heapalloc_value=17831560 +HeapAlloc dt=11 heapalloc_value=17839752 +HeapAlloc dt=12 heapalloc_value=17847944 +HeapAlloc dt=15 heapalloc_value=17856136 +HeapAlloc dt=11 heapalloc_value=17864328 +HeapAlloc dt=12 heapalloc_value=17872520 +HeapAlloc dt=12 heapalloc_value=17880712 +HeapAlloc dt=14 heapalloc_value=17888904 +HeapAlloc dt=42 heapalloc_value=17897096 +HeapAlloc dt=54 heapalloc_value=17905288 +HeapAlloc dt=49 heapalloc_value=17913480 +HeapAlloc dt=54 heapalloc_value=17921672 +HeapAlloc dt=56 heapalloc_value=17929864 +HeapAlloc dt=45 heapalloc_value=17938056 +HeapAlloc dt=57 heapalloc_value=17946248 +HeapAlloc dt=63 heapalloc_value=17954440 +HeapAlloc dt=57 heapalloc_value=17962632 +HeapAlloc dt=56 heapalloc_value=17970824 +HeapAlloc dt=62 heapalloc_value=17979016 +HeapAlloc dt=109 heapalloc_value=17987208 +HeapAlloc dt=59 heapalloc_value=17995400 +HeapAlloc dt=45 heapalloc_value=18003592 +HeapAlloc dt=61 heapalloc_value=18011784 +HeapAlloc dt=35 heapalloc_value=18019976 +HeapAlloc dt=16 heapalloc_value=18028168 +HeapAlloc dt=15 heapalloc_value=18036360 +HeapAlloc dt=15 heapalloc_value=18044552 +HeapAlloc dt=21 heapalloc_value=18052744 +HeapAlloc dt=16 heapalloc_value=18060936 +HeapAlloc dt=16 heapalloc_value=18069128 +HeapAlloc dt=22 heapalloc_value=18077320 +HeapAlloc dt=43 heapalloc_value=18085512 +HeapAlloc dt=46 heapalloc_value=18093704 +HeapAlloc dt=43 heapalloc_value=18101896 +HeapAlloc dt=42 heapalloc_value=18110088 +HeapAlloc dt=44 heapalloc_value=18118280 +HeapAlloc dt=35 heapalloc_value=18126472 +HeapAlloc dt=39 heapalloc_value=18134664 +HeapAlloc dt=40 heapalloc_value=18142856 +HeapAlloc dt=43 heapalloc_value=18151048 +HeapAlloc dt=44 heapalloc_value=18159240 +HeapAlloc dt=38 heapalloc_value=18167432 +HeapAlloc dt=42 heapalloc_value=18175624 +HeapAlloc dt=40 heapalloc_value=18183816 +HeapAlloc dt=40 heapalloc_value=18192008 +HeapAlloc dt=36 heapalloc_value=18200200 +HeapAlloc dt=55 heapalloc_value=18208392 +HeapAlloc dt=54 heapalloc_value=18216584 +HeapAlloc dt=54 heapalloc_value=18224776 +HeapAlloc dt=41 heapalloc_value=18232968 +HeapAlloc dt=58 heapalloc_value=18241160 +HeapAlloc dt=61 heapalloc_value=18249352 +HeapAlloc dt=55 heapalloc_value=18257544 +HeapAlloc dt=141 heapalloc_value=18265736 +HeapAlloc dt=55 heapalloc_value=18273928 +HeapAlloc dt=54 heapalloc_value=18282120 +HeapAlloc dt=50 heapalloc_value=18290312 +HeapAlloc dt=82 heapalloc_value=18298504 +HeapAlloc dt=64 heapalloc_value=18306696 +HeapAlloc dt=55 heapalloc_value=18314888 +HeapAlloc dt=58 heapalloc_value=18323080 +HeapAlloc dt=54 heapalloc_value=18331272 +HeapAlloc dt=57 heapalloc_value=18339464 +HeapAlloc dt=46 heapalloc_value=18347656 +HeapAlloc dt=41 heapalloc_value=18355848 +HeapAlloc dt=56 heapalloc_value=18364040 +HeapAlloc dt=50 heapalloc_value=18372232 +HeapAlloc dt=54 heapalloc_value=18380424 +HeapAlloc dt=56 heapalloc_value=18388616 +HeapAlloc dt=57 heapalloc_value=18396808 +HeapAlloc dt=55 heapalloc_value=18405000 +HeapAlloc dt=55 heapalloc_value=18413192 +HeapAlloc dt=51 heapalloc_value=18421384 +HeapAlloc dt=52 heapalloc_value=18429576 +HeapAlloc dt=67 heapalloc_value=18437768 +HeapAlloc dt=36 heapalloc_value=18445960 +HeapAlloc dt=28 heapalloc_value=18454152 +HeapAlloc dt=30 heapalloc_value=18462344 +HeapAlloc dt=40 heapalloc_value=18470536 +HeapAlloc dt=29 heapalloc_value=18478728 +HeapAlloc dt=37 heapalloc_value=18486920 +HeapAlloc dt=34 heapalloc_value=18495112 +HeapAlloc dt=73 heapalloc_value=18503304 +HeapAlloc dt=37 heapalloc_value=18511496 +HeapAlloc dt=38 heapalloc_value=18519688 +HeapAlloc dt=29 heapalloc_value=18527880 +HeapAlloc dt=35 heapalloc_value=18536072 +HeapAlloc dt=33 heapalloc_value=18544264 +HeapAlloc dt=40 heapalloc_value=18552456 +HeapAlloc dt=32 heapalloc_value=18560648 +HeapAlloc dt=42 heapalloc_value=18568840 +HeapAlloc dt=34 heapalloc_value=18577032 +HeapAlloc dt=37 heapalloc_value=18585224 +HeapAlloc dt=35 heapalloc_value=18593416 +HeapAlloc dt=39 heapalloc_value=18601608 +HeapAlloc dt=35 heapalloc_value=18609800 +GoBlock dt=51 reason_string=19 stack=21 +ProcStop dt=192 +ProcStart dt=17579 p=0 p_seq=27 +ProcStop dt=18 +ProcStart dt=1930 p=1 p_seq=18 +ProcStop dt=15 +ProcStart dt=16696 p=1 p_seq=19 +GoUnblock dt=22 g=1 g_seq=61 stack=0 +GoStart dt=125 g=1 g_seq=62 +HeapAlloc dt=53 heapalloc_value=19641992 +HeapAlloc dt=19 heapalloc_value=19650184 +HeapAlloc dt=20 heapalloc_value=19658376 +HeapAlloc dt=23 heapalloc_value=19666568 +HeapAlloc dt=16 heapalloc_value=19674760 +HeapAlloc dt=16 heapalloc_value=19682952 +HeapAlloc dt=19 heapalloc_value=19691144 +HeapAlloc dt=15 heapalloc_value=19699336 +HeapAlloc dt=12 heapalloc_value=19707528 +HeapAlloc dt=12 heapalloc_value=19715720 +HeapAlloc dt=13 heapalloc_value=19723912 +HeapAlloc dt=18 heapalloc_value=19732104 +HeapAlloc dt=12 heapalloc_value=19740296 +HeapAlloc dt=12 heapalloc_value=19748488 +HeapAlloc dt=9 heapalloc_value=19756680 +HeapAlloc dt=6 heapalloc_value=19764872 +HeapAlloc dt=5 heapalloc_value=19773064 +HeapAlloc dt=6 heapalloc_value=19781256 +HeapAlloc dt=5 heapalloc_value=19789448 +HeapAlloc dt=10 heapalloc_value=19797640 +HeapAlloc dt=5 heapalloc_value=19805832 +HeapAlloc dt=6 heapalloc_value=19814024 +HeapAlloc dt=9 heapalloc_value=19822216 +HeapAlloc dt=6 heapalloc_value=19830408 +HeapAlloc dt=117 heapalloc_value=19838600 +HeapAlloc dt=17 heapalloc_value=19846792 +HeapAlloc dt=5 heapalloc_value=19854984 +HeapAlloc dt=10 heapalloc_value=19863176 +HeapAlloc dt=6 heapalloc_value=19871368 +HeapAlloc dt=6 heapalloc_value=19879560 +HeapAlloc dt=9 heapalloc_value=19887752 +HeapAlloc dt=6 heapalloc_value=19895944 +HeapAlloc dt=6 heapalloc_value=19904136 +HeapAlloc dt=5 heapalloc_value=19912328 +HeapAlloc dt=6 heapalloc_value=19920520 +HeapAlloc dt=10 heapalloc_value=19928712 +HeapAlloc dt=5 heapalloc_value=19936904 +HeapAlloc dt=6 heapalloc_value=19945096 +HeapAlloc dt=9 heapalloc_value=19953288 +HeapAlloc dt=6 heapalloc_value=19961480 +HeapAlloc dt=35 heapalloc_value=19969672 +HeapAlloc dt=7 heapalloc_value=19977864 +HeapAlloc dt=5 heapalloc_value=19986056 +HeapAlloc dt=468 heapalloc_value=19994248 +HeapAlloc dt=14 heapalloc_value=20002440 +HeapAlloc dt=6 heapalloc_value=20010632 +HeapAlloc dt=10 heapalloc_value=20018824 +HeapAlloc dt=5 heapalloc_value=20027016 +HeapAlloc dt=6 heapalloc_value=20035208 +HeapAlloc dt=11 heapalloc_value=20043400 +HeapAlloc dt=6 heapalloc_value=20051592 +HeapAlloc dt=5 heapalloc_value=20059784 +HeapAlloc dt=6 heapalloc_value=20067976 +HeapAlloc dt=5 heapalloc_value=20076168 +HeapAlloc dt=7 heapalloc_value=20084360 +HeapAlloc dt=6 heapalloc_value=20092552 +HeapAlloc dt=5 heapalloc_value=20100744 +HeapAlloc dt=6 heapalloc_value=20108936 +HeapAlloc dt=6 heapalloc_value=20117128 +HeapAlloc dt=5 heapalloc_value=20125320 +HeapAlloc dt=6 heapalloc_value=20133512 +HeapAlloc dt=6 heapalloc_value=20141704 +HeapAlloc dt=7 heapalloc_value=20149896 +HeapAlloc dt=5 heapalloc_value=20158088 +HeapAlloc dt=6 heapalloc_value=20166280 +HeapAlloc dt=5 heapalloc_value=20174472 +HeapAlloc dt=6 heapalloc_value=20182664 +HeapAlloc dt=6 heapalloc_value=20190856 +HeapAlloc dt=5 heapalloc_value=20199048 +HeapAlloc dt=5 heapalloc_value=20207240 +HeapAlloc dt=6 heapalloc_value=20215432 +HeapAlloc dt=6 heapalloc_value=20223624 +HeapAlloc dt=5 heapalloc_value=20231816 +HeapAlloc dt=6 heapalloc_value=20240008 +HeapAlloc dt=5 heapalloc_value=20248200 +HeapAlloc dt=5 heapalloc_value=20256392 +HeapAlloc dt=6 heapalloc_value=20264584 +HeapAlloc dt=5 heapalloc_value=20272776 +HeapAlloc dt=6 heapalloc_value=20280968 +HeapAlloc dt=5 heapalloc_value=20289160 +HeapAlloc dt=6 heapalloc_value=20297352 +HeapAlloc dt=5 heapalloc_value=20305544 +HeapAlloc dt=6 heapalloc_value=20313736 +HeapAlloc dt=5 heapalloc_value=20321928 +HeapAlloc dt=6 heapalloc_value=20330120 +HeapAlloc dt=5 heapalloc_value=20338312 +HeapAlloc dt=6 heapalloc_value=20346504 +HeapAlloc dt=6 heapalloc_value=20354696 +HeapAlloc dt=62 heapalloc_value=20362888 +HeapAlloc dt=7 heapalloc_value=20371080 +HeapAlloc dt=5 heapalloc_value=20379272 +HeapAlloc dt=6 heapalloc_value=20387464 +HeapAlloc dt=37 heapalloc_value=20395656 +HeapAlloc dt=7 heapalloc_value=20403848 +HeapAlloc dt=6 heapalloc_value=20412040 +HeapAlloc dt=5 heapalloc_value=20420232 +HeapAlloc dt=6 heapalloc_value=20428424 +HeapAlloc dt=5 heapalloc_value=20436616 +HeapAlloc dt=6 heapalloc_value=20444808 +HeapAlloc dt=5 heapalloc_value=20453000 +HeapAlloc dt=6 heapalloc_value=20461192 +HeapAlloc dt=5 heapalloc_value=20469384 +HeapAlloc dt=6 heapalloc_value=20477576 +HeapAlloc dt=5 heapalloc_value=20485768 +HeapAlloc dt=6 heapalloc_value=20493960 +HeapAlloc dt=5 heapalloc_value=20502152 +HeapAlloc dt=6 heapalloc_value=20510344 +HeapAlloc dt=9 heapalloc_value=20518536 +HeapAlloc dt=6 heapalloc_value=20526728 +HeapAlloc dt=5 heapalloc_value=20534920 +HeapAlloc dt=6 heapalloc_value=20543112 +HeapAlloc dt=5 heapalloc_value=20551304 +HeapAlloc dt=6 heapalloc_value=20559496 +HeapAlloc dt=5 heapalloc_value=20567688 +HeapAlloc dt=6 heapalloc_value=20575880 +HeapAlloc dt=5 heapalloc_value=20584072 +HeapAlloc dt=6 heapalloc_value=20592264 +HeapAlloc dt=38 heapalloc_value=20600456 +HeapAlloc dt=7 heapalloc_value=20608648 +HeapAlloc dt=5 heapalloc_value=20616840 +HeapAlloc dt=6 heapalloc_value=20625032 +HeapAlloc dt=5 heapalloc_value=20633224 +HeapAlloc dt=6 heapalloc_value=20641416 +HeapAlloc dt=5 heapalloc_value=20649608 +HeapAlloc dt=6 heapalloc_value=20657800 +GoBlock dt=12 reason_string=19 stack=21 +ProcStop dt=167 +ProcStart dt=17576 p=0 p_seq=29 +ProcStop dt=20 +ProcStart dt=3256 p=1 p_seq=22 +ProcStop dt=17 +ProcStart dt=16071 p=1 p_seq=23 +GoUnblock dt=21 g=1 g_seq=65 stack=0 +GoStart dt=124 g=1 g_seq=66 +HeapAlloc dt=51 heapalloc_value=22230664 +HeapAlloc dt=26 heapalloc_value=22238856 +HeapAlloc dt=16 heapalloc_value=22247048 +HeapAlloc dt=19 heapalloc_value=22255240 +HeapAlloc dt=19 heapalloc_value=22263432 +HeapAlloc dt=16 heapalloc_value=22271624 +HeapAlloc dt=16 heapalloc_value=22279816 +HeapAlloc dt=19 heapalloc_value=22288008 +HeapAlloc dt=18 heapalloc_value=22296200 +HeapAlloc dt=16 heapalloc_value=22304392 +HeapAlloc dt=12 heapalloc_value=22312584 +HeapAlloc dt=13 heapalloc_value=22320776 +HeapAlloc dt=15 heapalloc_value=22328968 +HeapAlloc dt=12 heapalloc_value=22337160 +HeapAlloc dt=6 heapalloc_value=22345352 +HeapAlloc dt=8 heapalloc_value=22353544 +HeapAlloc dt=6 heapalloc_value=22361736 +HeapAlloc dt=5 heapalloc_value=22369928 +HeapAlloc dt=25 heapalloc_value=22378120 +HeapAlloc dt=23 heapalloc_value=22386312 +HeapAlloc dt=9 heapalloc_value=22394504 +HeapAlloc dt=6 heapalloc_value=22402696 +HeapAlloc dt=5 heapalloc_value=22410888 +HeapAlloc dt=10 heapalloc_value=22419080 +HeapAlloc dt=5 heapalloc_value=22427272 +HeapAlloc dt=6 heapalloc_value=22435464 +HeapAlloc dt=5 heapalloc_value=22443656 +HeapAlloc dt=6 heapalloc_value=22451848 +HeapAlloc dt=8 heapalloc_value=22460040 +HeapAlloc dt=135 heapalloc_value=22468232 +HeapAlloc dt=8 heapalloc_value=22476424 +HeapAlloc dt=9 heapalloc_value=22484616 +HeapAlloc dt=6 heapalloc_value=22492808 +HeapAlloc dt=6 heapalloc_value=22501000 +HeapAlloc dt=6 heapalloc_value=22509192 +HeapAlloc dt=5 heapalloc_value=22517384 +HeapAlloc dt=9 heapalloc_value=22525576 +HeapAlloc dt=6 heapalloc_value=22533768 +HeapAlloc dt=6 heapalloc_value=22541960 +HeapAlloc dt=5 heapalloc_value=22550152 +HeapAlloc dt=6 heapalloc_value=22558344 +HeapAlloc dt=5 heapalloc_value=22566536 +HeapAlloc dt=6 heapalloc_value=22574728 +HeapAlloc dt=5 heapalloc_value=22582920 +HeapAlloc dt=9 heapalloc_value=22591112 +HeapAlloc dt=44 heapalloc_value=22599304 +HeapAlloc dt=7 heapalloc_value=22607496 +HeapAlloc dt=38 heapalloc_value=22615688 +HeapAlloc dt=6 heapalloc_value=22623880 +HeapAlloc dt=6 heapalloc_value=22632072 +HeapAlloc dt=6 heapalloc_value=22640264 +HeapAlloc dt=6 heapalloc_value=22648456 +HeapAlloc dt=6 heapalloc_value=22656648 +HeapAlloc dt=5 heapalloc_value=22664840 +HeapAlloc dt=6 heapalloc_value=22673032 +HeapAlloc dt=5 heapalloc_value=22681224 +HeapAlloc dt=6 heapalloc_value=22689416 +HeapAlloc dt=5 heapalloc_value=22697608 +HeapAlloc dt=6 heapalloc_value=22705800 +HeapAlloc dt=6 heapalloc_value=22713992 +HeapAlloc dt=5 heapalloc_value=22722184 +HeapAlloc dt=5 heapalloc_value=22730376 +HeapAlloc dt=6 heapalloc_value=22738568 +HeapAlloc dt=6 heapalloc_value=22746760 +HeapAlloc dt=5 heapalloc_value=22754952 +HeapAlloc dt=6 heapalloc_value=22763144 +HeapAlloc dt=6 heapalloc_value=22771336 +HeapAlloc dt=6 heapalloc_value=22779528 +HeapAlloc dt=5 heapalloc_value=22787720 +HeapAlloc dt=5 heapalloc_value=22795912 +HeapAlloc dt=6 heapalloc_value=22804104 +HeapAlloc dt=75 heapalloc_value=22812296 +HeapAlloc dt=7 heapalloc_value=22820488 +HeapAlloc dt=5 heapalloc_value=22828680 +HeapAlloc dt=6 heapalloc_value=22836872 +HeapAlloc dt=5 heapalloc_value=22845064 +HeapAlloc dt=6 heapalloc_value=22853256 +HeapAlloc dt=6 heapalloc_value=22861448 +HeapAlloc dt=5 heapalloc_value=22869640 +HeapAlloc dt=6 heapalloc_value=22877832 +HeapAlloc dt=5 heapalloc_value=22886024 +HeapAlloc dt=5 heapalloc_value=22894216 +HeapAlloc dt=6 heapalloc_value=22902408 +HeapAlloc dt=7 heapalloc_value=22910600 +HeapAlloc dt=6 heapalloc_value=22918792 +HeapAlloc dt=5 heapalloc_value=22926984 +HeapAlloc dt=6 heapalloc_value=22935176 +HeapAlloc dt=6 heapalloc_value=22943368 +HeapAlloc dt=6 heapalloc_value=22951560 +HeapAlloc dt=5 heapalloc_value=22959752 +HeapAlloc dt=6 heapalloc_value=22967944 +HeapAlloc dt=7 heapalloc_value=22976136 +HeapAlloc dt=5 heapalloc_value=22984328 +HeapAlloc dt=43 heapalloc_value=22992520 +HeapAlloc dt=7 heapalloc_value=23000712 +HeapAlloc dt=5 heapalloc_value=23008904 +HeapAlloc dt=6 heapalloc_value=23017096 +HeapAlloc dt=35 heapalloc_value=23025288 +HeapAlloc dt=7 heapalloc_value=23033480 +HeapAlloc dt=5 heapalloc_value=23041672 +HeapAlloc dt=5 heapalloc_value=23049864 +HeapAlloc dt=6 heapalloc_value=23058056 +HeapAlloc dt=5 heapalloc_value=23066248 +HeapAlloc dt=6 heapalloc_value=23074440 +HeapAlloc dt=5 heapalloc_value=23082632 +HeapAlloc dt=6 heapalloc_value=23090824 +HeapAlloc dt=5 heapalloc_value=23099016 +HeapAlloc dt=6 heapalloc_value=23107208 +HeapAlloc dt=5 heapalloc_value=23115400 +HeapAlloc dt=6 heapalloc_value=23123592 +HeapAlloc dt=5 heapalloc_value=23131784 +HeapAlloc dt=12 heapalloc_value=23139976 +HeapAlloc dt=5 heapalloc_value=23148168 +HeapAlloc dt=6 heapalloc_value=23156360 +HeapAlloc dt=5 heapalloc_value=23164552 +HeapAlloc dt=6 heapalloc_value=23172744 +HeapAlloc dt=5 heapalloc_value=23180936 +HeapAlloc dt=6 heapalloc_value=23189128 +HeapAlloc dt=5 heapalloc_value=23197320 +HeapAlloc dt=7 heapalloc_value=23205512 +HeapAlloc dt=5 heapalloc_value=23213704 +HeapAlloc dt=6 heapalloc_value=23221896 +HeapAlloc dt=38 heapalloc_value=23230088 +HeapAlloc dt=7 heapalloc_value=23238280 +HeapAlloc dt=5 heapalloc_value=23246472 +GoBlock dt=9 reason_string=19 stack=21 +ProcStop dt=164 +ProcStart dt=17494 p=0 p_seq=31 +ProcStop dt=25 +ProcStart dt=1701 p=1 p_seq=26 +ProcStop dt=16 +ProcStart dt=16748 p=2 p_seq=17 +GoUnblock dt=36 g=1 g_seq=71 stack=0 +GoStart dt=149 g=1 g_seq=72 +HeapAlloc dt=67 heapalloc_value=25302664 +HeapAlloc dt=38 heapalloc_value=25310856 +HeapAlloc dt=23 heapalloc_value=25319048 +HeapAlloc dt=17 heapalloc_value=25327240 +HeapAlloc dt=21 heapalloc_value=25335432 +HeapAlloc dt=17 heapalloc_value=25343624 +HeapAlloc dt=17 heapalloc_value=25351816 +HeapAlloc dt=16 heapalloc_value=25360008 +HeapAlloc dt=19 heapalloc_value=25368200 +HeapAlloc dt=16 heapalloc_value=25376392 +HeapAlloc dt=16 heapalloc_value=25384584 +HeapAlloc dt=16 heapalloc_value=25392776 +HeapAlloc dt=17 heapalloc_value=25400968 +HeapAlloc dt=16 heapalloc_value=25409160 +HeapAlloc dt=9 heapalloc_value=25417352 +HeapAlloc dt=9 heapalloc_value=25425544 +HeapAlloc dt=9 heapalloc_value=25433736 +HeapAlloc dt=10 heapalloc_value=25441928 +HeapAlloc dt=9 heapalloc_value=25450120 +HeapAlloc dt=10 heapalloc_value=25458312 +HeapAlloc dt=9 heapalloc_value=25466504 +HeapAlloc dt=6 heapalloc_value=25474696 +HeapAlloc dt=5 heapalloc_value=25482888 +HeapAlloc dt=6 heapalloc_value=25491080 +HeapAlloc dt=9 heapalloc_value=25499272 +HeapAlloc dt=6 heapalloc_value=25507464 +HeapAlloc dt=8 heapalloc_value=25515656 +HeapAlloc dt=7 heapalloc_value=25523848 +HeapAlloc dt=10 heapalloc_value=25532040 +HeapAlloc dt=9 heapalloc_value=25540232 +HeapAlloc dt=102 heapalloc_value=25548424 +HeapAlloc dt=7 heapalloc_value=25556616 +HeapAlloc dt=10 heapalloc_value=25564808 +HeapAlloc dt=5 heapalloc_value=25573000 +HeapAlloc dt=5 heapalloc_value=25581192 +HeapAlloc dt=36 heapalloc_value=25589384 +HeapAlloc dt=8 heapalloc_value=25597576 +HeapAlloc dt=5 heapalloc_value=25605768 +HeapAlloc dt=43 heapalloc_value=25613960 +HeapAlloc dt=7 heapalloc_value=25622152 +HeapAlloc dt=10 heapalloc_value=25630344 +HeapAlloc dt=6 heapalloc_value=25638536 +HeapAlloc dt=6 heapalloc_value=25646728 +HeapAlloc dt=6 heapalloc_value=25654920 +HeapAlloc dt=7 heapalloc_value=25663112 +HeapAlloc dt=5 heapalloc_value=25671304 +HeapAlloc dt=6 heapalloc_value=25679496 +HeapAlloc dt=41 heapalloc_value=25687688 +HeapAlloc dt=13 heapalloc_value=25695880 +HeapAlloc dt=5 heapalloc_value=25704072 +HeapAlloc dt=6 heapalloc_value=25712264 +HeapAlloc dt=13 heapalloc_value=25720456 +HeapAlloc dt=13 heapalloc_value=25728648 +HeapAlloc dt=5 heapalloc_value=25736840 +HeapAlloc dt=6 heapalloc_value=25745032 +HeapAlloc dt=6 heapalloc_value=25753224 +HeapAlloc dt=9 heapalloc_value=25761416 +HeapAlloc dt=6 heapalloc_value=25769608 +HeapAlloc dt=5 heapalloc_value=25777800 +HeapAlloc dt=6 heapalloc_value=25785992 +HeapAlloc dt=5 heapalloc_value=25794184 +HeapAlloc dt=6 heapalloc_value=25802376 +HeapAlloc dt=5 heapalloc_value=25810568 +HeapAlloc dt=6 heapalloc_value=25818760 +HeapAlloc dt=10 heapalloc_value=25826952 +HeapAlloc dt=6 heapalloc_value=25835144 +HeapAlloc dt=6 heapalloc_value=25843336 +HeapAlloc dt=5 heapalloc_value=25851528 +HeapAlloc dt=6 heapalloc_value=25859720 +HeapAlloc dt=5 heapalloc_value=25867912 +HeapAlloc dt=6 heapalloc_value=25876104 +HeapAlloc dt=6 heapalloc_value=25884296 +HeapAlloc dt=7 heapalloc_value=25892488 +HeapAlloc dt=6 heapalloc_value=25900680 +HeapAlloc dt=5 heapalloc_value=25908872 +HeapAlloc dt=6 heapalloc_value=25917064 +HeapAlloc dt=6 heapalloc_value=25925256 +HeapAlloc dt=5 heapalloc_value=25933448 +HeapAlloc dt=6 heapalloc_value=25941640 +HeapAlloc dt=6 heapalloc_value=25949832 +HeapAlloc dt=6 heapalloc_value=25958024 +HeapAlloc dt=5 heapalloc_value=25966216 +HeapAlloc dt=6 heapalloc_value=25974408 +HeapAlloc dt=5 heapalloc_value=25982600 +HeapAlloc dt=6 heapalloc_value=25990792 +HeapAlloc dt=6 heapalloc_value=25998984 +HeapAlloc dt=5 heapalloc_value=26007176 +HeapAlloc dt=6 heapalloc_value=26015368 +HeapAlloc dt=6 heapalloc_value=26023560 +HeapAlloc dt=6 heapalloc_value=26031752 +HeapAlloc dt=5 heapalloc_value=26039944 +HeapAlloc dt=6 heapalloc_value=26048136 +HeapAlloc dt=5 heapalloc_value=26056328 +HeapAlloc dt=6 heapalloc_value=26064520 +HeapAlloc dt=94 heapalloc_value=26072712 +HeapAlloc dt=7 heapalloc_value=26080904 +HeapAlloc dt=5 heapalloc_value=26089096 +HeapAlloc dt=6 heapalloc_value=26097288 +HeapAlloc dt=6 heapalloc_value=26105480 +HeapAlloc dt=5 heapalloc_value=26113672 +HeapAlloc dt=6 heapalloc_value=26121864 +HeapAlloc dt=6 heapalloc_value=26130056 +HeapAlloc dt=5 heapalloc_value=26138248 +HeapAlloc dt=6 heapalloc_value=26146440 +HeapAlloc dt=6 heapalloc_value=26154632 +HeapAlloc dt=5 heapalloc_value=26162824 +HeapAlloc dt=1696 heapalloc_value=26171016 +HeapAlloc dt=7 heapalloc_value=26179208 +HeapAlloc dt=6 heapalloc_value=26187400 +HeapAlloc dt=5 heapalloc_value=26195592 +HeapAlloc dt=6 heapalloc_value=26203784 +HeapAlloc dt=5 heapalloc_value=26211976 +HeapAlloc dt=47 heapalloc_value=26220168 +HeapAlloc dt=8 heapalloc_value=26228360 +HeapAlloc dt=5 heapalloc_value=26236552 +HeapAlloc dt=6 heapalloc_value=26244744 +HeapAlloc dt=6 heapalloc_value=26252936 +HeapAlloc dt=5 heapalloc_value=26261128 +HeapAlloc dt=6 heapalloc_value=26269320 +HeapAlloc dt=5 heapalloc_value=26277512 +HeapAlloc dt=6 heapalloc_value=26285704 +HeapAlloc dt=6 heapalloc_value=26293896 +HeapAlloc dt=5 heapalloc_value=26302088 +HeapAlloc dt=6 heapalloc_value=26310280 +HeapAlloc dt=6 heapalloc_value=26318472 +HeapAlloc dt=30 heapalloc_value=26326360 +HeapAlloc dt=30 heapalloc_value=26334536 +HeapAlloc dt=24 heapalloc_value=26336904 +GoCreate dt=72 new_g=34 new_stack=47 stack=48 +GoCreate dt=183 new_g=35 new_stack=47 stack=48 +GoCreate dt=15 new_g=36 new_stack=47 stack=48 +GoCreate dt=12 new_g=37 new_stack=47 stack=48 +GoCreate dt=14 new_g=38 new_stack=47 stack=48 +HeapAlloc dt=25 heapalloc_value=26344200 +GoCreate dt=9 new_g=39 new_stack=47 stack=48 +GoCreate dt=13 new_g=40 new_stack=47 stack=48 +GoCreate dt=4 new_g=41 new_stack=47 stack=48 +HeapAlloc dt=17 heapalloc_value=26351912 +GoBlock dt=15 reason_string=10 stack=49 +GoStart dt=5 g=41 g_seq=1 +GoStop dt=307427 reason_string=16 stack=51 +GoStart dt=34 g=41 g_seq=2 +GoStop dt=315328 reason_string=16 stack=50 +GoStart dt=10 g=41 g_seq=3 +GoDestroy dt=158464 +ProcStop dt=40 +EventBatch gen=1 m=1709039 time=7689670530705 size=53 +GoUnblock dt=117 g=4 g_seq=3 stack=0 +GoUnblock dt=157408 g=4 g_seq=7 stack=0 +GoUnblock dt=157553 g=4 g_seq=11 stack=0 +ProcSteal dt=947714 p=7 p_seq=9 m=1709048 +ProcSteal dt=646055 p=7 p_seq=13 m=1709046 +ProcSteal dt=5677 p=5 p_seq=11 m=1709046 +ProcSteal dt=1312 p=6 p_seq=9 m=1709048 +EventBatch gen=1 m=1709038 time=7689670147327 size=336 +ProcStatus dt=56 p=0 pstatus=1 +GoStatus dt=4 g=1 m=1709038 gstatus=2 +ProcsChange dt=184 procs_value=8 stack=1 +STWBegin dt=81 kind_string=21 stack=2 +HeapGoal dt=5 heapgoal_value=4194304 +ProcStatus dt=2 p=1 pstatus=2 +ProcStatus dt=1 p=2 pstatus=2 +ProcStatus dt=1 p=3 pstatus=2 +ProcStatus dt=1 p=4 pstatus=2 +ProcStatus dt=1 p=5 pstatus=2 +ProcStatus dt=1 p=6 pstatus=2 +ProcStatus dt=1 p=7 pstatus=2 +ProcsChange dt=51 procs_value=8 stack=3 +STWEnd dt=74 +GoCreate dt=216 new_g=6 new_stack=4 stack=5 +HeapAlloc dt=174 heapalloc_value=2752512 +GoCreate dt=140 new_g=7 new_stack=6 stack=7 +HeapAlloc dt=16 heapalloc_value=2760704 +GoCreate dt=11 new_g=8 new_stack=8 stack=9 +GoCreate dt=197 new_g=9 new_stack=10 stack=11 +GoCreate dt=18 new_g=10 new_stack=12 stack=13 +GoBlock dt=159 reason_string=10 stack=14 +GoStart dt=10 g=10 g_seq=1 +GoStop dt=224159 reason_string=16 stack=19 +GoStart dt=105 g=10 g_seq=2 +GoUnblock dt=88262 g=1 g_seq=1 stack=20 +GoDestroy dt=111 +GoStart dt=10 g=1 g_seq=2 +GoBlock dt=18 reason_string=19 stack=21 +ProcStop dt=177 +ProcStart dt=22598 p=0 p_seq=2 +ProcStop dt=20 +ProcStart dt=30 p=2 p_seq=2 +ProcStop dt=1158 +ProcStart dt=1116 p=0 p_seq=4 +GoUnblock dt=19 g=25 g_seq=2 stack=0 +GoStart dt=130 g=25 g_seq=3 +GoLabel dt=1 label_string=2 +GoBlock dt=1809 reason_string=15 stack=27 +ProcStop dt=35 +ProcStart dt=45680 p=3 p_seq=4 +HeapAlloc dt=46 heapalloc_value=7659248 +HeapAlloc dt=48 heapalloc_value=7663408 +HeapAlloc dt=6065 heapalloc_value=7876144 +GoStart dt=2865 g=4 g_seq=6 +GoBlock dt=31 reason_string=15 stack=32 +ProcStop dt=49 +ProcStart dt=1490 p=3 p_seq=5 +ProcStop dt=29 +ProcStart dt=2071 p=1 p_seq=10 +ProcStop dt=21 +ProcStart dt=143297 p=2 p_seq=13 +GoUnblock dt=21 g=22 g_seq=6 stack=0 +GoStart dt=177 g=22 g_seq=7 +GoLabel dt=2 label_string=2 +GoBlock dt=2058 reason_string=15 stack=27 +ProcStop dt=2352 +ProcStart dt=162401 p=5 p_seq=2 +HeapAlloc dt=51 heapalloc_value=26353960 +HeapAlloc dt=42 heapalloc_value=26360360 +HeapAlloc dt=6510 heapalloc_value=26367784 +GoStart dt=1039 g=40 g_seq=1 +GoStop dt=297000 reason_string=16 stack=50 +GoStart dt=15 g=40 g_seq=2 +GoStop dt=315522 reason_string=16 stack=50 +GoStart dt=7 g=40 g_seq=3 +GoDestroy dt=168735 +ProcStop dt=43 +ProcStart dt=799345 p=6 p_seq=6 +ProcStop dt=33 +ProcStart dt=1506 p=6 p_seq=10 +ProcStop dt=26 +ProcStart dt=18634 p=7 p_seq=33 +ProcStop dt=34 +EventBatch gen=1 m=18446744073709551615 time=7689672466616 size=28 +GoStatus dt=61 g=2 m=18446744073709551615 gstatus=4 +GoStatus dt=3 g=5 m=18446744073709551615 gstatus=4 +EventBatch gen=1 m=18446744073709551615 time=7689672467258 size=4540 +Stacks +Stack id=86 nframes=7 + pc=4754167 func=24 file=25 line=736 + pc=4814861 func=26 file=27 line=181 + pc=4814837 func=28 file=29 line=736 + pc=4814480 func=30 file=29 line=160 + pc=4996132 func=31 file=32 line=55 + pc=5032836 func=33 file=34 line=179 + pc=5078635 func=35 file=36 line=73 +Stack id=77 nframes=16 + pc=4756520 func=37 file=25 line=1442 + pc=4751813 func=38 file=27 line=298 + pc=4996815 func=39 file=40 line=59 + pc=5049499 func=41 file=42 line=124 + pc=5048282 func=43 file=42 line=70 + pc=5021687 func=44 file=45 line=154 + pc=5057739 func=46 file=47 line=85 + pc=5057380 func=48 file=47 line=75 + pc=5057381 func=49 file=47 line=71 + pc=4965884 func=50 file=51 line=651 + pc=4964173 func=52 file=51 line=616 + pc=4961811 func=53 file=51 line=517 + pc=4960409 func=54 file=51 line=508 + pc=4958646 func=55 file=51 line=434 + pc=4958647 func=56 file=51 line=401 + pc=5078500 func=35 file=36 line=68 +Stack id=13 nframes=1 + pc=5077820 func=35 file=36 line=28 +Stack id=65 nframes=2 + pc=4224086 func=57 file=58 line=145 + pc=5080123 func=59 file=36 line=94 +Stack id=21 nframes=3 + pc=4640852 func=60 file=61 line=195 + pc=5081128 func=62 file=36 line=125 + pc=5077843 func=35 file=36 line=32 +Stack id=11 nframes=1 + pc=5077754 func=35 file=36 line=27 +Stack id=10 nframes=1 + pc=5080288 func=63 file=36 line=97 +Stack id=44 nframes=2 + pc=4354430 func=64 file=65 line=408 + pc=4354396 func=66 file=67 line=318 +Stack id=51 nframes=3 + pc=4658586 func=68 file=69 line=53 + pc=5080816 func=70 file=36 line=110 + pc=5079149 func=71 file=36 line=40 +Stack id=36 nframes=7 + pc=4310007 func=72 file=73 line=806 + pc=4326610 func=74 file=75 line=562 + pc=4258131 func=76 file=77 line=1353 + pc=4255947 func=78 file=77 line=1025 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=57 nframes=5 + pc=4753924 func=81 file=25 line=432 + pc=4744496 func=82 file=83 line=118 + pc=4823012 func=84 file=85 line=218 + pc=4824373 func=86 file=87 line=21 + pc=5079543 func=59 file=36 line=82 +Stack id=16 nframes=7 + pc=4754618 func=88 file=25 line=964 + pc=4816103 func=89 file=27 line=209 + pc=4816095 func=28 file=29 line=736 + pc=4815648 func=90 file=29 line=380 + pc=4821008 func=91 file=92 line=46 + pc=4821000 func=93 file=94 line=189 + pc=5077114 func=95 file=96 line=134 +Stack id=63 nframes=1 + pc=5080224 func=97 file=36 line=89 +Stack id=2 nframes=3 + pc=4567556 func=98 file=99 line=239 + pc=5076805 func=100 file=96 line=125 + pc=5077595 func=35 file=36 line=20 +Stack id=80 nframes=15 + pc=4998478 func=101 file=29 line=683 + pc=4998507 func=39 file=40 line=141 + pc=5049499 func=41 file=42 line=124 + pc=5048282 func=43 file=42 line=70 + pc=5021687 func=44 file=45 line=154 + pc=5057739 func=46 file=47 line=85 + pc=5057380 func=48 file=47 line=75 + pc=5057381 func=49 file=47 line=71 + pc=4965884 func=50 file=51 line=651 + pc=4964173 func=52 file=51 line=616 + pc=4961811 func=53 file=51 line=517 + pc=4960409 func=54 file=51 line=508 + pc=4958646 func=55 file=51 line=434 + pc=4958647 func=56 file=51 line=401 + pc=5078500 func=35 file=36 line=68 +Stack id=47 nframes=1 + pc=5079072 func=71 file=36 line=38 +Stack id=55 nframes=2 + pc=4227441 func=102 file=58 line=442 + pc=5078106 func=35 file=36 line=48 +Stack id=5 nframes=4 + pc=4576789 func=103 file=104 line=44 + pc=4567832 func=98 file=99 line=258 + pc=5076805 func=100 file=96 line=125 + pc=5077595 func=35 file=36 line=20 +Stack id=46 nframes=3 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=8 nframes=1 + pc=5077056 func=95 file=96 line=128 +Stack id=24 nframes=6 + pc=4315620 func=105 file=73 line=1249 + pc=4308860 func=106 file=73 line=662 + pc=4257811 func=78 file=77 line=1308 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=37 nframes=1 + pc=4316644 func=107 file=73 line=1469 +Stack id=79 nframes=5 + pc=4817209 func=108 file=29 line=611 + pc=5000296 func=109 file=40 line=172 + pc=5058941 func=110 file=47 line=159 + pc=5055951 func=111 file=112 line=327 + pc=5078747 func=113 file=36 line=59 +Stack id=17 nframes=1 + pc=5077124 func=95 file=96 line=130 +Stack id=41 nframes=2 + pc=4310763 func=72 file=73 line=816 + pc=4316644 func=107 file=73 line=1469 +Stack id=33 nframes=7 + pc=4328420 func=114 file=75 line=747 + pc=4326674 func=74 file=75 line=587 + pc=4258131 func=76 file=77 line=1353 + pc=4255947 func=78 file=77 line=1025 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=29 nframes=6 + pc=4644903 func=115 file=116 line=474 + pc=4309092 func=106 file=73 line=683 + pc=4257811 func=78 file=77 line=1308 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=73 nframes=10 + pc=4756296 func=117 file=25 line=1432 + pc=4751685 func=118 file=27 line=290 + pc=5051812 func=119 file=42 line=167 + pc=5048051 func=43 file=42 line=57 + pc=5021687 func=44 file=45 line=154 + pc=5059172 func=120 file=47 line=189 + pc=4967876 func=121 file=47 line=179 + pc=4967838 func=122 file=51 line=734 + pc=4968614 func=123 file=51 line=808 + pc=5078215 func=35 file=36 line=53 +Stack id=92 nframes=2 + pc=4640852 func=60 file=61 line=195 + pc=5078782 func=113 file=36 line=63 +Stack id=32 nframes=2 + pc=4344589 func=124 file=125 line=425 + pc=4346072 func=126 file=125 line=658 +Stack id=45 nframes=1 + pc=5077843 func=35 file=36 line=32 +Stack id=62 nframes=3 + pc=4754167 func=24 file=25 line=736 + pc=5079848 func=26 file=27 line=181 + pc=5079785 func=59 file=36 line=90 +Stack id=15 nframes=3 + pc=4227441 func=102 file=58 line=442 + pc=4574090 func=127 file=99 line=937 + pc=4576964 func=128 file=104 line=56 +Stack id=28 nframes=4 + pc=4257811 func=78 file=77 line=1308 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=64 nframes=7 + pc=4754618 func=88 file=25 line=964 + pc=4816103 func=89 file=27 line=209 + pc=4816095 func=28 file=29 line=736 + pc=4815648 func=90 file=29 line=380 + pc=4821008 func=91 file=92 line=46 + pc=4821000 func=93 file=94 line=189 + pc=5080260 func=97 file=36 line=89 +Stack id=91 nframes=8 + pc=4757394 func=129 file=25 line=1488 + pc=4819063 func=130 file=27 line=462 + pc=4819041 func=131 file=132 line=17 + pc=5060022 func=133 file=134 line=21 + pc=5055784 func=135 file=112 line=257 + pc=5058972 func=110 file=47 line=163 + pc=5055951 func=111 file=112 line=327 + pc=5078747 func=113 file=36 line=59 +Stack id=95 nframes=8 + pc=4753732 func=136 file=25 line=335 + pc=4813424 func=137 file=138 line=24 + pc=4813394 func=139 file=29 line=81 + pc=4811154 func=140 file=141 line=213 + pc=4813572 func=142 file=29 line=104 + pc=4996049 func=143 file=32 line=37 + pc=5033653 func=144 file=34 line=203 + pc=5078651 func=35 file=36 line=74 +Stack id=22 nframes=4 + pc=4257811 func=78 file=77 line=1308 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=56 nframes=5 + pc=4753924 func=81 file=25 line=432 + pc=4744422 func=82 file=83 line=106 + pc=4823012 func=84 file=85 line=218 + pc=4824373 func=86 file=87 line=21 + pc=5079543 func=59 file=36 line=82 +Stack id=60 nframes=5 + pc=4753924 func=81 file=25 line=432 + pc=4744422 func=82 file=83 line=106 + pc=4813961 func=145 file=29 line=129 + pc=5079772 func=146 file=85 line=90 + pc=5079785 func=59 file=36 line=90 +Stack id=38 nframes=2 + pc=4310679 func=72 file=73 line=914 + pc=4316644 func=107 file=73 line=1469 +Stack id=52 nframes=3 + pc=4708004 func=147 file=148 line=81 + pc=5079238 func=149 file=148 line=87 + pc=5079164 func=71 file=36 line=41 +Stack id=20 nframes=3 + pc=4708004 func=147 file=148 line=81 + pc=5080678 func=149 file=148 line=87 + pc=5080600 func=150 file=36 line=105 +Stack id=67 nframes=19 + pc=4752943 func=151 file=25 line=98 + pc=4822218 func=152 file=153 line=280 + pc=4822195 func=154 file=155 line=15 + pc=4823409 func=156 file=85 line=272 + pc=4821405 func=157 file=94 line=374 + pc=5042404 func=158 file=94 line=354 + pc=5042391 func=159 file=160 line=76 + pc=5047095 func=161 file=162 line=35 + pc=5068462 func=163 file=34 line=373 + pc=4703265 func=164 file=165 line=74 + pc=5034315 func=166 file=165 line=65 + pc=5034286 func=167 file=34 line=373 + pc=5047998 func=43 file=42 line=57 + pc=5021687 func=44 file=45 line=154 + pc=5059172 func=120 file=47 line=189 + pc=4967876 func=121 file=47 line=179 + pc=4967838 func=122 file=51 line=734 + pc=4968614 func=123 file=51 line=808 + pc=5078215 func=35 file=36 line=53 +Stack id=84 nframes=15 + pc=4757394 func=129 file=25 line=1488 + pc=4819063 func=130 file=27 line=462 + pc=4819041 func=131 file=132 line=17 + pc=5059867 func=133 file=134 line=18 + pc=5055784 func=135 file=112 line=257 + pc=5058352 func=46 file=47 line=121 + pc=5057380 func=48 file=47 line=75 + pc=5057381 func=49 file=47 line=71 + pc=4965884 func=50 file=51 line=651 + pc=4964173 func=52 file=51 line=616 + pc=4961811 func=53 file=51 line=517 + pc=4960409 func=54 file=51 line=508 + pc=4958646 func=55 file=51 line=434 + pc=4958647 func=56 file=51 line=401 + pc=5078500 func=35 file=36 line=68 +Stack id=74 nframes=9 + pc=4755428 func=168 file=25 line=1213 + pc=5051952 func=119 file=42 line=170 + pc=5048051 func=43 file=42 line=57 + pc=5021687 func=44 file=45 line=154 + pc=5059172 func=120 file=47 line=189 + pc=4967876 func=121 file=47 line=179 + pc=4967838 func=122 file=51 line=734 + pc=4968614 func=123 file=51 line=808 + pc=5078215 func=35 file=36 line=53 +Stack id=50 nframes=1 + pc=5079149 func=71 file=36 line=40 +Stack id=14 nframes=2 + pc=4708263 func=169 file=148 line=116 + pc=5077833 func=35 file=36 line=29 +Stack id=27 nframes=2 + pc=4437613 func=170 file=65 line=402 + pc=4316040 func=107 file=73 line=1333 +Stack id=30 nframes=5 + pc=4309402 func=106 file=73 line=745 + pc=4257811 func=78 file=77 line=1308 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=75 nframes=1 + pc=5078720 func=113 file=36 line=58 +Stack id=88 nframes=8 + pc=4757394 func=129 file=25 line=1488 + pc=4819063 func=130 file=27 line=462 + pc=4819041 func=131 file=132 line=17 + pc=5059594 func=171 file=172 line=15 + pc=5055722 func=135 file=112 line=251 + pc=5058972 func=110 file=47 line=163 + pc=5055951 func=111 file=112 line=327 + pc=5078747 func=113 file=36 line=59 +Stack id=70 nframes=21 + pc=4754167 func=24 file=25 line=736 + pc=4814861 func=26 file=27 line=181 + pc=4814837 func=28 file=29 line=736 + pc=4814480 func=30 file=29 line=160 + pc=4820817 func=173 file=92 line=29 + pc=4820809 func=174 file=94 line=118 + pc=4742703 func=175 file=176 line=335 + pc=5041967 func=177 file=176 line=354 + pc=5041927 func=178 file=160 line=55 + pc=5047143 func=161 file=162 line=40 + pc=5068462 func=163 file=34 line=373 + pc=4703265 func=164 file=165 line=74 + pc=5034315 func=166 file=165 line=65 + pc=5034286 func=167 file=34 line=373 + pc=5047998 func=43 file=42 line=57 + pc=5021687 func=44 file=45 line=154 + pc=5059172 func=120 file=47 line=189 + pc=4967876 func=121 file=47 line=179 + pc=4967838 func=122 file=51 line=734 + pc=4968614 func=123 file=51 line=808 + pc=5078215 func=35 file=36 line=53 +Stack id=25 nframes=7 + pc=4227441 func=102 file=58 line=442 + pc=4315507 func=105 file=73 line=1259 + pc=4308860 func=106 file=73 line=662 + pc=4257811 func=78 file=77 line=1308 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=58 nframes=5 + pc=4753924 func=81 file=25 line=432 + pc=4744422 func=82 file=83 line=106 + pc=4823012 func=84 file=85 line=218 + pc=4824408 func=86 file=87 line=21 + pc=5079543 func=59 file=36 line=82 +Stack id=69 nframes=19 + pc=4753924 func=81 file=25 line=432 + pc=4744496 func=82 file=83 line=118 + pc=4823012 func=84 file=85 line=218 + pc=4823631 func=156 file=85 line=301 + pc=4821405 func=157 file=94 line=374 + pc=5042404 func=158 file=94 line=354 + pc=5042391 func=159 file=160 line=76 + pc=5047095 func=161 file=162 line=35 + pc=5068462 func=163 file=34 line=373 + pc=4703265 func=164 file=165 line=74 + pc=5034315 func=166 file=165 line=65 + pc=5034286 func=167 file=34 line=373 + pc=5047998 func=43 file=42 line=57 + pc=5021687 func=44 file=45 line=154 + pc=5059172 func=120 file=47 line=189 + pc=4967876 func=121 file=47 line=179 + pc=4967838 func=122 file=51 line=734 + pc=4968614 func=123 file=51 line=808 + pc=5078215 func=35 file=36 line=53 +Stack id=83 nframes=15 + pc=4757394 func=129 file=25 line=1488 + pc=4819063 func=130 file=27 line=462 + pc=4819041 func=131 file=132 line=17 + pc=5054762 func=179 file=180 line=88 + pc=5055769 func=135 file=112 line=256 + pc=5058352 func=46 file=47 line=121 + pc=5057380 func=48 file=47 line=75 + pc=5057381 func=49 file=47 line=71 + pc=4965884 func=50 file=51 line=651 + pc=4964173 func=52 file=51 line=616 + pc=4961811 func=53 file=51 line=517 + pc=4960409 func=54 file=51 line=508 + pc=4958646 func=55 file=51 line=434 + pc=4958647 func=56 file=51 line=401 + pc=5078500 func=35 file=36 line=68 +Stack id=43 nframes=9 + pc=4368154 func=181 file=182 line=958 + pc=4293585 func=183 file=184 line=254 + pc=4293175 func=185 file=184 line=170 + pc=4290674 func=186 file=187 line=182 + pc=4255364 func=188 file=77 line=948 + pc=4256932 func=78 file=77 line=1149 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=78 nframes=8 + pc=4756062 func=189 file=25 line=1421 + pc=4750293 func=190 file=153 line=684 + pc=4818215 func=191 file=192 line=17 + pc=4816989 func=108 file=29 line=602 + pc=5000296 func=109 file=40 line=172 + pc=5058941 func=110 file=47 line=159 + pc=5055951 func=111 file=112 line=327 + pc=5078747 func=113 file=36 line=59 +Stack id=71 nframes=20 + pc=4753732 func=136 file=25 line=335 + pc=4813424 func=137 file=138 line=24 + pc=4813394 func=139 file=29 line=81 + pc=4811154 func=140 file=141 line=213 + pc=4813572 func=142 file=29 line=104 + pc=4823895 func=193 file=85 line=315 + pc=5047564 func=194 file=92 line=23 + pc=5047547 func=195 file=160 line=23 + pc=5047406 func=161 file=162 line=53 + pc=5068462 func=163 file=34 line=373 + pc=4703265 func=164 file=165 line=74 + pc=5034315 func=166 file=165 line=65 + pc=5034286 func=167 file=34 line=373 + pc=5047998 func=43 file=42 line=57 + pc=5021687 func=44 file=45 line=154 + pc=5059172 func=120 file=47 line=189 + pc=4967876 func=121 file=47 line=179 + pc=4967838 func=122 file=51 line=734 + pc=4968614 func=123 file=51 line=808 + pc=5078215 func=35 file=36 line=53 +Stack id=3 nframes=4 + pc=4446827 func=196 file=65 line=1369 + pc=4567827 func=98 file=99 line=256 + pc=5076805 func=100 file=96 line=125 + pc=5077595 func=35 file=36 line=20 +Stack id=35 nframes=2 + pc=4310007 func=72 file=73 line=806 + pc=4316644 func=107 file=73 line=1469 +Stack id=6 nframes=1 + pc=4573664 func=197 file=99 line=877 +Stack id=19 nframes=1 + pc=5080585 func=150 file=36 line=104 +Stack id=54 nframes=1 + pc=5078085 func=35 file=36 line=47 +Stack id=82 nframes=15 + pc=4757394 func=129 file=25 line=1488 + pc=4819063 func=130 file=27 line=462 + pc=4819041 func=131 file=132 line=17 + pc=5059594 func=171 file=172 line=15 + pc=5055722 func=135 file=112 line=251 + pc=5058352 func=46 file=47 line=121 + pc=5057380 func=48 file=47 line=75 + pc=5057381 func=49 file=47 line=71 + pc=4965884 func=50 file=51 line=651 + pc=4964173 func=52 file=51 line=616 + pc=4961811 func=53 file=51 line=517 + pc=4960409 func=54 file=51 line=508 + pc=4958646 func=55 file=51 line=434 + pc=4958647 func=56 file=51 line=401 + pc=5078500 func=35 file=36 line=68 +Stack id=90 nframes=8 + pc=4757394 func=129 file=25 line=1488 + pc=4819063 func=130 file=27 line=462 + pc=4819041 func=131 file=132 line=17 + pc=5059867 func=133 file=134 line=18 + pc=5055784 func=135 file=112 line=257 + pc=5058972 func=110 file=47 line=163 + pc=5055951 func=111 file=112 line=327 + pc=5078747 func=113 file=36 line=59 +Stack id=61 nframes=5 + pc=4753924 func=81 file=25 line=432 + pc=4744496 func=82 file=83 line=118 + pc=4813961 func=145 file=29 line=129 + pc=5079772 func=146 file=85 line=90 + pc=5079785 func=59 file=36 line=90 +Stack id=23 nframes=1 + pc=4315808 func=107 file=73 line=1298 +Stack id=12 nframes=1 + pc=5080512 func=150 file=36 line=102 +Stack id=68 nframes=19 + pc=4753924 func=81 file=25 line=432 + pc=4744422 func=82 file=83 line=106 + pc=4823012 func=84 file=85 line=218 + pc=4823631 func=156 file=85 line=301 + pc=4821405 func=157 file=94 line=374 + pc=5042404 func=158 file=94 line=354 + pc=5042391 func=159 file=160 line=76 + pc=5047095 func=161 file=162 line=35 + pc=5068462 func=163 file=34 line=373 + pc=4703265 func=164 file=165 line=74 + pc=5034315 func=166 file=165 line=65 + pc=5034286 func=167 file=34 line=373 + pc=5047998 func=43 file=42 line=57 + pc=5021687 func=44 file=45 line=154 + pc=5059172 func=120 file=47 line=189 + pc=4967876 func=121 file=47 line=179 + pc=4967838 func=122 file=51 line=734 + pc=4968614 func=123 file=51 line=808 + pc=5078215 func=35 file=36 line=53 +Stack id=4 nframes=1 + pc=4576896 func=128 file=104 line=44 +Stack id=66 nframes=6 + pc=5021687 func=44 file=45 line=154 + pc=5059172 func=120 file=47 line=189 + pc=4967876 func=121 file=47 line=179 + pc=4967838 func=122 file=51 line=734 + pc=4968614 func=123 file=51 line=808 + pc=5078215 func=35 file=36 line=53 +Stack id=81 nframes=16 + pc=4757147 func=198 file=25 line=1478 + pc=4752076 func=199 file=27 line=313 + pc=4998549 func=39 file=40 line=149 + pc=5049499 func=41 file=42 line=124 + pc=5048282 func=43 file=42 line=70 + pc=5021687 func=44 file=45 line=154 + pc=5057739 func=46 file=47 line=85 + pc=5057380 func=48 file=47 line=75 + pc=5057381 func=49 file=47 line=71 + pc=4965884 func=50 file=51 line=651 + pc=4964173 func=52 file=51 line=616 + pc=4961811 func=53 file=51 line=517 + pc=4960409 func=54 file=51 line=508 + pc=4958646 func=55 file=51 line=434 + pc=4958647 func=56 file=51 line=401 + pc=5078500 func=35 file=36 line=68 +Stack id=87 nframes=4 + pc=4814791 func=30 file=29 line=164 + pc=4996132 func=31 file=32 line=55 + pc=5032836 func=33 file=34 line=179 + pc=5078635 func=35 file=36 line=73 +Stack id=85 nframes=15 + pc=4757394 func=129 file=25 line=1488 + pc=4819063 func=130 file=27 line=462 + pc=4819041 func=131 file=132 line=17 + pc=5060022 func=133 file=134 line=21 + pc=5055784 func=135 file=112 line=257 + pc=5058352 func=46 file=47 line=121 + pc=5057380 func=48 file=47 line=75 + pc=5057381 func=49 file=47 line=71 + pc=4965884 func=50 file=51 line=651 + pc=4964173 func=52 file=51 line=616 + pc=4961811 func=53 file=51 line=517 + pc=4960409 func=54 file=51 line=508 + pc=4958646 func=55 file=51 line=434 + pc=4958647 func=56 file=51 line=401 + pc=5078500 func=35 file=36 line=68 +Stack id=39 nframes=4 + pc=4644903 func=115 file=116 line=474 + pc=4311677 func=200 file=73 line=964 + pc=4310756 func=72 file=73 line=926 + pc=4316644 func=107 file=73 line=1469 +Stack id=31 nframes=7 + pc=4585153 func=201 file=202 line=383 + pc=4326396 func=74 file=75 line=534 + pc=4258131 func=76 file=77 line=1353 + pc=4255947 func=78 file=77 line=1025 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=89 nframes=8 + pc=4757394 func=129 file=25 line=1488 + pc=4819063 func=130 file=27 line=462 + pc=4819041 func=131 file=132 line=17 + pc=5054762 func=179 file=180 line=88 + pc=5055769 func=135 file=112 line=256 + pc=5058972 func=110 file=47 line=163 + pc=5055951 func=111 file=112 line=327 + pc=5078747 func=113 file=36 line=59 +Stack id=53 nframes=1 + pc=5079488 func=59 file=36 line=81 +Stack id=18 nframes=3 + pc=4227441 func=102 file=58 line=442 + pc=4574090 func=127 file=99 line=937 + pc=4573703 func=197 file=99 line=880 +Stack id=48 nframes=1 + pc=5077881 func=35 file=36 line=38 +Stack id=94 nframes=8 + pc=4753732 func=136 file=25 line=335 + pc=4813424 func=137 file=138 line=24 + pc=4813394 func=139 file=29 line=81 + pc=4811154 func=140 file=141 line=213 + pc=4813572 func=142 file=29 line=104 + pc=4996049 func=143 file=32 line=37 + pc=5033653 func=144 file=34 line=203 + pc=5078837 func=113 file=36 line=66 +Stack id=42 nframes=9 + pc=4584693 func=203 file=202 line=357 + pc=4355940 func=204 file=67 line=522 + pc=4292956 func=185 file=184 line=147 + pc=4290674 func=186 file=187 line=182 + pc=4255364 func=188 file=77 line=948 + pc=4256932 func=78 file=77 line=1149 + pc=4528840 func=79 file=80 line=107 + pc=5081148 func=62 file=36 line=127 + pc=5077843 func=35 file=36 line=32 +Stack id=93 nframes=7 + pc=4754618 func=88 file=25 line=964 + pc=4816103 func=89 file=27 line=209 + pc=4816095 func=28 file=29 line=736 + pc=4815648 func=90 file=29 line=380 + pc=4996388 func=205 file=32 line=96 + pc=5033284 func=206 file=34 line=191 + pc=5078821 func=113 file=36 line=65 +Stack id=34 nframes=2 + pc=4644903 func=115 file=116 line=474 + pc=4316309 func=107 file=73 line=1393 +Stack id=49 nframes=2 + pc=4708263 func=169 file=148 line=116 + pc=5078001 func=35 file=36 line=43 +Stack id=7 nframes=4 + pc=4573636 func=207 file=99 line=877 + pc=4567844 func=98 file=99 line=259 + pc=5076805 func=100 file=96 line=125 + pc=5077595 func=35 file=36 line=20 +Stack id=76 nframes=1 + pc=5078444 func=35 file=36 line=58 +Stack id=1 nframes=4 + pc=4583115 func=208 file=202 line=260 + pc=4567535 func=98 file=99 line=238 + pc=5076805 func=100 file=96 line=125 + pc=5077595 func=35 file=36 line=20 +Stack id=26 nframes=2 + pc=4224086 func=57 file=58 line=145 + pc=4316011 func=107 file=73 line=1312 +Stack id=40 nframes=3 + pc=4312646 func=200 file=73 line=1086 + pc=4310756 func=72 file=73 line=926 + pc=4316644 func=107 file=73 line=1469 +Stack id=72 nframes=11 + pc=4757394 func=129 file=25 line=1488 + pc=5054386 func=130 file=27 line=462 + pc=5054396 func=209 file=210 line=28 + pc=5051349 func=119 file=42 line=152 + pc=5048051 func=43 file=42 line=57 + pc=5021687 func=44 file=45 line=154 + pc=5059172 func=120 file=47 line=189 + pc=4967876 func=121 file=47 line=179 + pc=4967838 func=122 file=51 line=734 + pc=4968614 func=123 file=51 line=808 + pc=5078215 func=35 file=36 line=53 +Stack id=59 nframes=5 + pc=4753924 func=81 file=25 line=432 + pc=4744496 func=82 file=83 line=118 + pc=4823012 func=84 file=85 line=218 + pc=4824408 func=86 file=87 line=21 + pc=5079543 func=59 file=36 line=82 +Stack id=9 nframes=2 + pc=5076879 func=100 file=96 line=128 + pc=5077595 func=35 file=36 line=20 +EventBatch gen=1 m=18446744073709551615 time=7689670146021 size=6980 +Strings +String id=1 + data="Not worker" +String id=2 + data="GC (dedicated)" +String id=3 + data="GC (fractional)" +String id=4 + data="GC (idle)" +String id=5 + data="unspecified" +String id=6 + data="forever" +String id=7 + data="network" +String id=8 + data="select" +String id=9 + data="sync.(*Cond).Wait" +String id=10 + data="sync" +String id=11 + data="chan send" +String id=12 + data="chan receive" +String id=13 + data="GC mark assist wait for work" +String id=14 + data="GC background sweeper wait" +String id=15 + data="system goroutine wait" +String id=16 + data="preempted" +String id=17 + data="wait for debug call" +String id=18 + data="wait until GC ends" +String id=19 + data="sleep" +String id=20 + data="runtime.Gosched" +String id=21 + data="start trace" +String id=22 + data="GC sweep termination" +String id=23 + data="GC mark termination" +String id=24 + data="syscall.read" +String id=25 + data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/zsyscall_linux_amd64.go" +String id=26 + data="syscall.Read" +String id=27 + data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/syscall_unix.go" +String id=28 + data="internal/poll.ignoringEINTRIO" +String id=29 + data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/fd_unix.go" +String id=30 + data="internal/poll.(*FD).Read" +String id=31 + data="net.(*netFD).Read" +String id=32 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/fd_posix.go" +String id=33 + data="net.(*conn).Read" +String id=34 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/net.go" +String id=35 + data="main.main" +String id=36 + data="/usr/local/google/home/mknyszek/work/go-1/src/cmd/trace/v2/testdata/testprog/main.go" +String id=37 + data="syscall.connect" +String id=38 + data="syscall.Connect" +String id=39 + data="net.(*netFD).connect" +String id=40 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/fd_unix.go" +String id=41 + data="net.(*netFD).dial" +String id=42 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/sock_posix.go" +String id=43 + data="net.socket" +String id=44 + data="net.internetSocket" +String id=45 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/ipsock_posix.go" +String id=46 + data="net.(*sysDialer).doDialTCPProto" +String id=47 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsock_posix.go" +String id=48 + data="net.(*sysDialer).doDialTCP" +String id=49 + data="net.(*sysDialer).dialTCP" +String id=50 + data="net.(*sysDialer).dialSingle" +String id=51 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/dial.go" +String id=52 + data="net.(*sysDialer).dialSerial" +String id=53 + data="net.(*sysDialer).dialParallel" +String id=54 + data="net.(*Dialer).DialContext" +String id=55 + data="net.(*Dialer).Dial" +String id=56 + data="net.Dial" +String id=57 + data="runtime.chansend1" +String id=58 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/chan.go" +String id=59 + data="main.blockingSyscall" +String id=60 + data="time.Sleep" +String id=61 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/time.go" +String id=62 + data="main.allocHog" +String id=63 + data="main.cpu10" +String id=64 + data="runtime.goparkunlock" +String id=65 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/proc.go" +String id=66 + data="runtime.bgsweep" +String id=67 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgcsweep.go" +String id=68 + data="runtime.asyncPreempt" +String id=69 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/preempt_amd64.s" +String id=70 + data="main.cpuHog" +String id=71 + data="main.main.func1" +String id=72 + data="runtime.gcMarkDone" +String id=73 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgc.go" +String id=74 + data="runtime.gcAssistAlloc" +String id=75 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgcmark.go" +String id=76 + data="runtime.deductAssistCredit" +String id=77 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/malloc.go" +String id=78 + data="runtime.mallocgc" +String id=79 + data="runtime.makeslice" +String id=80 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/slice.go" +String id=81 + data="syscall.fcntl" +String id=82 + data="syscall.SetNonblock" +String id=83 + data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/exec_unix.go" +String id=84 + data="os.newFile" +String id=85 + data="/usr/local/google/home/mknyszek/work/go-1/src/os/file_unix.go" +String id=86 + data="os.Pipe" +String id=87 + data="/usr/local/google/home/mknyszek/work/go-1/src/os/pipe2_unix.go" +String id=88 + data="syscall.write" +String id=89 + data="syscall.Write" +String id=90 + data="internal/poll.(*FD).Write" +String id=91 + data="os.(*File).write" +String id=92 + data="/usr/local/google/home/mknyszek/work/go-1/src/os/file_posix.go" +String id=93 + data="os.(*File).Write" +String id=94 + data="/usr/local/google/home/mknyszek/work/go-1/src/os/file.go" +String id=95 + data="runtime/trace.Start.func1" +String id=96 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace/trace.go" +String id=97 + data="main.blockingSyscall.func1" +String id=98 + data="runtime.StartTrace" +String id=99 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace2.go" +String id=100 + data="runtime/trace.Start" +String id=101 + data="internal/poll.(*FD).WaitWrite" +String id=102 + data="runtime.chanrecv1" +String id=103 + data="runtime.traceStartReadCPU" +String id=104 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace2cpu.go" +String id=105 + data="runtime.gcBgMarkStartWorkers" +String id=106 + data="runtime.gcStart" +String id=107 + data="runtime.gcBgMarkWorker" +String id=108 + data="internal/poll.(*FD).Accept" +String id=109 + data="net.(*netFD).accept" +String id=110 + data="net.(*TCPListener).accept" +String id=111 + data="net.(*TCPListener).Accept" +String id=112 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsock.go" +String id=113 + data="main.main.func2" +String id=114 + data="runtime.gcParkAssist" +String id=115 + data="runtime.systemstack_switch" +String id=116 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/asm_amd64.s" +String id=117 + data="syscall.bind" +String id=118 + data="syscall.Bind" +String id=119 + data="net.(*netFD).listenStream" +String id=120 + data="net.(*sysListener).listenTCPProto" +String id=121 + data="net.(*sysListener).listenTCP" +String id=122 + data="net.(*ListenConfig).Listen" +String id=123 + data="net.Listen" +String id=124 + data="runtime.(*scavengerState).park" +String id=125 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgcscavenge.go" +String id=126 + data="runtime.bgscavenge" +String id=127 + data="runtime.(*wakeableSleep).sleep" +String id=128 + data="runtime.traceStartReadCPU.func1" +String id=129 + data="syscall.setsockopt" +String id=130 + data="syscall.SetsockoptInt" +String id=131 + data="internal/poll.(*FD).SetsockoptInt" +String id=132 + data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/sockopt.go" +String id=133 + data="net.setKeepAlivePeriod" +String id=134 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsockopt_unix.go" +String id=135 + data="net.newTCPConn" +String id=136 + data="syscall.Close" +String id=137 + data="internal/poll.(*SysFile).destroy" +String id=138 + data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/fd_unixjs.go" +String id=139 + data="internal/poll.(*FD).destroy" +String id=140 + data="internal/poll.(*FD).decref" +String id=141 + data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/fd_mutex.go" +String id=142 + data="internal/poll.(*FD).Close" +String id=143 + data="net.(*netFD).Close" +String id=144 + data="net.(*conn).Close" +String id=145 + data="internal/poll.(*FD).SetBlocking" +String id=146 + data="os.(*File).Fd" +String id=147 + data="sync.(*WaitGroup).Add" +String id=148 + data="/usr/local/google/home/mknyszek/work/go-1/src/sync/waitgroup.go" +String id=149 + data="sync.(*WaitGroup).Done" +String id=150 + data="main.cpu20" +String id=151 + data="syscall.openat" +String id=152 + data="syscall.Open" +String id=153 + data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/syscall_linux.go" +String id=154 + data="os.open" +String id=155 + data="/usr/local/google/home/mknyszek/work/go-1/src/os/file_open_unix.go" +String id=156 + data="os.openFileNolog" +String id=157 + data="os.OpenFile" +String id=158 + data="os.Open" +String id=159 + data="net.open" +String id=160 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/parse.go" +String id=161 + data="net.maxListenerBacklog" +String id=162 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/sock_linux.go" +String id=163 + data="net.listenerBacklog.func1" +String id=164 + data="sync.(*Once).doSlow" +String id=165 + data="/usr/local/google/home/mknyszek/work/go-1/src/sync/once.go" +String id=166 + data="sync.(*Once).Do" +String id=167 + data="net.listenerBacklog" +String id=168 + data="syscall.Listen" +String id=169 + data="sync.(*WaitGroup).Wait" +String id=170 + data="runtime.gopark" +String id=171 + data="net.setNoDelay" +String id=172 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsockopt_posix.go" +String id=173 + data="os.(*File).read" +String id=174 + data="os.(*File).Read" +String id=175 + data="io.ReadAtLeast" +String id=176 + data="/usr/local/google/home/mknyszek/work/go-1/src/io/io.go" +String id=177 + data="io.ReadFull" +String id=178 + data="net.(*file).readLine" +String id=179 + data="net.setKeepAlive" +String id=180 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/sockopt_posix.go" +String id=181 + data="runtime.(*mheap).alloc" +String id=182 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mheap.go" +String id=183 + data="runtime.(*mcentral).grow" +String id=184 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mcentral.go" +String id=185 + data="runtime.(*mcentral).cacheSpan" +String id=186 + data="runtime.(*mcache).refill" +String id=187 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mcache.go" +String id=188 + data="runtime.(*mcache).nextFree" +String id=189 + data="syscall.accept4" +String id=190 + data="syscall.Accept4" +String id=191 + data="internal/poll.accept" +String id=192 + data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/sock_cloexec.go" +String id=193 + data="os.(*file).close" +String id=194 + data="os.(*File).Close" +String id=195 + data="net.(*file).close" +String id=196 + data="runtime.startTheWorld" +String id=197 + data="runtime.(*traceAdvancerState).start.func1" +String id=198 + data="syscall.getsockopt" +String id=199 + data="syscall.GetsockoptInt" +String id=200 + data="runtime.gcMarkTermination" +String id=201 + data="runtime.traceLocker.GCMarkAssistStart" +String id=202 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace2runtime.go" +String id=203 + data="runtime.traceLocker.GCSweepSpan" +String id=204 + data="runtime.(*sweepLocked).sweep" +String id=205 + data="net.(*netFD).Write" +String id=206 + data="net.(*conn).Write" +String id=207 + data="runtime.(*traceAdvancerState).start" +String id=208 + data="runtime.traceLocker.Gomaxprocs" +String id=209 + data="net.setDefaultListenerSockopts" +String id=210 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/sockopt_linux.go" diff --git a/src/cmd/trace/testdata/mktests.go b/src/cmd/trace/testdata/mktests.go new file mode 100644 index 0000000000..b6efa83ece --- /dev/null +++ b/src/cmd/trace/testdata/mktests.go @@ -0,0 +1,58 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import ( + "bytes" + "fmt" + "internal/trace/v2/raw" + "internal/trace/v2/version" + "io" + "log" + "os" + "os/exec" +) + +func main() { + // Create command. + var trace, stderr bytes.Buffer + cmd := exec.Command("go", "run", "./testprog/main.go") + cmd.Stdout = &trace + cmd.Stderr = &stderr + + // Run trace program; the trace will appear in stdout. + fmt.Fprintln(os.Stderr, "running trace program...") + if err := cmd.Run(); err != nil { + log.Fatalf("running trace program: %v:\n%s", err, stderr.String()) + } + + // Create file. + f, err := os.Create(fmt.Sprintf("./go1%d.test", version.Current)) + if err != nil { + log.Fatalf("creating output file: %v", err) + } + defer f.Close() + + // Write out the trace. + r, err := raw.NewReader(&trace) + if err != nil { + log.Fatalf("reading trace: %v", err) + } + w, err := raw.NewTextWriter(f, version.Current) + for { + ev, err := r.ReadEvent() + if err == io.EOF { + break + } + if err != nil { + log.Fatalf("reading trace: %v", err) + } + if err := w.WriteEvent(ev); err != nil { + log.Fatalf("writing trace: %v", err) + } + } +} diff --git a/src/cmd/trace/testdata/testprog/main.go b/src/cmd/trace/testdata/testprog/main.go new file mode 100644 index 0000000000..fcf4dc156c --- /dev/null +++ b/src/cmd/trace/testdata/testprog/main.go @@ -0,0 +1,129 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "log" + "net" + "os" + "runtime" + "runtime/trace" + "sync" + "syscall" + "time" +) + +func main() { + if err := trace.Start(os.Stdout); err != nil { + log.Fatal(err) + } + + // checkExecutionTimes relies on this. + var wg sync.WaitGroup + wg.Add(2) + go cpu10(&wg) + go cpu20(&wg) + wg.Wait() + + // checkHeapMetrics relies on this. + allocHog(25 * time.Millisecond) + + // checkProcStartStop relies on this. + var wg2 sync.WaitGroup + for i := 0; i < runtime.GOMAXPROCS(0); i++ { + wg2.Add(1) + go func() { + defer wg2.Done() + cpuHog(50 * time.Millisecond) + }() + } + wg2.Wait() + + // checkSyscalls relies on this. + done := make(chan error) + go blockingSyscall(50*time.Millisecond, done) + if err := <-done; err != nil { + log.Fatal(err) + } + + // checkNetworkUnblock relies on this. + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + log.Fatalf("listen failed: %v", err) + } + defer ln.Close() + go func() { + c, err := ln.Accept() + if err != nil { + return + } + time.Sleep(time.Millisecond) + var buf [1]byte + c.Write(buf[:]) + c.Close() + }() + c, err := net.Dial("tcp", ln.Addr().String()) + if err != nil { + log.Fatalf("dial failed: %v", err) + } + var tmp [1]byte + c.Read(tmp[:]) + c.Close() + + trace.Stop() +} + +// blockingSyscall blocks the current goroutine for duration d in a syscall and +// sends a message to done when it is done or if the syscall failed. +func blockingSyscall(d time.Duration, done chan<- error) { + r, w, err := os.Pipe() + if err != nil { + done <- err + return + } + start := time.Now() + msg := []byte("hello") + time.AfterFunc(d, func() { w.Write(msg) }) + _, err = syscall.Read(int(r.Fd()), make([]byte, len(msg))) + if err == nil && time.Since(start) < d { + err = fmt.Errorf("syscall returned too early: want=%s got=%s", d, time.Since(start)) + } + done <- err +} + +func cpu10(wg *sync.WaitGroup) { + defer wg.Done() + cpuHog(10 * time.Millisecond) +} + +func cpu20(wg *sync.WaitGroup) { + defer wg.Done() + cpuHog(20 * time.Millisecond) +} + +func cpuHog(dt time.Duration) { + start := time.Now() + for i := 0; ; i++ { + if i%1000 == 0 && time.Since(start) > dt { + return + } + } +} + +func allocHog(dt time.Duration) { + start := time.Now() + var s [][]byte + for i := 0; ; i++ { + if i%1000 == 0 { + if time.Since(start) > dt { + return + } + // Take a break... this will generate a ton of events otherwise. + time.Sleep(50 * time.Microsecond) + } + s = append(s, make([]byte, 1024)) + } +} diff --git a/src/cmd/trace/threadgen.go b/src/cmd/trace/threadgen.go new file mode 100644 index 0000000000..2d2c7eb753 --- /dev/null +++ b/src/cmd/trace/threadgen.go @@ -0,0 +1,204 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "internal/trace/traceviewer" + "internal/trace/traceviewer/format" + tracev2 "internal/trace/v2" +) + +var _ generator = &threadGenerator{} + +type threadGenerator struct { + globalRangeGenerator + globalMetricGenerator + stackSampleGenerator[tracev2.ThreadID] + logEventGenerator[tracev2.ThreadID] + + gStates map[tracev2.GoID]*gState[tracev2.ThreadID] + threads map[tracev2.ThreadID]struct{} +} + +func newThreadGenerator() *threadGenerator { + tg := new(threadGenerator) + rg := func(ev *tracev2.Event) tracev2.ThreadID { + return ev.Thread() + } + tg.stackSampleGenerator.getResource = rg + tg.logEventGenerator.getResource = rg + tg.gStates = make(map[tracev2.GoID]*gState[tracev2.ThreadID]) + tg.threads = make(map[tracev2.ThreadID]struct{}) + return tg +} + +func (g *threadGenerator) Sync() { + g.globalRangeGenerator.Sync() +} + +func (g *threadGenerator) GoroutineLabel(ctx *traceContext, ev *tracev2.Event) { + l := ev.Label() + g.gStates[l.Resource.Goroutine()].setLabel(l.Label) +} + +func (g *threadGenerator) GoroutineRange(ctx *traceContext, ev *tracev2.Event) { + r := ev.Range() + switch ev.Kind() { + case tracev2.EventRangeBegin: + g.gStates[r.Scope.Goroutine()].rangeBegin(ev.Time(), r.Name, ev.Stack()) + case tracev2.EventRangeActive: + g.gStates[r.Scope.Goroutine()].rangeActive(r.Name) + case tracev2.EventRangeEnd: + gs := g.gStates[r.Scope.Goroutine()] + gs.rangeEnd(ev.Time(), r.Name, ev.Stack(), ctx) + } +} + +func (g *threadGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event) { + if ev.Thread() != tracev2.NoThread { + if _, ok := g.threads[ev.Thread()]; !ok { + g.threads[ev.Thread()] = struct{}{} + } + } + + st := ev.StateTransition() + goID := st.Resource.Goroutine() + + // If we haven't seen this goroutine before, create a new + // gState for it. + gs, ok := g.gStates[goID] + if !ok { + gs = newGState[tracev2.ThreadID](goID) + g.gStates[goID] = gs + } + // If we haven't already named this goroutine, try to name it. + gs.augmentName(st.Stack) + + // Handle the goroutine state transition. + from, to := st.Goroutine() + if from == to { + // Filter out no-op events. + return + } + if from.Executing() && !to.Executing() { + if to == tracev2.GoWaiting { + // Goroutine started blocking. + gs.block(ev.Time(), ev.Stack(), st.Reason, ctx) + } else { + gs.stop(ev.Time(), ev.Stack(), ctx) + } + } + if !from.Executing() && to.Executing() { + start := ev.Time() + if from == tracev2.GoUndetermined { + // Back-date the event to the start of the trace. + start = ctx.startTime + } + gs.start(start, ev.Thread(), ctx) + } + + if from == tracev2.GoWaiting { + // Goroutine was unblocked. + gs.unblock(ev.Time(), ev.Stack(), ev.Thread(), ctx) + } + if from == tracev2.GoNotExist && to == tracev2.GoRunnable { + // Goroutine was created. + gs.created(ev.Time(), ev.Thread(), ev.Stack()) + } + if from == tracev2.GoSyscall { + // Exiting syscall. + gs.syscallEnd(ev.Time(), to != tracev2.GoRunning, ctx) + } + + // Handle syscalls. + if to == tracev2.GoSyscall { + start := ev.Time() + if from == tracev2.GoUndetermined { + // Back-date the event to the start of the trace. + start = ctx.startTime + } + // Write down that we've entered a syscall. Note: we might have no P here + // if we're in a cgo callback or this is a transition from GoUndetermined + // (i.e. the G has been blocked in a syscall). + gs.syscallBegin(start, ev.Thread(), ev.Stack()) + } + + // Note down the goroutine transition. + _, inMarkAssist := gs.activeRanges["GC mark assist"] + ctx.GoroutineTransition(ctx.elapsed(ev.Time()), viewerGState(from, inMarkAssist), viewerGState(to, inMarkAssist)) +} + +func (g *threadGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { + if ev.Thread() != tracev2.NoThread { + if _, ok := g.threads[ev.Thread()]; !ok { + g.threads[ev.Thread()] = struct{}{} + } + } + + type procArg struct { + Proc uint64 `json:"proc,omitempty"` + } + st := ev.StateTransition() + viewerEv := traceviewer.InstantEvent{ + Resource: uint64(ev.Thread()), + Stack: ctx.Stack(viewerFrames(ev.Stack())), + Arg: procArg{Proc: uint64(st.Resource.Proc())}, + } + + from, to := st.Proc() + if from == to { + // Filter out no-op events. + return + } + if to.Executing() { + start := ev.Time() + if from == tracev2.ProcUndetermined { + start = ctx.startTime + } + viewerEv.Name = "proc start" + viewerEv.Arg = format.ThreadIDArg{ThreadID: uint64(ev.Thread())} + viewerEv.Ts = ctx.elapsed(start) + // TODO(mknyszek): We don't have a state machine for threads, so approximate + // running threads with running Ps. + ctx.IncThreadStateCount(ctx.elapsed(start), traceviewer.ThreadStateRunning, 1) + } + if from.Executing() { + start := ev.Time() + viewerEv.Name = "proc stop" + viewerEv.Ts = ctx.elapsed(start) + // TODO(mknyszek): We don't have a state machine for threads, so approximate + // running threads with running Ps. + ctx.IncThreadStateCount(ctx.elapsed(start), traceviewer.ThreadStateRunning, -1) + } + // TODO(mknyszek): Consider modeling procs differently and have them be + // transition to and from NotExist when GOMAXPROCS changes. We can emit + // events for this to clearly delineate GOMAXPROCS changes. + + if viewerEv.Name != "" { + ctx.Instant(viewerEv) + } +} + +func (g *threadGenerator) ProcRange(ctx *traceContext, ev *tracev2.Event) { + // TODO(mknyszek): Extend procRangeGenerator to support rendering proc ranges on threads. +} + +func (g *threadGenerator) Finish(ctx *traceContext) { + ctx.SetResourceType("OS THREADS") + + // Finish off global ranges. + g.globalRangeGenerator.Finish(ctx) + + // Finish off all the goroutine slices. + for _, gs := range g.gStates { + gs.finish(ctx) + } + + // Name all the threads to the emitter. + for id := range g.threads { + ctx.Resource(uint64(id), fmt.Sprintf("Thread %d", id)) + } +} diff --git a/src/cmd/trace/trace.go b/src/cmd/trace/trace.go deleted file mode 100644 index 438b8dd328..0000000000 --- a/src/cmd/trace/trace.go +++ /dev/null @@ -1,810 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "internal/trace" - "internal/trace/traceviewer" - "log" - "math" - "net/http" - "runtime/debug" - "sort" - "strconv" - "time" - - "internal/trace/traceviewer/format" -) - -func init() { - http.HandleFunc("/trace", httpTrace) - http.HandleFunc("/jsontrace", httpJsonTrace) - http.Handle("/static/", traceviewer.StaticHandler()) -} - -// httpTrace serves either whole trace (goid==0) or trace for goid goroutine. -func httpTrace(w http.ResponseWriter, r *http.Request) { - _, err := parseTrace() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - traceviewer.TraceHandler().ServeHTTP(w, r) -} - -// httpJsonTrace serves json trace, requested from within templTrace HTML. -func httpJsonTrace(w http.ResponseWriter, r *http.Request) { - defer debug.FreeOSMemory() - defer reportMemoryUsage("after httpJsonTrace") - // This is an AJAX handler, so instead of http.Error we use log.Printf to log errors. - res, err := parseTrace() - if err != nil { - log.Printf("failed to parse trace: %v", err) - return - } - - params := &traceParams{ - parsed: res, - endTime: math.MaxInt64, - } - - if goids := r.FormValue("goid"); goids != "" { - // If goid argument is present, we are rendering a trace for this particular goroutine. - goid, err := strconv.ParseUint(goids, 10, 64) - if err != nil { - log.Printf("failed to parse goid parameter %q: %v", goids, err) - return - } - analyzeGoroutines(res.Events) - g, ok := gs[goid] - if !ok { - log.Printf("failed to find goroutine %d", goid) - return - } - params.mode = traceviewer.ModeGoroutineOriented - params.startTime = g.StartTime - if g.EndTime != 0 { - params.endTime = g.EndTime - } else { // The goroutine didn't end. - params.endTime = lastTimestamp() - } - params.maing = goid - params.gs = trace.RelatedGoroutines(res.Events, goid) - } else if taskids := r.FormValue("taskid"); taskids != "" { - taskid, err := strconv.ParseUint(taskids, 10, 64) - if err != nil { - log.Printf("failed to parse taskid parameter %q: %v", taskids, err) - return - } - annotRes, _ := analyzeAnnotations() - task, ok := annotRes.tasks[taskid] - if !ok || len(task.events) == 0 { - log.Printf("failed to find task with id %d", taskid) - return - } - goid := task.events[0].G - params.mode = traceviewer.ModeGoroutineOriented | traceviewer.ModeTaskOriented - params.startTime = task.firstTimestamp() - 1 - params.endTime = task.lastTimestamp() + 1 - params.maing = goid - params.tasks = task.descendants() - gs := map[uint64]bool{} - for _, t := range params.tasks { - // find only directly involved goroutines - for k, v := range t.RelatedGoroutines(res.Events, 0) { - gs[k] = v - } - } - params.gs = gs - } else if taskids := r.FormValue("focustask"); taskids != "" { - taskid, err := strconv.ParseUint(taskids, 10, 64) - if err != nil { - log.Printf("failed to parse focustask parameter %q: %v", taskids, err) - return - } - annotRes, _ := analyzeAnnotations() - task, ok := annotRes.tasks[taskid] - if !ok || len(task.events) == 0 { - log.Printf("failed to find task with id %d", taskid) - return - } - params.mode = traceviewer.ModeTaskOriented - params.startTime = task.firstTimestamp() - 1 - params.endTime = task.lastTimestamp() + 1 - params.tasks = task.descendants() - } - - start := int64(0) - end := int64(math.MaxInt64) - if startStr, endStr := r.FormValue("start"), r.FormValue("end"); startStr != "" && endStr != "" { - // If start/end arguments are present, we are rendering a range of the trace. - start, err = strconv.ParseInt(startStr, 10, 64) - if err != nil { - log.Printf("failed to parse start parameter %q: %v", startStr, err) - return - } - end, err = strconv.ParseInt(endStr, 10, 64) - if err != nil { - log.Printf("failed to parse end parameter %q: %v", endStr, err) - return - } - } - - c := traceviewer.ViewerDataTraceConsumer(w, start, end) - if err := generateTrace(params, c); err != nil { - log.Printf("failed to generate trace: %v", err) - return - } -} - -// splitTrace splits the trace into a number of ranges, -// each resulting in approx 100MB of json output -// (trace viewer can hardly handle more). -func splitTrace(res trace.ParseResult) []traceviewer.Range { - params := &traceParams{ - parsed: res, - endTime: math.MaxInt64, - } - s, c := traceviewer.SplittingTraceConsumer(100 << 20) // 100M - if err := generateTrace(params, c); err != nil { - dief("%v\n", err) - } - return s.Ranges -} - -type traceParams struct { - parsed trace.ParseResult - mode traceviewer.Mode - startTime int64 - endTime int64 - maing uint64 // for goroutine-oriented view, place this goroutine on the top row - gs map[uint64]bool // Goroutines to be displayed for goroutine-oriented or task-oriented view - tasks []*taskDesc // Tasks to be displayed. tasks[0] is the top-most task -} - -type traceContext struct { - *traceParams - consumer traceviewer.TraceConsumer - emitter *traceviewer.Emitter - arrowSeq uint64 - gcount uint64 - regionID int // last emitted region id. incremented in each emitRegion call. -} - -type gInfo struct { - state traceviewer.GState // current state - name string // name chosen for this goroutine at first EvGoStart - isSystemG bool - start *trace.Event // most recent EvGoStart - markAssist *trace.Event // if non-nil, the mark assist currently running. -} - -type NameArg struct { - Name string `json:"name"` -} - -type TaskArg struct { - ID uint64 `json:"id"` - StartG uint64 `json:"start_g,omitempty"` - EndG uint64 `json:"end_g,omitempty"` -} - -type RegionArg struct { - TaskID uint64 `json:"taskid,omitempty"` -} - -type SortIndexArg struct { - Index int `json:"sort_index"` -} - -// generateTrace generates json trace for trace-viewer: -// https://github.com/google/trace-viewer -// Trace format is described at: -// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/view -// If mode==goroutineMode, generate trace for goroutine goid, otherwise whole trace. -// startTime, endTime determine part of the trace that we are interested in. -// gset restricts goroutines that are included in the resulting trace. -func generateTrace(params *traceParams, consumer traceviewer.TraceConsumer) error { - emitter := traceviewer.NewEmitter( - consumer, - time.Duration(params.startTime), - time.Duration(params.endTime), - ) - if params.mode&traceviewer.ModeGoroutineOriented != 0 { - emitter.SetResourceType("G") - } else { - emitter.SetResourceType("PROCS") - } - defer emitter.Flush() - - ctx := &traceContext{traceParams: params, emitter: emitter} - ctx.consumer = consumer - - maxProc := 0 - ginfos := make(map[uint64]*gInfo) - stacks := params.parsed.Stacks - - getGInfo := func(g uint64) *gInfo { - info, ok := ginfos[g] - if !ok { - info = &gInfo{} - ginfos[g] = info - } - return info - } - - // Since we make many calls to setGState, we record a sticky - // error in setGStateErr and check it after every event. - var setGStateErr error - setGState := func(ev *trace.Event, g uint64, oldState, newState traceviewer.GState) { - info := getGInfo(g) - if oldState == traceviewer.GWaiting && info.state == traceviewer.GWaitingGC { - // For checking, traceviewer.GWaiting counts as any traceviewer.GWaiting*. - oldState = info.state - } - if info.state != oldState && setGStateErr == nil { - setGStateErr = fmt.Errorf("expected G %d to be in state %d, but got state %d", g, oldState, info.state) - } - - emitter.GoroutineTransition(time.Duration(ev.Ts), info.state, newState) - info.state = newState - } - - for _, ev := range ctx.parsed.Events { - // Handle state transitions before we filter out events. - switch ev.Type { - case trace.EvGoStart, trace.EvGoStartLabel: - setGState(ev, ev.G, traceviewer.GRunnable, traceviewer.GRunning) - info := getGInfo(ev.G) - info.start = ev - case trace.EvProcStart: - emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateRunning, 1) - case trace.EvProcStop: - emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateRunning, -1) - case trace.EvGoCreate: - newG := ev.Args[0] - info := getGInfo(newG) - if info.name != "" { - return fmt.Errorf("duplicate go create event for go id=%d detected at offset %d", newG, ev.Off) - } - - stk, ok := stacks[ev.Args[1]] - if !ok || len(stk) == 0 { - return fmt.Errorf("invalid go create event: missing stack information for go id=%d at offset %d", newG, ev.Off) - } - - fname := stk[0].Fn - info.name = fmt.Sprintf("G%v %s", newG, fname) - info.isSystemG = trace.IsSystemGoroutine(fname) - - ctx.gcount++ - setGState(ev, newG, traceviewer.GDead, traceviewer.GRunnable) - case trace.EvGoEnd: - ctx.gcount-- - setGState(ev, ev.G, traceviewer.GRunning, traceviewer.GDead) - case trace.EvGoUnblock: - setGState(ev, ev.Args[0], traceviewer.GWaiting, traceviewer.GRunnable) - case trace.EvGoSysExit: - setGState(ev, ev.G, traceviewer.GWaiting, traceviewer.GRunnable) - if getGInfo(ev.G).isSystemG { - emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscallRuntime, -1) - } else { - emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscall, -1) - } - case trace.EvGoSysBlock: - setGState(ev, ev.G, traceviewer.GRunning, traceviewer.GWaiting) - if getGInfo(ev.G).isSystemG { - emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscallRuntime, 1) - } else { - emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscall, 1) - } - case trace.EvGoSched, trace.EvGoPreempt: - setGState(ev, ev.G, traceviewer.GRunning, traceviewer.GRunnable) - case trace.EvGoStop, - trace.EvGoSleep, trace.EvGoBlock, trace.EvGoBlockSend, trace.EvGoBlockRecv, - trace.EvGoBlockSelect, trace.EvGoBlockSync, trace.EvGoBlockCond, trace.EvGoBlockNet: - setGState(ev, ev.G, traceviewer.GRunning, traceviewer.GWaiting) - case trace.EvGoBlockGC: - setGState(ev, ev.G, traceviewer.GRunning, traceviewer.GWaitingGC) - case trace.EvGCMarkAssistStart: - getGInfo(ev.G).markAssist = ev - case trace.EvGCMarkAssistDone: - getGInfo(ev.G).markAssist = nil - case trace.EvGoWaiting: - setGState(ev, ev.G, traceviewer.GRunnable, traceviewer.GWaiting) - case trace.EvGoInSyscall: - // Cancel out the effect of EvGoCreate at the beginning. - setGState(ev, ev.G, traceviewer.GRunnable, traceviewer.GWaiting) - if getGInfo(ev.G).isSystemG { - emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscallRuntime, 1) - } else { - emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscall, 1) - } - case trace.EvHeapAlloc: - emitter.HeapAlloc(time.Duration(ev.Ts), ev.Args[0]) - case trace.EvHeapGoal: - emitter.HeapGoal(time.Duration(ev.Ts), ev.Args[0]) - } - if setGStateErr != nil { - return setGStateErr - } - - if err := emitter.Err(); err != nil { - return fmt.Errorf("invalid state after processing %v: %s", ev, err) - } - - // Ignore events that are from uninteresting goroutines - // or outside of the interesting timeframe. - if ctx.gs != nil && ev.P < trace.FakeP && !ctx.gs[ev.G] { - continue - } - if !withinTimeRange(ev, ctx.startTime, ctx.endTime) { - continue - } - - if ev.P < trace.FakeP && ev.P > maxProc { - maxProc = ev.P - } - - // Emit trace objects. - switch ev.Type { - case trace.EvProcStart: - if ctx.mode&traceviewer.ModeGoroutineOriented != 0 { - continue - } - ctx.emitInstant(ev, "proc start", "") - case trace.EvProcStop: - if ctx.mode&traceviewer.ModeGoroutineOriented != 0 { - continue - } - ctx.emitInstant(ev, "proc stop", "") - case trace.EvGCStart: - ctx.emitSlice(ev, "GC") - case trace.EvGCDone: - case trace.EvSTWStart: - if ctx.mode&traceviewer.ModeGoroutineOriented != 0 { - continue - } - ctx.emitSlice(ev, fmt.Sprintf("STW (%s)", ev.SArgs[0])) - case trace.EvSTWDone: - case trace.EvGCMarkAssistStart: - // Mark assists can continue past preemptions, so truncate to the - // whichever comes first. We'll synthesize another slice if - // necessary in EvGoStart. - markFinish := ev.Link - goFinish := getGInfo(ev.G).start.Link - fakeMarkStart := *ev - text := "MARK ASSIST" - if markFinish == nil || markFinish.Ts > goFinish.Ts { - fakeMarkStart.Link = goFinish - text = "MARK ASSIST (unfinished)" - } - ctx.emitSlice(&fakeMarkStart, text) - case trace.EvGCSweepStart: - slice := ctx.makeSlice(ev, "SWEEP") - if done := ev.Link; done != nil && done.Args[0] != 0 { - slice.Arg = struct { - Swept uint64 `json:"Swept bytes"` - Reclaimed uint64 `json:"Reclaimed bytes"` - }{done.Args[0], done.Args[1]} - } - ctx.emit(slice) - case trace.EvGoStart, trace.EvGoStartLabel: - info := getGInfo(ev.G) - if ev.Type == trace.EvGoStartLabel { - ctx.emitSlice(ev, ev.SArgs[0]) - } else { - ctx.emitSlice(ev, info.name) - } - if info.markAssist != nil { - // If we're in a mark assist, synthesize a new slice, ending - // either when the mark assist ends or when we're descheduled. - markFinish := info.markAssist.Link - goFinish := ev.Link - fakeMarkStart := *ev - text := "MARK ASSIST (resumed, unfinished)" - if markFinish != nil && markFinish.Ts < goFinish.Ts { - fakeMarkStart.Link = markFinish - text = "MARK ASSIST (resumed)" - } - ctx.emitSlice(&fakeMarkStart, text) - } - case trace.EvGoCreate: - ctx.emitArrow(ev, "go") - case trace.EvGoUnblock: - ctx.emitArrow(ev, "unblock") - case trace.EvGoSysCall: - ctx.emitInstant(ev, "syscall", "") - case trace.EvGoSysExit: - ctx.emitArrow(ev, "sysexit") - case trace.EvUserLog: - ctx.emitInstant(ev, formatUserLog(ev), "user event") - case trace.EvUserTaskCreate: - ctx.emitInstant(ev, "task start", "user event") - case trace.EvUserTaskEnd: - ctx.emitInstant(ev, "task end", "user event") - case trace.EvCPUSample: - if ev.P >= 0 { - // only show in this UI when there's an associated P - ctx.emitInstant(ev, "CPU profile sample", "") - } - } - } - - // Display task and its regions if we are in task-oriented presentation mode. - if ctx.mode&traceviewer.ModeTaskOriented != 0 { - // sort tasks based on the task start time. - sortedTask := make([]*taskDesc, len(ctx.tasks)) - copy(sortedTask, ctx.tasks) - sort.SliceStable(sortedTask, func(i, j int) bool { - ti, tj := sortedTask[i], sortedTask[j] - if ti.firstTimestamp() == tj.firstTimestamp() { - return ti.lastTimestamp() < tj.lastTimestamp() - } - return ti.firstTimestamp() < tj.firstTimestamp() - }) - - for i, task := range sortedTask { - ctx.emitTask(task, i) - - // If we are in goroutine-oriented mode, we draw regions. - // TODO(hyangah): add this for task/P-oriented mode (i.e., focustask view) too. - if ctx.mode&traceviewer.ModeGoroutineOriented != 0 { - for _, s := range task.regions { - ctx.emitRegion(s) - } - } - } - } - - // Display goroutine rows if we are either in goroutine-oriented mode. - if ctx.mode&traceviewer.ModeGoroutineOriented != 0 { - for k, v := range ginfos { - if !ctx.gs[k] { - continue - } - emitter.Resource(k, v.name) - } - emitter.Focus(ctx.maing) - - // Row for GC or global state (specified with G=0) - ctx.emitFooter(&format.Event{Name: "thread_sort_index", Phase: "M", PID: format.ProcsSection, TID: 0, Arg: &SortIndexArg{-1}}) - } else { - // Display rows for Ps if we are in the default trace view mode. - for i := 0; i <= maxProc; i++ { - emitter.Resource(uint64(i), fmt.Sprintf("Proc %v", i)) - } - } - - return nil -} - -func (ctx *traceContext) emit(e *format.Event) { - ctx.consumer.ConsumeViewerEvent(e, false) -} - -func (ctx *traceContext) emitFooter(e *format.Event) { - ctx.consumer.ConsumeViewerEvent(e, true) -} -func (ctx *traceContext) time(ev *trace.Event) float64 { - // Trace viewer wants timestamps in microseconds. - return float64(ev.Ts) / 1000 -} - -func withinTimeRange(ev *trace.Event, s, e int64) bool { - if evEnd := ev.Link; evEnd != nil { - return ev.Ts <= e && evEnd.Ts >= s - } - return ev.Ts >= s && ev.Ts <= e -} - -func tsWithinRange(ts, s, e int64) bool { - return s <= ts && ts <= e -} - -func (ctx *traceContext) proc(ev *trace.Event) uint64 { - if ctx.mode&traceviewer.ModeGoroutineOriented != 0 && ev.P < trace.FakeP { - return ev.G - } else { - return uint64(ev.P) - } -} - -func (ctx *traceContext) emitSlice(ev *trace.Event, name string) { - ctx.emit(ctx.makeSlice(ev, name)) -} - -func (ctx *traceContext) makeSlice(ev *trace.Event, name string) *format.Event { - // If ViewerEvent.Dur is not a positive value, - // trace viewer handles it as a non-terminating time interval. - // Avoid it by setting the field with a small value. - durationUsec := ctx.time(ev.Link) - ctx.time(ev) - if ev.Link.Ts-ev.Ts <= 0 { - durationUsec = 0.0001 // 0.1 nanoseconds - } - sl := &format.Event{ - Name: name, - Phase: "X", - Time: ctx.time(ev), - Dur: durationUsec, - TID: ctx.proc(ev), - Stack: ctx.emitter.Stack(ev.Stk), - EndStack: ctx.emitter.Stack(ev.Link.Stk), - } - - // grey out non-overlapping events if the event is not a global event (ev.G == 0) - if ctx.mode&traceviewer.ModeTaskOriented != 0 && ev.G != 0 { - // include P information. - if t := ev.Type; t == trace.EvGoStart || t == trace.EvGoStartLabel { - type Arg struct { - P int - } - sl.Arg = &Arg{P: ev.P} - } - // grey out non-overlapping events. - overlapping := false - for _, task := range ctx.tasks { - if _, overlapped := task.overlappingDuration(ev); overlapped { - overlapping = true - break - } - } - if !overlapping { - sl.Cname = colorLightGrey - } - } - return sl -} - -func (ctx *traceContext) emitTask(task *taskDesc, sortIndex int) { - taskRow := uint64(task.id) - taskName := task.name - durationUsec := float64(task.lastTimestamp()-task.firstTimestamp()) / 1e3 - - ctx.emitter.Task(taskRow, taskName, sortIndex) - ts := float64(task.firstTimestamp()) / 1e3 - sl := &format.Event{ - Name: taskName, - Phase: "X", - Time: ts, - Dur: durationUsec, - PID: format.TasksSection, - TID: taskRow, - Cname: pickTaskColor(task.id), - } - targ := TaskArg{ID: task.id} - if task.create != nil { - sl.Stack = ctx.emitter.Stack(task.create.Stk) - targ.StartG = task.create.G - } - if task.end != nil { - sl.EndStack = ctx.emitter.Stack(task.end.Stk) - targ.EndG = task.end.G - } - sl.Arg = targ - ctx.emit(sl) - - if task.create != nil && task.create.Type == trace.EvUserTaskCreate && task.create.Args[1] != 0 { - ctx.arrowSeq++ - ctx.emit(&format.Event{Name: "newTask", Phase: "s", TID: task.create.Args[1], ID: ctx.arrowSeq, Time: ts, PID: format.TasksSection}) - ctx.emit(&format.Event{Name: "newTask", Phase: "t", TID: taskRow, ID: ctx.arrowSeq, Time: ts, PID: format.TasksSection}) - } -} - -func (ctx *traceContext) emitRegion(s regionDesc) { - if s.Name == "" { - return - } - - if !tsWithinRange(s.firstTimestamp(), ctx.startTime, ctx.endTime) && - !tsWithinRange(s.lastTimestamp(), ctx.startTime, ctx.endTime) { - return - } - - ctx.regionID++ - regionID := ctx.regionID - - id := s.TaskID - scopeID := fmt.Sprintf("%x", id) - name := s.Name - - sl0 := &format.Event{ - Category: "Region", - Name: name, - Phase: "b", - Time: float64(s.firstTimestamp()) / 1e3, - TID: s.G, // only in goroutine-oriented view - ID: uint64(regionID), - Scope: scopeID, - Cname: pickTaskColor(s.TaskID), - } - if s.Start != nil { - sl0.Stack = ctx.emitter.Stack(s.Start.Stk) - } - ctx.emit(sl0) - - sl1 := &format.Event{ - Category: "Region", - Name: name, - Phase: "e", - Time: float64(s.lastTimestamp()) / 1e3, - TID: s.G, - ID: uint64(regionID), - Scope: scopeID, - Cname: pickTaskColor(s.TaskID), - Arg: RegionArg{TaskID: s.TaskID}, - } - if s.End != nil { - sl1.Stack = ctx.emitter.Stack(s.End.Stk) - } - ctx.emit(sl1) -} - -func (ctx *traceContext) emitInstant(ev *trace.Event, name, category string) { - if !tsWithinRange(ev.Ts, ctx.startTime, ctx.endTime) { - return - } - - cname := "" - if ctx.mode&traceviewer.ModeTaskOriented != 0 { - taskID, isUserAnnotation := isUserAnnotationEvent(ev) - - show := false - for _, task := range ctx.tasks { - if isUserAnnotation && task.id == taskID || task.overlappingInstant(ev) { - show = true - break - } - } - // grey out or skip if non-overlapping instant. - if !show { - if isUserAnnotation { - return // don't display unrelated user annotation events. - } - cname = colorLightGrey - } - } - var arg any - if ev.Type == trace.EvProcStart { - type Arg struct { - ThreadID uint64 - } - arg = &Arg{ev.Args[0]} - } - ctx.emit(&format.Event{ - Name: name, - Category: category, - Phase: "I", - Scope: "t", - Time: ctx.time(ev), - TID: ctx.proc(ev), - Stack: ctx.emitter.Stack(ev.Stk), - Cname: cname, - Arg: arg}) -} - -func (ctx *traceContext) emitArrow(ev *trace.Event, name string) { - if ev.Link == nil { - // The other end of the arrow is not captured in the trace. - // For example, a goroutine was unblocked but was not scheduled before trace stop. - return - } - if ctx.mode&traceviewer.ModeGoroutineOriented != 0 && (!ctx.gs[ev.Link.G] || ev.Link.Ts < ctx.startTime || ev.Link.Ts > ctx.endTime) { - return - } - - if ev.P == trace.NetpollP || ev.P == trace.TimerP || ev.P == trace.SyscallP { - // Trace-viewer discards arrows if they don't start/end inside of a slice or instant. - // So emit a fake instant at the start of the arrow. - ctx.emitInstant(&trace.Event{P: ev.P, Ts: ev.Ts}, "unblock", "") - } - - color := "" - if ctx.mode&traceviewer.ModeTaskOriented != 0 { - overlapping := false - // skip non-overlapping arrows. - for _, task := range ctx.tasks { - if _, overlapped := task.overlappingDuration(ev); overlapped { - overlapping = true - break - } - } - if !overlapping { - return - } - } - - ctx.arrowSeq++ - ctx.emit(&format.Event{Name: name, Phase: "s", TID: ctx.proc(ev), ID: ctx.arrowSeq, Time: ctx.time(ev), Stack: ctx.emitter.Stack(ev.Stk), Cname: color}) - ctx.emit(&format.Event{Name: name, Phase: "t", TID: ctx.proc(ev.Link), ID: ctx.arrowSeq, Time: ctx.time(ev.Link), Cname: color}) -} - -// firstTimestamp returns the timestamp of the first event record. -func firstTimestamp() int64 { - res, _ := parseTrace() - if len(res.Events) > 0 { - return res.Events[0].Ts - } - return 0 -} - -// lastTimestamp returns the timestamp of the last event record. -func lastTimestamp() int64 { - res, _ := parseTrace() - if n := len(res.Events); n > 1 { - return res.Events[n-1].Ts - } - return 0 -} - -// Mapping from more reasonable color names to the reserved color names in -// https://github.com/catapult-project/catapult/blob/master/tracing/tracing/base/color_scheme.html#L50 -// The chrome trace viewer allows only those as cname values. -const ( - colorLightMauve = "thread_state_uninterruptible" // 182, 125, 143 - colorOrange = "thread_state_iowait" // 255, 140, 0 - colorSeafoamGreen = "thread_state_running" // 126, 200, 148 - colorVistaBlue = "thread_state_runnable" // 133, 160, 210 - colorTan = "thread_state_unknown" // 199, 155, 125 - colorIrisBlue = "background_memory_dump" // 0, 180, 180 - colorMidnightBlue = "light_memory_dump" // 0, 0, 180 - colorDeepMagenta = "detailed_memory_dump" // 180, 0, 180 - colorBlue = "vsync_highlight_color" // 0, 0, 255 - colorGrey = "generic_work" // 125, 125, 125 - colorGreen = "good" // 0, 125, 0 - colorDarkGoldenrod = "bad" // 180, 125, 0 - colorPeach = "terrible" // 180, 0, 0 - colorBlack = "black" // 0, 0, 0 - colorLightGrey = "grey" // 221, 221, 221 - colorWhite = "white" // 255, 255, 255 - colorYellow = "yellow" // 255, 255, 0 - colorOlive = "olive" // 100, 100, 0 - colorCornflowerBlue = "rail_response" // 67, 135, 253 - colorSunsetOrange = "rail_animation" // 244, 74, 63 - colorTangerine = "rail_idle" // 238, 142, 0 - colorShamrockGreen = "rail_load" // 13, 168, 97 - colorGreenishYellow = "startup" // 230, 230, 0 - colorDarkGrey = "heap_dump_stack_frame" // 128, 128, 128 - colorTawny = "heap_dump_child_node_arrow" // 204, 102, 0 - colorLemon = "cq_build_running" // 255, 255, 119 - colorLime = "cq_build_passed" // 153, 238, 102 - colorPink = "cq_build_failed" // 238, 136, 136 - colorSilver = "cq_build_abandoned" // 187, 187, 187 - colorManzGreen = "cq_build_attempt_runnig" // 222, 222, 75 - colorKellyGreen = "cq_build_attempt_passed" // 108, 218, 35 - colorAnotherGrey = "cq_build_attempt_failed" // 187, 187, 187 -) - -var colorForTask = []string{ - colorLightMauve, - colorOrange, - colorSeafoamGreen, - colorVistaBlue, - colorTan, - colorMidnightBlue, - colorIrisBlue, - colorDeepMagenta, - colorGreen, - colorDarkGoldenrod, - colorPeach, - colorOlive, - colorCornflowerBlue, - colorSunsetOrange, - colorTangerine, - colorShamrockGreen, - colorTawny, - colorLemon, - colorLime, - colorPink, - colorSilver, - colorManzGreen, - colorKellyGreen, -} - -func pickTaskColor(id uint64) string { - idx := id % uint64(len(colorForTask)) - return colorForTask[idx] -} diff --git a/src/cmd/trace/trace_test.go b/src/cmd/trace/trace_test.go deleted file mode 100644 index 912b52cb60..0000000000 --- a/src/cmd/trace/trace_test.go +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !js - -package main - -import ( - "internal/trace" - "internal/trace/traceviewer" - "internal/trace/traceviewer/format" - "io" - "strings" - "testing" -) - -// stacks is a fake stack map populated for test. -type stacks map[uint64][]*trace.Frame - -// add adds a stack with a single frame whose Fn field is -// set to the provided fname and returns a unique stack id. -func (s *stacks) add(fname string) uint64 { - if *s == nil { - *s = make(map[uint64][]*trace.Frame) - } - - id := uint64(len(*s)) - (*s)[id] = []*trace.Frame{{Fn: fname}} - return id -} - -// TestGoroutineCount tests runnable/running goroutine counts computed by generateTrace -// remain in the valid range. -// - the counts must not be negative. generateTrace will return an error. -// - the counts must not include goroutines blocked waiting on channels or in syscall. -func TestGoroutineCount(t *testing.T) { - w := trace.NewWriter() - w.Emit(trace.EvBatch, 0, 0) // start of per-P batch event [pid, timestamp] - w.Emit(trace.EvFrequency, 1) // [ticks per second] - - var s stacks - - // In this test, we assume a valid trace contains EvGoWaiting or EvGoInSyscall - // event for every blocked goroutine. - - // goroutine 10: blocked - w.Emit(trace.EvGoCreate, 1, 10, s.add("pkg.f1"), s.add("main.f1")) // [timestamp, new goroutine id, new stack id, stack id] - w.Emit(trace.EvGoWaiting, 1, 10) // [timestamp, goroutine id] - - // goroutine 20: in syscall - w.Emit(trace.EvGoCreate, 1, 20, s.add("pkg.f2"), s.add("main.f2")) - w.Emit(trace.EvGoInSyscall, 1, 20) // [timestamp, goroutine id] - - // goroutine 30: runnable - w.Emit(trace.EvGoCreate, 1, 30, s.add("pkg.f3"), s.add("main.f3")) - - w.Emit(trace.EvProcStart, 2, 0) // [timestamp, thread id] - - // goroutine 40: runnable->running->runnable - w.Emit(trace.EvGoCreate, 1, 40, s.add("pkg.f4"), s.add("main.f4")) - w.Emit(trace.EvGoStartLocal, 1, 40) // [timestamp, goroutine id] - w.Emit(trace.EvGoSched, 1, s.add("main.f4")) // [timestamp, stack] - - res, err := trace.Parse(w, "") - if err != nil { - t.Fatalf("failed to parse test trace: %v", err) - } - res.Stacks = s // use fake stacks. - - params := &traceParams{ - parsed: res, - endTime: int64(1<<63 - 1), - } - - // Use the default viewerDataTraceConsumer but replace - // consumeViewerEvent to intercept the ViewerEvents for testing. - c := traceviewer.ViewerDataTraceConsumer(io.Discard, 0, 1<<63-1) - c.ConsumeViewerEvent = func(ev *format.Event, _ bool) { - if ev.Name == "Goroutines" { - cnt := ev.Arg.(*format.GoroutineCountersArg) - if cnt.Runnable+cnt.Running > 2 { - t.Errorf("goroutine count=%+v; want no more than 2 goroutines in runnable/running state", cnt) - } - t.Logf("read %+v %+v", ev, cnt) - } - } - - // If the counts drop below 0, generateTrace will return an error. - if err := generateTrace(params, c); err != nil { - t.Fatalf("generateTrace failed: %v", err) - } -} - -func TestGoroutineFilter(t *testing.T) { - // Test that we handle state changes to selected goroutines - // caused by events on goroutines that are not selected. - - var s stacks - - w := trace.NewWriter() - w.Emit(trace.EvBatch, 0, 0) // start of per-P batch event [pid, timestamp] - w.Emit(trace.EvFrequency, 1) // [ticks per second] - - // goroutine 10: blocked - w.Emit(trace.EvGoCreate, 1, 10, s.add("pkg.f1"), s.add("main.f1")) // [timestamp, new goroutine id, new stack id, stack id] - w.Emit(trace.EvGoWaiting, 1, 10) // [timestamp, goroutine id] - - // goroutine 20: runnable->running->unblock 10 - w.Emit(trace.EvGoCreate, 1, 20, s.add("pkg.f2"), s.add("main.f2")) - w.Emit(trace.EvGoStartLocal, 1, 20) // [timestamp, goroutine id] - w.Emit(trace.EvGoUnblockLocal, 1, 10, s.add("pkg.f2")) // [timestamp, goroutine id, stack] - w.Emit(trace.EvGoEnd, 1) // [timestamp] - - // goroutine 10: runnable->running->block - w.Emit(trace.EvGoStartLocal, 1, 10) // [timestamp, goroutine id] - w.Emit(trace.EvGoBlock, 1, s.add("pkg.f3")) // [timestamp, stack] - - res, err := trace.Parse(w, "") - if err != nil { - t.Fatalf("failed to parse test trace: %v", err) - } - res.Stacks = s // use fake stacks - - params := &traceParams{ - parsed: res, - endTime: int64(1<<63 - 1), - gs: map[uint64]bool{10: true}, - } - - c := traceviewer.ViewerDataTraceConsumer(io.Discard, 0, 1<<63-1) - if err := generateTrace(params, c); err != nil { - t.Fatalf("generateTrace failed: %v", err) - } -} - -func TestPreemptedMarkAssist(t *testing.T) { - w := trace.NewWriter() - w.Emit(trace.EvBatch, 0, 0) // start of per-P batch event [pid, timestamp] - w.Emit(trace.EvFrequency, 1) // [ticks per second] - - var s stacks - // goroutine 9999: running -> mark assisting -> preempted -> assisting -> running -> block - w.Emit(trace.EvGoCreate, 1, 9999, s.add("pkg.f1"), s.add("main.f1")) // [timestamp, new goroutine id, new stack id, stack id] - w.Emit(trace.EvGoStartLocal, 1, 9999) // [timestamp, goroutine id] - w.Emit(trace.EvGCMarkAssistStart, 1, s.add("main.f1")) // [timestamp, stack] - w.Emit(trace.EvGoPreempt, 1, s.add("main.f1")) // [timestamp, stack] - w.Emit(trace.EvGoStartLocal, 1, 9999) // [timestamp, goroutine id] - w.Emit(trace.EvGCMarkAssistDone, 1) // [timestamp] - w.Emit(trace.EvGoBlock, 1, s.add("main.f2")) // [timestamp, stack] - - res, err := trace.Parse(w, "") - if err != nil { - t.Fatalf("failed to parse test trace: %v", err) - } - res.Stacks = s // use fake stacks - - params := &traceParams{ - parsed: res, - endTime: int64(1<<63 - 1), - } - - c := traceviewer.ViewerDataTraceConsumer(io.Discard, 0, 1<<63-1) - - marks := 0 - c.ConsumeViewerEvent = func(ev *format.Event, _ bool) { - if strings.Contains(ev.Name, "MARK ASSIST") { - marks++ - } - } - if err := generateTrace(params, c); err != nil { - t.Fatalf("generateTrace failed: %v", err) - } - - if marks != 2 { - t.Errorf("Got %v MARK ASSIST events, want %v", marks, 2) - } -} diff --git a/src/cmd/trace/v2/gen.go b/src/cmd/trace/v2/gen.go deleted file mode 100644 index f6a4bb643b..0000000000 --- a/src/cmd/trace/v2/gen.go +++ /dev/null @@ -1,394 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - "fmt" - "internal/trace" - "internal/trace/traceviewer" - tracev2 "internal/trace/v2" - "strings" -) - -// generator is an interface for generating a JSON trace for the trace viewer -// from a trace. Each method in this interface is a handler for a kind of event -// that is interesting to render in the UI via the JSON trace. -type generator interface { - // Global parts. - Sync() // Notifies the generator of an EventSync event. - StackSample(ctx *traceContext, ev *tracev2.Event) - GlobalRange(ctx *traceContext, ev *tracev2.Event) - GlobalMetric(ctx *traceContext, ev *tracev2.Event) - - // Goroutine parts. - GoroutineLabel(ctx *traceContext, ev *tracev2.Event) - GoroutineRange(ctx *traceContext, ev *tracev2.Event) - GoroutineTransition(ctx *traceContext, ev *tracev2.Event) - - // Proc parts. - ProcRange(ctx *traceContext, ev *tracev2.Event) - ProcTransition(ctx *traceContext, ev *tracev2.Event) - - // User annotations. - Log(ctx *traceContext, ev *tracev2.Event) - - // Finish indicates the end of the trace and finalizes generation. - Finish(ctx *traceContext) -} - -// runGenerator produces a trace into ctx by running the generator over the parsed trace. -func runGenerator(ctx *traceContext, g generator, parsed *parsedTrace, opts *genOpts) { - for i := range parsed.events { - ev := &parsed.events[i] - - switch ev.Kind() { - case tracev2.EventSync: - g.Sync() - case tracev2.EventStackSample: - g.StackSample(ctx, ev) - case tracev2.EventRangeBegin, tracev2.EventRangeActive, tracev2.EventRangeEnd: - r := ev.Range() - switch r.Scope.Kind { - case tracev2.ResourceGoroutine: - g.GoroutineRange(ctx, ev) - case tracev2.ResourceProc: - g.ProcRange(ctx, ev) - case tracev2.ResourceNone: - g.GlobalRange(ctx, ev) - } - case tracev2.EventMetric: - g.GlobalMetric(ctx, ev) - case tracev2.EventLabel: - l := ev.Label() - if l.Resource.Kind == tracev2.ResourceGoroutine { - g.GoroutineLabel(ctx, ev) - } - case tracev2.EventStateTransition: - switch ev.StateTransition().Resource.Kind { - case tracev2.ResourceProc: - g.ProcTransition(ctx, ev) - case tracev2.ResourceGoroutine: - g.GoroutineTransition(ctx, ev) - } - case tracev2.EventLog: - g.Log(ctx, ev) - } - } - for i, task := range opts.tasks { - emitTask(ctx, task, i) - if opts.mode&traceviewer.ModeGoroutineOriented != 0 { - for _, region := range task.Regions { - emitRegion(ctx, region) - } - } - } - g.Finish(ctx) -} - -// emitTask emits information about a task into the trace viewer's event stream. -// -// sortIndex sets the order in which this task will appear related to other tasks, -// lowest first. -func emitTask(ctx *traceContext, task *trace.UserTaskSummary, sortIndex int) { - // Collect information about the task. - var startStack, endStack tracev2.Stack - var startG, endG tracev2.GoID - startTime, endTime := ctx.startTime, ctx.endTime - if task.Start != nil { - startStack = task.Start.Stack() - startG = task.Start.Goroutine() - startTime = task.Start.Time() - } - if task.End != nil { - endStack = task.End.Stack() - endG = task.End.Goroutine() - endTime = task.End.Time() - } - arg := struct { - ID uint64 `json:"id"` - StartG uint64 `json:"start_g,omitempty"` - EndG uint64 `json:"end_g,omitempty"` - }{ - ID: uint64(task.ID), - StartG: uint64(startG), - EndG: uint64(endG), - } - - // Emit the task slice and notify the emitter of the task. - ctx.Task(uint64(task.ID), fmt.Sprintf("T%d %s", task.ID, task.Name), sortIndex) - ctx.TaskSlice(traceviewer.SliceEvent{ - Name: task.Name, - Ts: ctx.elapsed(startTime), - Dur: endTime.Sub(startTime), - Resource: uint64(task.ID), - Stack: ctx.Stack(viewerFrames(startStack)), - EndStack: ctx.Stack(viewerFrames(endStack)), - Arg: arg, - }) - // Emit an arrow from the parent to the child. - if task.Parent != nil && task.Start != nil && task.Start.Kind() == tracev2.EventTaskBegin { - ctx.TaskArrow(traceviewer.ArrowEvent{ - Name: "newTask", - Start: ctx.elapsed(task.Start.Time()), - End: ctx.elapsed(task.Start.Time()), - FromResource: uint64(task.Parent.ID), - ToResource: uint64(task.ID), - FromStack: ctx.Stack(viewerFrames(task.Start.Stack())), - }) - } -} - -// emitRegion emits goroutine-based slice events to the UI. The caller -// must be emitting for a goroutine-oriented trace. -// -// TODO(mknyszek): Make regions part of the regular generator loop and -// treat them like ranges so that we can emit regions in traces oriented -// by proc or thread. -func emitRegion(ctx *traceContext, region *trace.UserRegionSummary) { - if region.Name == "" { - return - } - // Collect information about the region. - var startStack, endStack tracev2.Stack - goroutine := tracev2.NoGoroutine - startTime, endTime := ctx.startTime, ctx.endTime - if region.Start != nil { - startStack = region.Start.Stack() - startTime = region.Start.Time() - goroutine = region.Start.Goroutine() - } - if region.End != nil { - endStack = region.End.Stack() - endTime = region.End.Time() - goroutine = region.End.Goroutine() - } - if goroutine == tracev2.NoGoroutine { - return - } - arg := struct { - TaskID uint64 `json:"taskid"` - }{ - TaskID: uint64(region.TaskID), - } - ctx.AsyncSlice(traceviewer.AsyncSliceEvent{ - SliceEvent: traceviewer.SliceEvent{ - Name: region.Name, - Ts: ctx.elapsed(startTime), - Dur: endTime.Sub(startTime), - Resource: uint64(goroutine), - Stack: ctx.Stack(viewerFrames(startStack)), - EndStack: ctx.Stack(viewerFrames(endStack)), - Arg: arg, - }, - Category: "Region", - Scope: fmt.Sprintf("%x", region.TaskID), - TaskColorIndex: uint64(region.TaskID), - }) -} - -// Building blocks for generators. - -// stackSampleGenerator implements a generic handler for stack sample events. -// The provided resource is the resource the stack sample should count against. -type stackSampleGenerator[R resource] struct { - // getResource is a function to extract a resource ID from a stack sample event. - getResource func(*tracev2.Event) R -} - -// StackSample implements a stack sample event handler. It expects ev to be one such event. -func (g *stackSampleGenerator[R]) StackSample(ctx *traceContext, ev *tracev2.Event) { - id := g.getResource(ev) - if id == R(noResource) { - // We have nowhere to put this in the UI. - return - } - ctx.Instant(traceviewer.InstantEvent{ - Name: "CPU profile sample", - Ts: ctx.elapsed(ev.Time()), - Resource: uint64(id), - Stack: ctx.Stack(viewerFrames(ev.Stack())), - }) -} - -// globalRangeGenerator implements a generic handler for EventRange* events that pertain -// to tracev2.ResourceNone (the global scope). -type globalRangeGenerator struct { - ranges map[string]activeRange - seenSync bool -} - -// Sync notifies the generator of an EventSync event. -func (g *globalRangeGenerator) Sync() { - g.seenSync = true -} - -// GlobalRange implements a handler for EventRange* events whose Scope.Kind is ResourceNone. -// It expects ev to be one such event. -func (g *globalRangeGenerator) GlobalRange(ctx *traceContext, ev *tracev2.Event) { - if g.ranges == nil { - g.ranges = make(map[string]activeRange) - } - r := ev.Range() - switch ev.Kind() { - case tracev2.EventRangeBegin: - g.ranges[r.Name] = activeRange{ev.Time(), ev.Stack()} - case tracev2.EventRangeActive: - // If we've seen a Sync event, then Active events are always redundant. - if !g.seenSync { - // Otherwise, they extend back to the start of the trace. - g.ranges[r.Name] = activeRange{ctx.startTime, ev.Stack()} - } - case tracev2.EventRangeEnd: - // Only emit GC events, because we have nowhere to - // put other events. - ar := g.ranges[r.Name] - if strings.Contains(r.Name, "GC") { - ctx.Slice(traceviewer.SliceEvent{ - Name: r.Name, - Ts: ctx.elapsed(ar.time), - Dur: ev.Time().Sub(ar.time), - Resource: trace.GCP, - Stack: ctx.Stack(viewerFrames(ar.stack)), - EndStack: ctx.Stack(viewerFrames(ev.Stack())), - }) - } - delete(g.ranges, r.Name) - } -} - -// Finish flushes any outstanding ranges at the end of the trace. -func (g *globalRangeGenerator) Finish(ctx *traceContext) { - for name, ar := range g.ranges { - if !strings.Contains(name, "GC") { - continue - } - ctx.Slice(traceviewer.SliceEvent{ - Name: name, - Ts: ctx.elapsed(ar.time), - Dur: ctx.endTime.Sub(ar.time), - Resource: trace.GCP, - Stack: ctx.Stack(viewerFrames(ar.stack)), - }) - } -} - -// globalMetricGenerator implements a generic handler for Metric events. -type globalMetricGenerator struct { -} - -// GlobalMetric implements an event handler for EventMetric events. ev must be one such event. -func (g *globalMetricGenerator) GlobalMetric(ctx *traceContext, ev *tracev2.Event) { - m := ev.Metric() - switch m.Name { - case "/memory/classes/heap/objects:bytes": - ctx.HeapAlloc(ctx.elapsed(ev.Time()), m.Value.Uint64()) - case "/gc/heap/goal:bytes": - ctx.HeapGoal(ctx.elapsed(ev.Time()), m.Value.Uint64()) - case "/sched/gomaxprocs:threads": - ctx.Gomaxprocs(m.Value.Uint64()) - } -} - -// procRangeGenerator implements a generic handler for EventRange* events whose Scope.Kind is -// ResourceProc. -type procRangeGenerator struct { - ranges map[tracev2.Range]activeRange - seenSync bool -} - -// Sync notifies the generator of an EventSync event. -func (g *procRangeGenerator) Sync() { - g.seenSync = true -} - -// ProcRange implements a handler for EventRange* events whose Scope.Kind is ResourceProc. -// It expects ev to be one such event. -func (g *procRangeGenerator) ProcRange(ctx *traceContext, ev *tracev2.Event) { - if g.ranges == nil { - g.ranges = make(map[tracev2.Range]activeRange) - } - r := ev.Range() - switch ev.Kind() { - case tracev2.EventRangeBegin: - g.ranges[r] = activeRange{ev.Time(), ev.Stack()} - case tracev2.EventRangeActive: - // If we've seen a Sync event, then Active events are always redundant. - if !g.seenSync { - // Otherwise, they extend back to the start of the trace. - g.ranges[r] = activeRange{ctx.startTime, ev.Stack()} - } - case tracev2.EventRangeEnd: - // Emit proc-based ranges. - ar := g.ranges[r] - ctx.Slice(traceviewer.SliceEvent{ - Name: r.Name, - Ts: ctx.elapsed(ar.time), - Dur: ev.Time().Sub(ar.time), - Resource: uint64(r.Scope.Proc()), - Stack: ctx.Stack(viewerFrames(ar.stack)), - EndStack: ctx.Stack(viewerFrames(ev.Stack())), - }) - delete(g.ranges, r) - } -} - -// Finish flushes any outstanding ranges at the end of the trace. -func (g *procRangeGenerator) Finish(ctx *traceContext) { - for r, ar := range g.ranges { - ctx.Slice(traceviewer.SliceEvent{ - Name: r.Name, - Ts: ctx.elapsed(ar.time), - Dur: ctx.endTime.Sub(ar.time), - Resource: uint64(r.Scope.Proc()), - Stack: ctx.Stack(viewerFrames(ar.stack)), - }) - } -} - -// activeRange represents an active EventRange* range. -type activeRange struct { - time tracev2.Time - stack tracev2.Stack -} - -// completedRange represents a completed EventRange* range. -type completedRange struct { - name string - startTime tracev2.Time - endTime tracev2.Time - startStack tracev2.Stack - endStack tracev2.Stack - arg any -} - -type logEventGenerator[R resource] struct { - // getResource is a function to extract a resource ID from a Log event. - getResource func(*tracev2.Event) R -} - -// Log implements a log event handler. It expects ev to be one such event. -func (g *logEventGenerator[R]) Log(ctx *traceContext, ev *tracev2.Event) { - id := g.getResource(ev) - if id == R(noResource) { - // We have nowhere to put this in the UI. - return - } - - // Construct the name to present. - log := ev.Log() - name := log.Message - if log.Category != "" { - name = "[" + log.Category + "] " + name - } - - // Emit an instant event. - ctx.Instant(traceviewer.InstantEvent{ - Name: name, - Ts: ctx.elapsed(ev.Time()), - Category: "user event", - Resource: uint64(id), - Stack: ctx.Stack(viewerFrames(ev.Stack())), - }) -} diff --git a/src/cmd/trace/v2/goroutinegen.go b/src/cmd/trace/v2/goroutinegen.go deleted file mode 100644 index c76bd8487a..0000000000 --- a/src/cmd/trace/v2/goroutinegen.go +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - tracev2 "internal/trace/v2" -) - -var _ generator = &goroutineGenerator{} - -type goroutineGenerator struct { - globalRangeGenerator - globalMetricGenerator - stackSampleGenerator[tracev2.GoID] - logEventGenerator[tracev2.GoID] - - gStates map[tracev2.GoID]*gState[tracev2.GoID] - focus tracev2.GoID - filter map[tracev2.GoID]struct{} -} - -func newGoroutineGenerator(ctx *traceContext, focus tracev2.GoID, filter map[tracev2.GoID]struct{}) *goroutineGenerator { - gg := new(goroutineGenerator) - rg := func(ev *tracev2.Event) tracev2.GoID { - return ev.Goroutine() - } - gg.stackSampleGenerator.getResource = rg - gg.logEventGenerator.getResource = rg - gg.gStates = make(map[tracev2.GoID]*gState[tracev2.GoID]) - gg.focus = focus - gg.filter = filter - - // Enable a filter on the emitter. - if filter != nil { - ctx.SetResourceFilter(func(resource uint64) bool { - _, ok := filter[tracev2.GoID(resource)] - return ok - }) - } - return gg -} - -func (g *goroutineGenerator) Sync() { - g.globalRangeGenerator.Sync() -} - -func (g *goroutineGenerator) GoroutineLabel(ctx *traceContext, ev *tracev2.Event) { - l := ev.Label() - g.gStates[l.Resource.Goroutine()].setLabel(l.Label) -} - -func (g *goroutineGenerator) GoroutineRange(ctx *traceContext, ev *tracev2.Event) { - r := ev.Range() - switch ev.Kind() { - case tracev2.EventRangeBegin: - g.gStates[r.Scope.Goroutine()].rangeBegin(ev.Time(), r.Name, ev.Stack()) - case tracev2.EventRangeActive: - g.gStates[r.Scope.Goroutine()].rangeActive(r.Name) - case tracev2.EventRangeEnd: - gs := g.gStates[r.Scope.Goroutine()] - gs.rangeEnd(ev.Time(), r.Name, ev.Stack(), ctx) - } -} - -func (g *goroutineGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event) { - st := ev.StateTransition() - goID := st.Resource.Goroutine() - - // If we haven't seen this goroutine before, create a new - // gState for it. - gs, ok := g.gStates[goID] - if !ok { - gs = newGState[tracev2.GoID](goID) - g.gStates[goID] = gs - } - - // Try to augment the name of the goroutine. - gs.augmentName(st.Stack) - - // Handle the goroutine state transition. - from, to := st.Goroutine() - if from == to { - // Filter out no-op events. - return - } - if from.Executing() && !to.Executing() { - if to == tracev2.GoWaiting { - // Goroutine started blocking. - gs.block(ev.Time(), ev.Stack(), st.Reason, ctx) - } else { - gs.stop(ev.Time(), ev.Stack(), ctx) - } - } - if !from.Executing() && to.Executing() { - start := ev.Time() - if from == tracev2.GoUndetermined { - // Back-date the event to the start of the trace. - start = ctx.startTime - } - gs.start(start, goID, ctx) - } - - if from == tracev2.GoWaiting { - // Goroutine unblocked. - gs.unblock(ev.Time(), ev.Stack(), ev.Goroutine(), ctx) - } - if from == tracev2.GoNotExist && to == tracev2.GoRunnable { - // Goroutine was created. - gs.created(ev.Time(), ev.Goroutine(), ev.Stack()) - } - if from == tracev2.GoSyscall && to != tracev2.GoRunning { - // Exiting blocked syscall. - gs.syscallEnd(ev.Time(), true, ctx) - gs.blockedSyscallEnd(ev.Time(), ev.Stack(), ctx) - } else if from == tracev2.GoSyscall { - // Check if we're exiting a syscall in a non-blocking way. - gs.syscallEnd(ev.Time(), false, ctx) - } - - // Handle syscalls. - if to == tracev2.GoSyscall { - start := ev.Time() - if from == tracev2.GoUndetermined { - // Back-date the event to the start of the trace. - start = ctx.startTime - } - // Write down that we've entered a syscall. Note: we might have no G or P here - // if we're in a cgo callback or this is a transition from GoUndetermined - // (i.e. the G has been blocked in a syscall). - gs.syscallBegin(start, goID, ev.Stack()) - } - - // Note down the goroutine transition. - _, inMarkAssist := gs.activeRanges["GC mark assist"] - ctx.GoroutineTransition(ctx.elapsed(ev.Time()), viewerGState(from, inMarkAssist), viewerGState(to, inMarkAssist)) -} - -func (g *goroutineGenerator) ProcRange(ctx *traceContext, ev *tracev2.Event) { - // TODO(mknyszek): Extend procRangeGenerator to support rendering proc ranges - // that overlap with a goroutine's execution. -} - -func (g *goroutineGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { - // Not needed. All relevant information for goroutines can be derived from goroutine transitions. -} - -func (g *goroutineGenerator) Finish(ctx *traceContext) { - ctx.SetResourceType("G") - - // Finish off global ranges. - g.globalRangeGenerator.Finish(ctx) - - // Finish off all the goroutine slices. - for id, gs := range g.gStates { - gs.finish(ctx) - - // Tell the emitter about the goroutines we want to render. - ctx.Resource(uint64(id), gs.name()) - } - - // Set the goroutine to focus on. - if g.focus != tracev2.NoGoroutine { - ctx.Focus(uint64(g.focus)) - } -} diff --git a/src/cmd/trace/v2/goroutines.go b/src/cmd/trace/v2/goroutines.go deleted file mode 100644 index 3cf366635a..0000000000 --- a/src/cmd/trace/v2/goroutines.go +++ /dev/null @@ -1,420 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Goroutine-related profiles. - -package trace - -import ( - "cmp" - "fmt" - "html/template" - "internal/trace" - "internal/trace/traceviewer" - tracev2 "internal/trace/v2" - "log" - "net/http" - "slices" - "sort" - "strings" - "time" -) - -// GoroutinesHandlerFunc returns a HandlerFunc that serves list of goroutine groups. -func GoroutinesHandlerFunc(summaries map[tracev2.GoID]*trace.GoroutineSummary) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - // goroutineGroup describes a group of goroutines grouped by name. - type goroutineGroup struct { - Name string // Start function. - N int // Total number of goroutines in this group. - ExecTime time.Duration // Total execution time of all goroutines in this group. - } - // Accumulate groups by Name. - groupsByName := make(map[string]goroutineGroup) - for _, summary := range summaries { - group := groupsByName[summary.Name] - group.Name = summary.Name - group.N++ - group.ExecTime += summary.ExecTime - groupsByName[summary.Name] = group - } - var groups []goroutineGroup - for _, group := range groupsByName { - groups = append(groups, group) - } - slices.SortFunc(groups, func(a, b goroutineGroup) int { - return cmp.Compare(b.ExecTime, a.ExecTime) - }) - w.Header().Set("Content-Type", "text/html;charset=utf-8") - if err := templGoroutines.Execute(w, groups); err != nil { - log.Printf("failed to execute template: %v", err) - return - } - } -} - -var templGoroutines = template.Must(template.New("").Parse(` - - - -

Goroutines

-Below is a table of all goroutines in the trace grouped by start location and sorted by the total execution time of the group.
-
-Click a start location to view more details about that group.
-
-
WhenElapsedGoroutineEvents
{{$el.WhenString}}{{$el.Duration}} + Task {{$el.ID}} + (goroutine view) + ({{if .Complete}}complete{{else}}incomplete{{end}}) +
{{.WhenString}}{{elapsed .Elapsed}}{{.Goroutine}}{{.What}}
- - - - - -{{range $}} - - - - - -{{end}} -
Start locationCountTotal execution time
{{or .Name "(Inactive, no stack trace sampled)"}}{{.N}}{{.ExecTime}}
- - -`)) - -// GoroutineHandler creates a handler that serves information about -// goroutines in a particular group. -func GoroutineHandler(summaries map[tracev2.GoID]*trace.GoroutineSummary) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - goroutineName := r.FormValue("name") - - type goroutine struct { - *trace.GoroutineSummary - NonOverlappingStats map[string]time.Duration - HasRangeTime bool - } - - // Collect all the goroutines in the group. - var ( - goroutines []goroutine - name string - totalExecTime, execTime time.Duration - maxTotalTime time.Duration - ) - validNonOverlappingStats := make(map[string]struct{}) - validRangeStats := make(map[string]struct{}) - for _, summary := range summaries { - totalExecTime += summary.ExecTime - - if summary.Name != goroutineName { - continue - } - nonOverlappingStats := summary.NonOverlappingStats() - for name := range nonOverlappingStats { - validNonOverlappingStats[name] = struct{}{} - } - var totalRangeTime time.Duration - for name, dt := range summary.RangeTime { - validRangeStats[name] = struct{}{} - totalRangeTime += dt - } - goroutines = append(goroutines, goroutine{ - GoroutineSummary: summary, - NonOverlappingStats: nonOverlappingStats, - HasRangeTime: totalRangeTime != 0, - }) - name = summary.Name - execTime += summary.ExecTime - if maxTotalTime < summary.TotalTime { - maxTotalTime = summary.TotalTime - } - } - - // Compute the percent of total execution time these goroutines represent. - execTimePercent := "" - if totalExecTime > 0 { - execTimePercent = fmt.Sprintf("%.2f%%", float64(execTime)/float64(totalExecTime)*100) - } - - // Sort. - sortBy := r.FormValue("sortby") - if _, ok := validNonOverlappingStats[sortBy]; ok { - slices.SortFunc(goroutines, func(a, b goroutine) int { - return cmp.Compare(b.NonOverlappingStats[sortBy], a.NonOverlappingStats[sortBy]) - }) - } else { - // Sort by total time by default. - slices.SortFunc(goroutines, func(a, b goroutine) int { - return cmp.Compare(b.TotalTime, a.TotalTime) - }) - } - - // Write down all the non-overlapping stats and sort them. - allNonOverlappingStats := make([]string, 0, len(validNonOverlappingStats)) - for name := range validNonOverlappingStats { - allNonOverlappingStats = append(allNonOverlappingStats, name) - } - slices.SortFunc(allNonOverlappingStats, func(a, b string) int { - if a == b { - return 0 - } - if a == "Execution time" { - return -1 - } - if b == "Execution time" { - return 1 - } - return cmp.Compare(a, b) - }) - - // Write down all the range stats and sort them. - allRangeStats := make([]string, 0, len(validRangeStats)) - for name := range validRangeStats { - allRangeStats = append(allRangeStats, name) - } - sort.Strings(allRangeStats) - - err := templGoroutine.Execute(w, struct { - Name string - N int - ExecTimePercent string - MaxTotal time.Duration - Goroutines []goroutine - NonOverlappingStats []string - RangeStats []string - }{ - Name: name, - N: len(goroutines), - ExecTimePercent: execTimePercent, - MaxTotal: maxTotalTime, - Goroutines: goroutines, - NonOverlappingStats: allNonOverlappingStats, - RangeStats: allRangeStats, - }) - if err != nil { - http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) - return - } - } -} - -func stat2Color(statName string) string { - color := "#636363" - if strings.HasPrefix(statName, "Block time") { - color = "#d01c8b" - } - switch statName { - case "Sched wait time": - color = "#2c7bb6" - case "Syscall execution time": - color = "#7b3294" - case "Execution time": - color = "#d7191c" - } - return color -} - -var templGoroutine = template.Must(template.New("").Funcs(template.FuncMap{ - "percent": func(dividend, divisor time.Duration) template.HTML { - if divisor == 0 { - return "" - } - return template.HTML(fmt.Sprintf("(%.1f%%)", float64(dividend)/float64(divisor)*100)) - }, - "headerStyle": func(statName string) template.HTMLAttr { - return template.HTMLAttr(fmt.Sprintf("style=\"background-color: %s;\"", stat2Color(statName))) - }, - "barStyle": func(statName string, dividend, divisor time.Duration) template.HTMLAttr { - width := "0" - if divisor != 0 { - width = fmt.Sprintf("%.2f%%", float64(dividend)/float64(divisor)*100) - } - return template.HTMLAttr(fmt.Sprintf("style=\"width: %s; background-color: %s;\"", width, stat2Color(statName))) - }, -}).Parse(` - -Goroutines: {{.Name}} - - - - -

Goroutines

- -Table of contents - - -

Summary

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Goroutine start location:{{.Name}}
Count:{{.N}}
Execution Time:{{.ExecTimePercent}} of total program execution time
Network wait profile: graph (download)
Sync block profile: graph (download)
Syscall profile: graph (download)
Scheduler wait profile: graph (download)
- -

Breakdown

- -The table below breaks down where each goroutine is spent its time during the -traced period. -All of the columns except total time are non-overlapping. -
-
- - - - - - -{{range $.NonOverlappingStats}} - -{{end}} - -{{range .Goroutines}} - - - - - {{$Goroutine := .}} - {{range $.NonOverlappingStats}} - {{$Time := index $Goroutine.NonOverlappingStats .}} - - {{end}} - -{{end}} -
Goroutine Total {{.}}
{{.ID}} {{ .TotalTime.String }} -
- {{$Goroutine := .}} - {{range $.NonOverlappingStats}} - {{$Time := index $Goroutine.NonOverlappingStats .}} - {{if $Time}} -   - {{end}} - {{end}} -
-
{{$Time.String}}
- -

Special ranges

- -The table below describes how much of the traced period each goroutine spent in -certain special time ranges. -If a goroutine has spent no time in any special time ranges, it is excluded from -the table. -For example, how much time it spent helping the GC. Note that these times do -overlap with the times from the first table. -In general the goroutine may not be executing in these special time ranges. -For example, it may have blocked while trying to help the GC. -This must be taken into account when interpreting the data. -
-
- - - - - -{{range $.RangeStats}} - -{{end}} - -{{range .Goroutines}} - {{if .HasRangeTime}} - - - - {{$Goroutine := .}} - {{range $.RangeStats}} - {{$Time := index $Goroutine.RangeTime .}} - - {{end}} - - {{end}} -{{end}} -
Goroutine Total {{.}}
{{.ID}} {{ .TotalTime.String }} {{$Time.String}}
-`)) diff --git a/src/cmd/trace/v2/gstate.go b/src/cmd/trace/v2/gstate.go deleted file mode 100644 index d4e7042c98..0000000000 --- a/src/cmd/trace/v2/gstate.go +++ /dev/null @@ -1,373 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - "fmt" - "internal/trace" - "internal/trace/traceviewer" - "internal/trace/traceviewer/format" - tracev2 "internal/trace/v2" - "strings" -) - -// resource is a generic constraint interface for resource IDs. -type resource interface { - tracev2.GoID | tracev2.ProcID | tracev2.ThreadID -} - -// noResource indicates the lack of a resource. -const noResource = -1 - -// gState represents the trace viewer state of a goroutine in a trace. -// -// The type parameter on this type is the resource which is used to construct -// a timeline of events. e.g. R=ProcID for a proc-oriented view, R=GoID for -// a goroutine-oriented view, etc. -type gState[R resource] struct { - baseName string - named bool // Whether baseName has been set. - label string // EventLabel extension. - isSystemG bool - - executing R // The resource this goroutine is executing on. (Could be itself.) - - // lastStopStack is the stack trace at the point of the last - // call to the stop method. This tends to be a more reliable way - // of picking up stack traces, since the parser doesn't provide - // a stack for every state transition event. - lastStopStack tracev2.Stack - - // activeRanges is the set of all active ranges on the goroutine. - activeRanges map[string]activeRange - - // completedRanges is a list of ranges that completed since before the - // goroutine stopped executing. These are flushed on every stop or block. - completedRanges []completedRange - - // startRunning is the most recent event that caused a goroutine to - // transition to GoRunning. - startRunningTime tracev2.Time - - // startSyscall is the most recent event that caused a goroutine to - // transition to GoSyscall. - syscall struct { - time tracev2.Time - stack tracev2.Stack - active bool - } - - // startBlockReason is the StateTransition.Reason of the most recent - // event that caused a goroutine to transition to GoWaiting. - startBlockReason string - - // startCause is the event that allowed this goroutine to start running. - // It's used to generate flow events. This is typically something like - // an unblock event or a goroutine creation event. - // - // startCause.resource is the resource on which startCause happened, but is - // listed separately because the cause may have happened on a resource that - // isn't R (or perhaps on some abstract nebulous resource, like trace.NetpollP). - startCause struct { - time tracev2.Time - name string - resource uint64 - stack tracev2.Stack - } -} - -// newGState constructs a new goroutine state for the goroutine -// identified by the provided ID. -func newGState[R resource](goID tracev2.GoID) *gState[R] { - return &gState[R]{ - baseName: fmt.Sprintf("G%d", goID), - executing: R(noResource), - activeRanges: make(map[string]activeRange), - } -} - -// augmentName attempts to use stk to augment the name of the goroutine -// with stack information. This stack must be related to the goroutine -// in some way, but it doesn't really matter which stack. -func (gs *gState[R]) augmentName(stk tracev2.Stack) { - if gs.named { - return - } - if stk == tracev2.NoStack { - return - } - name := lastFunc(stk) - gs.baseName += fmt.Sprintf(" %s", name) - gs.named = true - gs.isSystemG = trace.IsSystemGoroutine(name) -} - -// setLabel adds an additional label to the goroutine's name. -func (gs *gState[R]) setLabel(label string) { - gs.label = label -} - -// name returns a name for the goroutine. -func (gs *gState[R]) name() string { - name := gs.baseName - if gs.label != "" { - name += " (" + gs.label + ")" - } - return name -} - -// setStartCause sets the reason a goroutine will be allowed to start soon. -// For example, via unblocking or exiting a blocked syscall. -func (gs *gState[R]) setStartCause(ts tracev2.Time, name string, resource uint64, stack tracev2.Stack) { - gs.startCause.time = ts - gs.startCause.name = name - gs.startCause.resource = resource - gs.startCause.stack = stack -} - -// created indicates that this goroutine was just created by the provided creator. -func (gs *gState[R]) created(ts tracev2.Time, creator R, stack tracev2.Stack) { - if creator == R(noResource) { - return - } - gs.setStartCause(ts, "go", uint64(creator), stack) -} - -// start indicates that a goroutine has started running on a proc. -func (gs *gState[R]) start(ts tracev2.Time, resource R, ctx *traceContext) { - // Set the time for all the active ranges. - for name := range gs.activeRanges { - gs.activeRanges[name] = activeRange{ts, tracev2.NoStack} - } - - if gs.startCause.name != "" { - // It has a start cause. Emit a flow event. - ctx.Arrow(traceviewer.ArrowEvent{ - Name: gs.startCause.name, - Start: ctx.elapsed(gs.startCause.time), - End: ctx.elapsed(ts), - FromResource: uint64(gs.startCause.resource), - ToResource: uint64(resource), - FromStack: ctx.Stack(viewerFrames(gs.startCause.stack)), - }) - gs.startCause.time = 0 - gs.startCause.name = "" - gs.startCause.resource = 0 - gs.startCause.stack = tracev2.NoStack - } - gs.executing = resource - gs.startRunningTime = ts -} - -// syscallBegin indicates that the goroutine entered a syscall on a proc. -func (gs *gState[R]) syscallBegin(ts tracev2.Time, resource R, stack tracev2.Stack) { - gs.syscall.time = ts - gs.syscall.stack = stack - gs.syscall.active = true - if gs.executing == R(noResource) { - gs.executing = resource - gs.startRunningTime = ts - } -} - -// syscallEnd ends the syscall slice, wherever the syscall is at. This is orthogonal -// to blockedSyscallEnd -- both must be called when a syscall ends and that syscall -// blocked. They're kept separate because syscallEnd indicates the point at which the -// goroutine is no longer executing on the resource (e.g. a proc) whereas blockedSyscallEnd -// is the point at which the goroutine actually exited the syscall regardless of which -// resource that happened on. -func (gs *gState[R]) syscallEnd(ts tracev2.Time, blocked bool, ctx *traceContext) { - if !gs.syscall.active { - return - } - blockString := "no" - if blocked { - blockString = "yes" - } - gs.completedRanges = append(gs.completedRanges, completedRange{ - name: "syscall", - startTime: gs.syscall.time, - endTime: ts, - startStack: gs.syscall.stack, - arg: format.BlockedArg{Blocked: blockString}, - }) - gs.syscall.active = false - gs.syscall.time = 0 - gs.syscall.stack = tracev2.NoStack -} - -// blockedSyscallEnd indicates the point at which the blocked syscall ended. This is distinct -// and orthogonal to syscallEnd; both must be called if the syscall blocked. This sets up an instant -// to emit a flow event from, indicating explicitly that this goroutine was unblocked by the system. -func (gs *gState[R]) blockedSyscallEnd(ts tracev2.Time, stack tracev2.Stack, ctx *traceContext) { - name := "exit blocked syscall" - gs.setStartCause(ts, name, trace.SyscallP, stack) - - // Emit an syscall exit instant event for the "Syscall" lane. - ctx.Instant(traceviewer.InstantEvent{ - Name: name, - Ts: ctx.elapsed(ts), - Resource: trace.SyscallP, - Stack: ctx.Stack(viewerFrames(stack)), - }) -} - -// unblock indicates that the goroutine gs represents has been unblocked. -func (gs *gState[R]) unblock(ts tracev2.Time, stack tracev2.Stack, resource R, ctx *traceContext) { - name := "unblock" - viewerResource := uint64(resource) - if gs.startBlockReason != "" { - name = fmt.Sprintf("%s (%s)", name, gs.startBlockReason) - } - if strings.Contains(gs.startBlockReason, "network") { - // Attribute the network instant to the nebulous "NetpollP" if - // resource isn't a thread, because there's a good chance that - // resource isn't going to be valid in this case. - // - // TODO(mknyszek): Handle this invalidness in a more general way. - if _, ok := any(resource).(tracev2.ThreadID); !ok { - // Emit an unblock instant event for the "Network" lane. - viewerResource = trace.NetpollP - } - ctx.Instant(traceviewer.InstantEvent{ - Name: name, - Ts: ctx.elapsed(ts), - Resource: viewerResource, - Stack: ctx.Stack(viewerFrames(stack)), - }) - } - gs.startBlockReason = "" - if viewerResource != 0 { - gs.setStartCause(ts, name, viewerResource, stack) - } -} - -// block indicates that the goroutine has stopped executing on a proc -- specifically, -// it blocked for some reason. -func (gs *gState[R]) block(ts tracev2.Time, stack tracev2.Stack, reason string, ctx *traceContext) { - gs.startBlockReason = reason - gs.stop(ts, stack, ctx) -} - -// stop indicates that the goroutine has stopped executing on a proc. -func (gs *gState[R]) stop(ts tracev2.Time, stack tracev2.Stack, ctx *traceContext) { - // Emit the execution time slice. - var stk int - if gs.lastStopStack != tracev2.NoStack { - stk = ctx.Stack(viewerFrames(gs.lastStopStack)) - } - // Check invariants. - if gs.startRunningTime == 0 { - panic("silently broken trace or generator invariant (startRunningTime != 0) not held") - } - if gs.executing == R(noResource) { - panic("non-executing goroutine stopped") - } - ctx.Slice(traceviewer.SliceEvent{ - Name: gs.name(), - Ts: ctx.elapsed(gs.startRunningTime), - Dur: ts.Sub(gs.startRunningTime), - Resource: uint64(gs.executing), - Stack: stk, - }) - - // Flush completed ranges. - for _, cr := range gs.completedRanges { - ctx.Slice(traceviewer.SliceEvent{ - Name: cr.name, - Ts: ctx.elapsed(cr.startTime), - Dur: cr.endTime.Sub(cr.startTime), - Resource: uint64(gs.executing), - Stack: ctx.Stack(viewerFrames(cr.startStack)), - EndStack: ctx.Stack(viewerFrames(cr.endStack)), - Arg: cr.arg, - }) - } - gs.completedRanges = gs.completedRanges[:0] - - // Continue in-progress ranges. - for name, r := range gs.activeRanges { - // Check invariant. - if r.time == 0 { - panic("silently broken trace or generator invariant (activeRanges time != 0) not held") - } - ctx.Slice(traceviewer.SliceEvent{ - Name: name, - Ts: ctx.elapsed(r.time), - Dur: ts.Sub(r.time), - Resource: uint64(gs.executing), - Stack: ctx.Stack(viewerFrames(r.stack)), - }) - } - - // Clear the range info. - for name := range gs.activeRanges { - gs.activeRanges[name] = activeRange{0, tracev2.NoStack} - } - - gs.startRunningTime = 0 - gs.lastStopStack = stack - gs.executing = R(noResource) -} - -// finalize writes out any in-progress slices as if the goroutine stopped. -// This must only be used once the trace has been fully processed and no -// further events will be processed. This method may leave the gState in -// an inconsistent state. -func (gs *gState[R]) finish(ctx *traceContext) { - if gs.executing != R(noResource) { - gs.syscallEnd(ctx.endTime, false, ctx) - gs.stop(ctx.endTime, tracev2.NoStack, ctx) - } -} - -// rangeBegin indicates the start of a special range of time. -func (gs *gState[R]) rangeBegin(ts tracev2.Time, name string, stack tracev2.Stack) { - if gs.executing != R(noResource) { - // If we're executing, start the slice from here. - gs.activeRanges[name] = activeRange{ts, stack} - } else { - // If the goroutine isn't executing, there's no place for - // us to create a slice from. Wait until it starts executing. - gs.activeRanges[name] = activeRange{0, stack} - } -} - -// rangeActive indicates that a special range of time has been in progress. -func (gs *gState[R]) rangeActive(name string) { - if gs.executing != R(noResource) { - // If we're executing, and the range is active, then start - // from wherever the goroutine started running from. - gs.activeRanges[name] = activeRange{gs.startRunningTime, tracev2.NoStack} - } else { - // If the goroutine isn't executing, there's no place for - // us to create a slice from. Wait until it starts executing. - gs.activeRanges[name] = activeRange{0, tracev2.NoStack} - } -} - -// rangeEnd indicates the end of a special range of time. -func (gs *gState[R]) rangeEnd(ts tracev2.Time, name string, stack tracev2.Stack, ctx *traceContext) { - if gs.executing != R(noResource) { - r := gs.activeRanges[name] - gs.completedRanges = append(gs.completedRanges, completedRange{ - name: name, - startTime: r.time, - endTime: ts, - startStack: r.stack, - endStack: stack, - }) - } - delete(gs.activeRanges, name) -} - -func lastFunc(s tracev2.Stack) string { - var last tracev2.StackFrame - s.Frames(func(f tracev2.StackFrame) bool { - last = f - return true - }) - return last.Func -} diff --git a/src/cmd/trace/v2/jsontrace.go b/src/cmd/trace/v2/jsontrace.go deleted file mode 100644 index e4ca613678..0000000000 --- a/src/cmd/trace/v2/jsontrace.go +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - "cmp" - "log" - "math" - "net/http" - "slices" - "strconv" - "time" - - "internal/trace" - "internal/trace/traceviewer" - tracev2 "internal/trace/v2" -) - -func JSONTraceHandler(parsed *parsedTrace) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - opts := defaultGenOpts() - - switch r.FormValue("view") { - case "thread": - opts.mode = traceviewer.ModeThreadOriented - } - if goids := r.FormValue("goid"); goids != "" { - // Render trace focused on a particular goroutine. - - id, err := strconv.ParseUint(goids, 10, 64) - if err != nil { - log.Printf("failed to parse goid parameter %q: %v", goids, err) - return - } - goid := tracev2.GoID(id) - g, ok := parsed.summary.Goroutines[goid] - if !ok { - log.Printf("failed to find goroutine %d", goid) - return - } - opts.mode = traceviewer.ModeGoroutineOriented - if g.StartTime != 0 { - opts.startTime = g.StartTime.Sub(parsed.startTime()) - } else { - opts.startTime = 0 - } - if g.EndTime != 0 { - opts.endTime = g.EndTime.Sub(parsed.startTime()) - } else { // The goroutine didn't end. - opts.endTime = parsed.endTime().Sub(parsed.startTime()) - } - opts.focusGoroutine = goid - opts.goroutines = trace.RelatedGoroutinesV2(parsed.events, goid) - } else if taskids := r.FormValue("focustask"); taskids != "" { - taskid, err := strconv.ParseUint(taskids, 10, 64) - if err != nil { - log.Printf("failed to parse focustask parameter %q: %v", taskids, err) - return - } - task, ok := parsed.summary.Tasks[tracev2.TaskID(taskid)] - if !ok || (task.Start == nil && task.End == nil) { - log.Printf("failed to find task with id %d", taskid) - return - } - opts.setTask(parsed, task) - } else if taskids := r.FormValue("taskid"); taskids != "" { - taskid, err := strconv.ParseUint(taskids, 10, 64) - if err != nil { - log.Printf("failed to parse taskid parameter %q: %v", taskids, err) - return - } - task, ok := parsed.summary.Tasks[tracev2.TaskID(taskid)] - if !ok { - log.Printf("failed to find task with id %d", taskid) - return - } - // This mode is goroutine-oriented. - opts.mode = traceviewer.ModeGoroutineOriented - opts.setTask(parsed, task) - - // Pick the goroutine to orient ourselves around by just - // trying to pick the earliest event in the task that makes - // any sense. Though, we always want the start if that's there. - var firstEv *tracev2.Event - if task.Start != nil { - firstEv = task.Start - } else { - for _, logEv := range task.Logs { - if firstEv == nil || logEv.Time() < firstEv.Time() { - firstEv = logEv - } - } - if task.End != nil && (firstEv == nil || task.End.Time() < firstEv.Time()) { - firstEv = task.End - } - } - if firstEv == nil || firstEv.Goroutine() == tracev2.NoGoroutine { - log.Printf("failed to find task with id %d", taskid) - return - } - - // Set the goroutine filtering options. - goid := firstEv.Goroutine() - opts.focusGoroutine = goid - goroutines := make(map[tracev2.GoID]struct{}) - for _, task := range opts.tasks { - // Find only directly involved goroutines. - for id := range task.Goroutines { - goroutines[id] = struct{}{} - } - } - opts.goroutines = goroutines - } - - // Parse start and end options. Both or none must be present. - start := int64(0) - end := int64(math.MaxInt64) - if startStr, endStr := r.FormValue("start"), r.FormValue("end"); startStr != "" && endStr != "" { - var err error - start, err = strconv.ParseInt(startStr, 10, 64) - if err != nil { - log.Printf("failed to parse start parameter %q: %v", startStr, err) - return - } - - end, err = strconv.ParseInt(endStr, 10, 64) - if err != nil { - log.Printf("failed to parse end parameter %q: %v", endStr, err) - return - } - } - - c := traceviewer.ViewerDataTraceConsumer(w, start, end) - if err := generateTrace(parsed, opts, c); err != nil { - log.Printf("failed to generate trace: %v", err) - } - }) -} - -// traceContext is a wrapper around a traceviewer.Emitter with some additional -// information that's useful to most parts of trace viewer JSON emission. -type traceContext struct { - *traceviewer.Emitter - startTime tracev2.Time - endTime tracev2.Time -} - -// elapsed returns the elapsed time between the trace time and the start time -// of the trace. -func (ctx *traceContext) elapsed(now tracev2.Time) time.Duration { - return now.Sub(ctx.startTime) -} - -type genOpts struct { - mode traceviewer.Mode - startTime time.Duration - endTime time.Duration - - // Used if mode != 0. - focusGoroutine tracev2.GoID - goroutines map[tracev2.GoID]struct{} // Goroutines to be displayed for goroutine-oriented or task-oriented view. goroutines[0] is the main goroutine. - tasks []*trace.UserTaskSummary -} - -// setTask sets a task to focus on. -func (opts *genOpts) setTask(parsed *parsedTrace, task *trace.UserTaskSummary) { - opts.mode |= traceviewer.ModeTaskOriented - if task.Start != nil { - opts.startTime = task.Start.Time().Sub(parsed.startTime()) - } else { // The task started before the trace did. - opts.startTime = 0 - } - if task.End != nil { - opts.endTime = task.End.Time().Sub(parsed.startTime()) - } else { // The task didn't end. - opts.endTime = parsed.endTime().Sub(parsed.startTime()) - } - opts.tasks = task.Descendents() - slices.SortStableFunc(opts.tasks, func(a, b *trace.UserTaskSummary) int { - aStart, bStart := parsed.startTime(), parsed.startTime() - if a.Start != nil { - aStart = a.Start.Time() - } - if b.Start != nil { - bStart = b.Start.Time() - } - if a.Start != b.Start { - return cmp.Compare(aStart, bStart) - } - // Break ties with the end time. - aEnd, bEnd := parsed.endTime(), parsed.endTime() - if a.End != nil { - aEnd = a.End.Time() - } - if b.End != nil { - bEnd = b.End.Time() - } - return cmp.Compare(aEnd, bEnd) - }) -} - -func defaultGenOpts() *genOpts { - return &genOpts{ - startTime: time.Duration(0), - endTime: time.Duration(math.MaxInt64), - } -} - -func generateTrace(parsed *parsedTrace, opts *genOpts, c traceviewer.TraceConsumer) error { - ctx := &traceContext{ - Emitter: traceviewer.NewEmitter(c, opts.startTime, opts.endTime), - startTime: parsed.events[0].Time(), - endTime: parsed.events[len(parsed.events)-1].Time(), - } - defer ctx.Flush() - - var g generator - if opts.mode&traceviewer.ModeGoroutineOriented != 0 { - g = newGoroutineGenerator(ctx, opts.focusGoroutine, opts.goroutines) - } else if opts.mode&traceviewer.ModeThreadOriented != 0 { - g = newThreadGenerator() - } else { - g = newProcGenerator() - } - runGenerator(ctx, g, parsed, opts) - return nil -} diff --git a/src/cmd/trace/v2/jsontrace_test.go b/src/cmd/trace/v2/jsontrace_test.go deleted file mode 100644 index e1a53669b7..0000000000 --- a/src/cmd/trace/v2/jsontrace_test.go +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - "bytes" - "encoding/json" - tracev1 "internal/trace" - "io" - "net/http/httptest" - "os" - "path/filepath" - "slices" - "strconv" - "strings" - "testing" - "time" - - "internal/trace/traceviewer/format" - "internal/trace/v2/raw" -) - -func TestJSONTraceHandler(t *testing.T) { - testPaths, err := filepath.Glob("./testdata/*.test") - if err != nil { - t.Fatalf("discovering tests: %v", err) - } - for _, testPath := range testPaths { - t.Run(filepath.Base(testPath), func(t *testing.T) { - parsed := getTestTrace(t, testPath) - data := recordJSONTraceHandlerResponse(t, parsed) - // TODO(mknyszek): Check that there's one at most goroutine per proc at any given time. - checkExecutionTimes(t, data) - checkPlausibleHeapMetrics(t, data) - // TODO(mknyszek): Check for plausible thread and goroutine metrics. - checkMetaNamesEmitted(t, data, "process_name", []string{"STATS", "PROCS"}) - checkMetaNamesEmitted(t, data, "thread_name", []string{"GC", "Network", "Timers", "Syscalls", "Proc 0"}) - checkProcStartStop(t, data) - checkSyscalls(t, data) - checkNetworkUnblock(t, data) - // TODO(mknyszek): Check for flow events. - }) - } -} - -func checkSyscalls(t *testing.T, data format.Data) { - data = filterViewerTrace(data, - filterEventName("syscall"), - filterStackRootFunc("main.blockingSyscall")) - if len(data.Events) <= 1 { - t.Errorf("got %d events, want > 1", len(data.Events)) - } - data = filterViewerTrace(data, filterBlocked("yes")) - if len(data.Events) != 1 { - t.Errorf("got %d events, want 1", len(data.Events)) - } -} - -type eventFilterFn func(*format.Event, *format.Data) bool - -func filterEventName(name string) eventFilterFn { - return func(e *format.Event, _ *format.Data) bool { - return e.Name == name - } -} - -// filterGoRoutineName returns an event filter that returns true if the event's -// goroutine name is equal to name. -func filterGoRoutineName(name string) eventFilterFn { - return func(e *format.Event, _ *format.Data) bool { - return parseGoroutineName(e) == name - } -} - -// parseGoroutineName returns the goroutine name from the event's name field. -// E.g. if e.Name is "G42 main.cpu10", this returns "main.cpu10". -func parseGoroutineName(e *format.Event) string { - parts := strings.SplitN(e.Name, " ", 2) - if len(parts) != 2 || !strings.HasPrefix(parts[0], "G") { - return "" - } - return parts[1] -} - -// filterBlocked returns an event filter that returns true if the event's -// "blocked" argument is equal to blocked. -func filterBlocked(blocked string) eventFilterFn { - return func(e *format.Event, _ *format.Data) bool { - m, ok := e.Arg.(map[string]any) - if !ok { - return false - } - return m["blocked"] == blocked - } -} - -// filterStackRootFunc returns an event filter that returns true if the function -// at the root of the stack trace is named name. -func filterStackRootFunc(name string) eventFilterFn { - return func(e *format.Event, data *format.Data) bool { - frames := stackFrames(data, e.Stack) - rootFrame := frames[len(frames)-1] - return strings.HasPrefix(rootFrame, name+":") - } -} - -// filterViewerTrace returns a copy of data with only the events that pass all -// of the given filters. -func filterViewerTrace(data format.Data, fns ...eventFilterFn) (filtered format.Data) { - filtered = data - filtered.Events = nil - for _, e := range data.Events { - keep := true - for _, fn := range fns { - keep = keep && fn(e, &filtered) - } - if keep { - filtered.Events = append(filtered.Events, e) - } - } - return -} - -func stackFrames(data *format.Data, stackID int) (frames []string) { - for { - frame, ok := data.Frames[strconv.Itoa(stackID)] - if !ok { - return - } - frames = append(frames, frame.Name) - stackID = frame.Parent - } -} - -func checkProcStartStop(t *testing.T, data format.Data) { - procStarted := map[uint64]bool{} - for _, e := range data.Events { - if e.Name == "proc start" { - if procStarted[e.TID] == true { - t.Errorf("proc started twice: %d", e.TID) - } - procStarted[e.TID] = true - } - if e.Name == "proc stop" { - if procStarted[e.TID] == false { - t.Errorf("proc stopped twice: %d", e.TID) - } - procStarted[e.TID] = false - } - } - if got, want := len(procStarted), 8; got != want { - t.Errorf("wrong number of procs started/stopped got=%d want=%d", got, want) - } -} - -func checkNetworkUnblock(t *testing.T, data format.Data) { - count := 0 - var netBlockEv *format.Event - for _, e := range data.Events { - if e.TID == tracev1.NetpollP && e.Name == "unblock (network)" && e.Phase == "I" && e.Scope == "t" { - count++ - netBlockEv = e - } - } - if netBlockEv == nil { - t.Error("failed to find a network unblock") - } - if count == 0 { - t.Errorf("found zero network block events, want at least one") - } - // TODO(mknyszek): Check for the flow of this event to some slice event of a goroutine running. -} - -func checkExecutionTimes(t *testing.T, data format.Data) { - cpu10 := sumExecutionTime(filterViewerTrace(data, filterGoRoutineName("main.cpu10"))) - cpu20 := sumExecutionTime(filterViewerTrace(data, filterGoRoutineName("main.cpu20"))) - if cpu10 <= 0 || cpu20 <= 0 || cpu10 >= cpu20 { - t.Errorf("bad execution times: cpu10=%v, cpu20=%v", cpu10, cpu20) - } -} - -func checkMetaNamesEmitted(t *testing.T, data format.Data, category string, want []string) { - t.Helper() - names := metaEventNameArgs(category, data) - for _, wantName := range want { - if !slices.Contains(names, wantName) { - t.Errorf("%s: names=%v, want %q", category, names, wantName) - } - } -} - -func metaEventNameArgs(category string, data format.Data) (names []string) { - for _, e := range data.Events { - if e.Name == category && e.Phase == "M" { - names = append(names, e.Arg.(map[string]any)["name"].(string)) - } - } - return -} - -func checkPlausibleHeapMetrics(t *testing.T, data format.Data) { - hms := heapMetrics(data) - var nonZeroAllocated, nonZeroNextGC bool - for _, hm := range hms { - if hm.Allocated > 0 { - nonZeroAllocated = true - } - if hm.NextGC > 0 { - nonZeroNextGC = true - } - } - - if !nonZeroAllocated { - t.Errorf("nonZeroAllocated=%v, want true", nonZeroAllocated) - } - if !nonZeroNextGC { - t.Errorf("nonZeroNextGC=%v, want true", nonZeroNextGC) - } -} - -func heapMetrics(data format.Data) (metrics []format.HeapCountersArg) { - for _, e := range data.Events { - if e.Phase == "C" && e.Name == "Heap" { - j, _ := json.Marshal(e.Arg) - var metric format.HeapCountersArg - json.Unmarshal(j, &metric) - metrics = append(metrics, metric) - } - } - return -} - -func recordJSONTraceHandlerResponse(t *testing.T, parsed *parsedTrace) format.Data { - h := JSONTraceHandler(parsed) - recorder := httptest.NewRecorder() - r := httptest.NewRequest("GET", "/jsontrace", nil) - h.ServeHTTP(recorder, r) - - var data format.Data - if err := json.Unmarshal(recorder.Body.Bytes(), &data); err != nil { - t.Fatal(err) - } - return data -} - -func sumExecutionTime(data format.Data) (sum time.Duration) { - for _, e := range data.Events { - sum += time.Duration(e.Dur) * time.Microsecond - } - return -} - -func getTestTrace(t *testing.T, testPath string) *parsedTrace { - t.Helper() - - // First read in the text trace and write it out as bytes. - f, err := os.Open(testPath) - if err != nil { - t.Fatalf("failed to open test %s: %v", testPath, err) - } - r, err := raw.NewTextReader(f) - if err != nil { - t.Fatalf("failed to read test %s: %v", testPath, err) - } - var trace bytes.Buffer - w, err := raw.NewWriter(&trace, r.Version()) - if err != nil { - t.Fatalf("failed to write out test %s: %v", testPath, err) - } - for { - ev, err := r.ReadEvent() - if err == io.EOF { - break - } - if err != nil { - t.Fatalf("failed to read test %s: %v", testPath, err) - } - if err := w.WriteEvent(ev); err != nil { - t.Fatalf("failed to write out test %s: %v", testPath, err) - } - } - - // Parse the test trace. - parsed, err := parseTrace(&trace, int64(trace.Len())) - if err != nil { - t.Fatalf("failed to parse trace: %v", err) - } - return parsed -} diff --git a/src/cmd/trace/v2/main.go b/src/cmd/trace/v2/main.go deleted file mode 100644 index 93e9fa742c..0000000000 --- a/src/cmd/trace/v2/main.go +++ /dev/null @@ -1,323 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - "fmt" - "internal/trace" - "internal/trace/traceviewer" - tracev2 "internal/trace/v2" - "io" - "log" - "net" - "net/http" - "os" - "sync/atomic" - "time" - - "internal/trace/v2/raw" - - "cmd/internal/browser" -) - -// Main is the main function for cmd/trace v2. -func Main(traceFile, httpAddr, pprof string, debug int) error { - tracef, err := os.Open(traceFile) - if err != nil { - return fmt.Errorf("failed to read trace file: %w", err) - } - defer tracef.Close() - - // Get the size of the trace file. - fi, err := tracef.Stat() - if err != nil { - return fmt.Errorf("failed to stat trace file: %v", err) - } - traceSize := fi.Size() - - // Handle requests for profiles. - if pprof != "" { - parsed, err := parseTrace(tracef, traceSize) - if err != nil { - return err - } - var f traceviewer.ProfileFunc - switch pprof { - case "net": - f = pprofByGoroutine(computePprofIO(), parsed) - case "sync": - f = pprofByGoroutine(computePprofBlock(), parsed) - case "syscall": - f = pprofByGoroutine(computePprofSyscall(), parsed) - case "sched": - f = pprofByGoroutine(computePprofSched(), parsed) - default: - return fmt.Errorf("unknown pprof type %s\n", pprof) - } - records, err := f(&http.Request{}) - if err != nil { - return fmt.Errorf("failed to generate pprof: %v\n", err) - } - if err := traceviewer.BuildProfile(records).Write(os.Stdout); err != nil { - return fmt.Errorf("failed to generate pprof: %v\n", err) - } - return nil - } - - // Debug flags. - switch debug { - case 1: - return debugProcessedEvents(tracef) - case 2: - return debugRawEvents(tracef) - } - - ln, err := net.Listen("tcp", httpAddr) - if err != nil { - return fmt.Errorf("failed to create server socket: %w", err) - } - addr := "http://" + ln.Addr().String() - - log.Print("Preparing trace for viewer...") - parsed, err := parseTraceInteractive(tracef, traceSize) - if err != nil { - return err - } - // N.B. tracef not needed after this point. - // We might double-close, but that's fine; we ignore the error. - tracef.Close() - - // Print a nice message for a partial trace. - if parsed.err != nil { - log.Printf("Encountered error, but able to proceed. Error: %v", parsed.err) - - lost := parsed.size - parsed.valid - pct := float64(lost) / float64(parsed.size) * 100 - log.Printf("Lost %.2f%% of the latest trace data due to error (%s of %s)", pct, byteCount(lost), byteCount(parsed.size)) - } - - log.Print("Splitting trace for viewer...") - ranges, err := splitTrace(parsed) - if err != nil { - return err - } - - log.Printf("Opening browser. Trace viewer is listening on %s", addr) - browser.Open(addr) - - mutatorUtil := func(flags trace.UtilFlags) ([][]trace.MutatorUtil, error) { - return trace.MutatorUtilizationV2(parsed.events, flags), nil - } - - mux := http.NewServeMux() - - // Main endpoint. - mux.Handle("/", traceviewer.MainHandler([]traceviewer.View{ - {Type: traceviewer.ViewProc, Ranges: ranges}, - // N.B. Use the same ranges for threads. It takes a long time to compute - // the split a second time, but the makeup of the events are similar enough - // that this is still a good split. - {Type: traceviewer.ViewThread, Ranges: ranges}, - })) - - // Catapult handlers. - mux.Handle("/trace", traceviewer.TraceHandler()) - mux.Handle("/jsontrace", JSONTraceHandler(parsed)) - mux.Handle("/static/", traceviewer.StaticHandler()) - - // Goroutines handlers. - mux.HandleFunc("/goroutines", GoroutinesHandlerFunc(parsed.summary.Goroutines)) - mux.HandleFunc("/goroutine", GoroutineHandler(parsed.summary.Goroutines)) - - // MMU handler. - mux.HandleFunc("/mmu", traceviewer.MMUHandlerFunc(ranges, mutatorUtil)) - - // Basic pprof endpoints. - mux.HandleFunc("/io", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofIO(), parsed))) - mux.HandleFunc("/block", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofBlock(), parsed))) - mux.HandleFunc("/syscall", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofSyscall(), parsed))) - mux.HandleFunc("/sched", traceviewer.SVGProfileHandlerFunc(pprofByGoroutine(computePprofSched(), parsed))) - - // Region-based pprof endpoints. - mux.HandleFunc("/regionio", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofIO(), parsed))) - mux.HandleFunc("/regionblock", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofBlock(), parsed))) - mux.HandleFunc("/regionsyscall", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofSyscall(), parsed))) - mux.HandleFunc("/regionsched", traceviewer.SVGProfileHandlerFunc(pprofByRegion(computePprofSched(), parsed))) - - // Region endpoints. - mux.HandleFunc("/userregions", UserRegionsHandlerFunc(parsed)) - mux.HandleFunc("/userregion", UserRegionHandlerFunc(parsed)) - - // Task endpoints. - mux.HandleFunc("/usertasks", UserTasksHandlerFunc(parsed)) - mux.HandleFunc("/usertask", UserTaskHandlerFunc(parsed)) - - err = http.Serve(ln, mux) - return fmt.Errorf("failed to start http server: %w", err) -} - -func parseTraceInteractive(tr io.Reader, size int64) (parsed *parsedTrace, err error) { - done := make(chan struct{}) - cr := countingReader{r: tr} - go func() { - parsed, err = parseTrace(&cr, size) - done <- struct{}{} - }() - ticker := time.NewTicker(5 * time.Second) -progressLoop: - for { - select { - case <-ticker.C: - case <-done: - ticker.Stop() - break progressLoop - } - progress := cr.bytesRead.Load() - pct := float64(progress) / float64(size) * 100 - log.Printf("%s of %s (%.1f%%) processed...", byteCount(progress), byteCount(size), pct) - } - return -} - -type parsedTrace struct { - events []tracev2.Event - summary *trace.Summary - size, valid int64 - err error -} - -func parseTrace(rr io.Reader, size int64) (*parsedTrace, error) { - // Set up the reader. - cr := countingReader{r: rr} - r, err := tracev2.NewReader(&cr) - if err != nil { - return nil, fmt.Errorf("failed to create trace reader: %w", err) - } - - // Set up state. - s := trace.NewSummarizer() - t := new(parsedTrace) - var validBytes int64 - var validEvents int - for { - ev, err := r.ReadEvent() - if err == io.EOF { - validBytes = cr.bytesRead.Load() - validEvents = len(t.events) - break - } - if err != nil { - t.err = err - break - } - t.events = append(t.events, ev) - s.Event(&t.events[len(t.events)-1]) - - if ev.Kind() == tracev2.EventSync { - validBytes = cr.bytesRead.Load() - validEvents = len(t.events) - } - } - - // Check to make sure we got at least one good generation. - if validEvents == 0 { - return nil, fmt.Errorf("failed to parse any useful part of the trace: %v", t.err) - } - - // Finish off the parsedTrace. - t.summary = s.Finalize() - t.valid = validBytes - t.size = size - t.events = t.events[:validEvents] - return t, nil -} - -func (t *parsedTrace) startTime() tracev2.Time { - return t.events[0].Time() -} - -func (t *parsedTrace) endTime() tracev2.Time { - return t.events[len(t.events)-1].Time() -} - -// splitTrace splits the trace into a number of ranges, each resulting in approx 100 MiB of -// json output (the trace viewer can hardly handle more). -func splitTrace(parsed *parsedTrace) ([]traceviewer.Range, error) { - // TODO(mknyszek): Split traces by generation by doing a quick first pass over the - // trace to identify all the generation boundaries. - s, c := traceviewer.SplittingTraceConsumer(100 << 20) // 100 MiB - if err := generateTrace(parsed, defaultGenOpts(), c); err != nil { - return nil, err - } - return s.Ranges, nil -} - -func debugProcessedEvents(trace io.Reader) error { - tr, err := tracev2.NewReader(trace) - if err != nil { - return err - } - for { - ev, err := tr.ReadEvent() - if err == io.EOF { - return nil - } else if err != nil { - return err - } - fmt.Println(ev.String()) - } -} - -func debugRawEvents(trace io.Reader) error { - rr, err := raw.NewReader(trace) - if err != nil { - return err - } - for { - ev, err := rr.ReadEvent() - if err == io.EOF { - return nil - } else if err != nil { - return err - } - fmt.Println(ev.String()) - } -} - -type countingReader struct { - r io.Reader - bytesRead atomic.Int64 -} - -func (c *countingReader) Read(buf []byte) (n int, err error) { - n, err = c.r.Read(buf) - c.bytesRead.Add(int64(n)) - return n, err -} - -type byteCount int64 - -func (b byteCount) String() string { - var suffix string - var divisor int64 - switch { - case b < 1<<10: - suffix = "B" - divisor = 1 - case b < 1<<20: - suffix = "KiB" - divisor = 1 << 10 - case b < 1<<30: - suffix = "MiB" - divisor = 1 << 20 - case b < 1<<40: - suffix = "GiB" - divisor = 1 << 30 - } - if divisor == 1 { - return fmt.Sprintf("%d %s", b, suffix) - } - return fmt.Sprintf("%.1f %s", float64(b)/float64(divisor), suffix) -} diff --git a/src/cmd/trace/v2/pprof.go b/src/cmd/trace/v2/pprof.go deleted file mode 100644 index 43b0257fc0..0000000000 --- a/src/cmd/trace/v2/pprof.go +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Serving of pprof-like profiles. - -package trace - -import ( - "cmp" - "fmt" - "internal/trace" - "internal/trace/traceviewer" - tracev2 "internal/trace/v2" - "net/http" - "slices" - "strings" - "time" -) - -func pprofByGoroutine(compute computePprofFunc, t *parsedTrace) traceviewer.ProfileFunc { - return func(r *http.Request) ([]traceviewer.ProfileRecord, error) { - name := r.FormValue("name") - gToIntervals, err := pprofMatchingGoroutines(name, t) - if err != nil { - return nil, err - } - return compute(gToIntervals, t.events) - } -} - -func pprofByRegion(compute computePprofFunc, t *parsedTrace) traceviewer.ProfileFunc { - return func(r *http.Request) ([]traceviewer.ProfileRecord, error) { - filter, err := newRegionFilter(r) - if err != nil { - return nil, err - } - gToIntervals, err := pprofMatchingRegions(filter, t) - if err != nil { - return nil, err - } - return compute(gToIntervals, t.events) - } -} - -// pprofMatchingGoroutines returns the ids of goroutines of the matching name and its interval. -// If the id string is empty, returns nil without an error. -func pprofMatchingGoroutines(name string, t *parsedTrace) (map[tracev2.GoID][]interval, error) { - res := make(map[tracev2.GoID][]interval) - for _, g := range t.summary.Goroutines { - if name != "" && g.Name != name { - continue - } - endTime := g.EndTime - if g.EndTime == 0 { - endTime = t.endTime() // Use the trace end time, since the goroutine is still live then. - } - res[g.ID] = []interval{{start: g.StartTime, end: endTime}} - } - if len(res) == 0 { - return nil, fmt.Errorf("failed to find matching goroutines for name: %s", name) - } - return res, nil -} - -// pprofMatchingRegions returns the time intervals of matching regions -// grouped by the goroutine id. If the filter is nil, returns nil without an error. -func pprofMatchingRegions(filter *regionFilter, t *parsedTrace) (map[tracev2.GoID][]interval, error) { - if filter == nil { - return nil, nil - } - - gToIntervals := make(map[tracev2.GoID][]interval) - for _, g := range t.summary.Goroutines { - for _, r := range g.Regions { - if !filter.match(t, r) { - continue - } - gToIntervals[g.ID] = append(gToIntervals[g.ID], regionInterval(t, r)) - } - } - - for g, intervals := range gToIntervals { - // In order to remove nested regions and - // consider only the outermost regions, - // first, we sort based on the start time - // and then scan through to select only the outermost regions. - slices.SortFunc(intervals, func(a, b interval) int { - if c := cmp.Compare(a.start, b.start); c != 0 { - return c - } - return cmp.Compare(a.end, b.end) - }) - var lastTimestamp tracev2.Time - var n int - // Select only the outermost regions. - for _, i := range intervals { - if lastTimestamp <= i.start { - intervals[n] = i // new non-overlapping region starts. - lastTimestamp = i.end - n++ - } - // Otherwise, skip because this region overlaps with a previous region. - } - gToIntervals[g] = intervals[:n] - } - return gToIntervals, nil -} - -type computePprofFunc func(gToIntervals map[tracev2.GoID][]interval, events []tracev2.Event) ([]traceviewer.ProfileRecord, error) - -// computePprofIO returns a computePprofFunc that generates IO pprof-like profile (time spent in -// IO wait, currently only network blocking event). -func computePprofIO() computePprofFunc { - return makeComputePprofFunc(tracev2.GoWaiting, func(reason string) bool { - return reason == "network" - }) -} - -// computePprofBlock returns a computePprofFunc that generates blocking pprof-like profile -// (time spent blocked on synchronization primitives). -func computePprofBlock() computePprofFunc { - return makeComputePprofFunc(tracev2.GoWaiting, func(reason string) bool { - return strings.Contains(reason, "chan") || strings.Contains(reason, "sync") || strings.Contains(reason, "select") - }) -} - -// computePprofSyscall returns a computePprofFunc that generates a syscall pprof-like -// profile (time spent in syscalls). -func computePprofSyscall() computePprofFunc { - return makeComputePprofFunc(tracev2.GoSyscall, func(_ string) bool { - return true - }) -} - -// computePprofSched returns a computePprofFunc that generates a scheduler latency pprof-like profile -// (time between a goroutine become runnable and actually scheduled for execution). -func computePprofSched() computePprofFunc { - return makeComputePprofFunc(tracev2.GoRunnable, func(_ string) bool { - return true - }) -} - -// makeComputePprofFunc returns a computePprofFunc that generates a profile of time goroutines spend -// in a particular state for the specified reasons. -func makeComputePprofFunc(state tracev2.GoState, trackReason func(string) bool) computePprofFunc { - return func(gToIntervals map[tracev2.GoID][]interval, events []tracev2.Event) ([]traceviewer.ProfileRecord, error) { - stacks := newStackMap() - tracking := make(map[tracev2.GoID]*tracev2.Event) - for i := range events { - ev := &events[i] - - // Filter out any non-state-transitions and events without stacks. - if ev.Kind() != tracev2.EventStateTransition { - continue - } - stack := ev.Stack() - if stack == tracev2.NoStack { - continue - } - - // The state transition has to apply to a goroutine. - st := ev.StateTransition() - if st.Resource.Kind != tracev2.ResourceGoroutine { - continue - } - id := st.Resource.Goroutine() - _, new := st.Goroutine() - - // Check if we're tracking this goroutine. - startEv := tracking[id] - if startEv == nil { - // We're not. Start tracking if the new state - // matches what we want and the transition is - // for one of the reasons we care about. - if new == state && trackReason(st.Reason) { - tracking[id] = ev - } - continue - } - // We're tracking this goroutine. - if new == state { - // We're tracking this goroutine, but it's just transitioning - // to the same state (this is a no-ip - continue - } - // The goroutine has transitioned out of the state we care about, - // so remove it from tracking and record the stack. - delete(tracking, id) - - overlapping := pprofOverlappingDuration(gToIntervals, id, interval{startEv.Time(), ev.Time()}) - if overlapping > 0 { - rec := stacks.getOrAdd(startEv.Stack()) - rec.Count++ - rec.Time += overlapping - } - } - return stacks.profile(), nil - } -} - -// pprofOverlappingDuration returns the overlapping duration between -// the time intervals in gToIntervals and the specified event. -// If gToIntervals is nil, this simply returns the event's duration. -func pprofOverlappingDuration(gToIntervals map[tracev2.GoID][]interval, id tracev2.GoID, sample interval) time.Duration { - if gToIntervals == nil { // No filtering. - return sample.duration() - } - intervals := gToIntervals[id] - if len(intervals) == 0 { - return 0 - } - - var overlapping time.Duration - for _, i := range intervals { - if o := i.overlap(sample); o > 0 { - overlapping += o - } - } - return overlapping -} - -// interval represents a time interval in the trace. -type interval struct { - start, end tracev2.Time -} - -func (i interval) duration() time.Duration { - return i.end.Sub(i.start) -} - -func (i1 interval) overlap(i2 interval) time.Duration { - // Assume start1 <= end1 and start2 <= end2 - if i1.end < i2.start || i2.end < i1.start { - return 0 - } - if i1.start < i2.start { // choose the later one - i1.start = i2.start - } - if i1.end > i2.end { // choose the earlier one - i1.end = i2.end - } - return i1.duration() -} - -// pprofMaxStack is the extent of the deduplication we're willing to do. -// -// Because slices aren't comparable and we want to leverage maps for deduplication, -// we have to choose a fixed constant upper bound on the amount of frames we want -// to support. In practice this is fine because there's a maximum depth to these -// stacks anyway. -const pprofMaxStack = 128 - -// stackMap is a map of tracev2.Stack to some value V. -type stackMap struct { - // stacks contains the full list of stacks in the set, however - // it is insufficient for deduplication because tracev2.Stack - // equality is only optimistic. If two tracev2.Stacks are equal, - // then they are guaranteed to be equal in content. If they are - // not equal, then they might still be equal in content. - stacks map[tracev2.Stack]*traceviewer.ProfileRecord - - // pcs is the source-of-truth for deduplication. It is a map of - // the actual PCs in the stack to a tracev2.Stack. - pcs map[[pprofMaxStack]uint64]tracev2.Stack -} - -func newStackMap() *stackMap { - return &stackMap{ - stacks: make(map[tracev2.Stack]*traceviewer.ProfileRecord), - pcs: make(map[[pprofMaxStack]uint64]tracev2.Stack), - } -} - -func (m *stackMap) getOrAdd(stack tracev2.Stack) *traceviewer.ProfileRecord { - // Fast path: check to see if this exact stack is already in the map. - if rec, ok := m.stacks[stack]; ok { - return rec - } - // Slow path: the stack may still be in the map. - - // Grab the stack's PCs as the source-of-truth. - var pcs [pprofMaxStack]uint64 - pcsForStack(stack, &pcs) - - // Check the source-of-truth. - var rec *traceviewer.ProfileRecord - if existing, ok := m.pcs[pcs]; ok { - // In the map. - rec = m.stacks[existing] - delete(m.stacks, existing) - } else { - // Not in the map. - rec = new(traceviewer.ProfileRecord) - } - // Insert regardless of whether we have a match in m.pcs. - // Even if we have a match, we want to keep the newest version - // of that stack, since we're much more likely tos see it again - // as we iterate through the trace linearly. Simultaneously, we - // are likely to never see the old stack again. - m.pcs[pcs] = stack - m.stacks[stack] = rec - return rec -} - -func (m *stackMap) profile() []traceviewer.ProfileRecord { - prof := make([]traceviewer.ProfileRecord, 0, len(m.stacks)) - for stack, record := range m.stacks { - rec := *record - i := 0 - stack.Frames(func(frame tracev2.StackFrame) bool { - rec.Stack = append(rec.Stack, &trace.Frame{ - PC: frame.PC, - Fn: frame.Func, - File: frame.File, - Line: int(frame.Line), - }) - i++ - // Cut this off at pprofMaxStack because that's as far - // as our deduplication goes. - return i < pprofMaxStack - }) - prof = append(prof, rec) - } - return prof -} - -// pcsForStack extracts the first pprofMaxStack PCs from stack into pcs. -func pcsForStack(stack tracev2.Stack, pcs *[pprofMaxStack]uint64) { - i := 0 - stack.Frames(func(frame tracev2.StackFrame) bool { - pcs[i] = frame.PC - i++ - return i < len(pcs) - }) -} diff --git a/src/cmd/trace/v2/procgen.go b/src/cmd/trace/v2/procgen.go deleted file mode 100644 index 41e379527f..0000000000 --- a/src/cmd/trace/v2/procgen.go +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - "fmt" - "internal/trace/traceviewer" - "internal/trace/traceviewer/format" - tracev2 "internal/trace/v2" -) - -var _ generator = &procGenerator{} - -type procGenerator struct { - globalRangeGenerator - globalMetricGenerator - procRangeGenerator - stackSampleGenerator[tracev2.ProcID] - logEventGenerator[tracev2.ProcID] - - gStates map[tracev2.GoID]*gState[tracev2.ProcID] - inSyscall map[tracev2.ProcID]*gState[tracev2.ProcID] - maxProc tracev2.ProcID -} - -func newProcGenerator() *procGenerator { - pg := new(procGenerator) - rg := func(ev *tracev2.Event) tracev2.ProcID { - return ev.Proc() - } - pg.stackSampleGenerator.getResource = rg - pg.logEventGenerator.getResource = rg - pg.gStates = make(map[tracev2.GoID]*gState[tracev2.ProcID]) - pg.inSyscall = make(map[tracev2.ProcID]*gState[tracev2.ProcID]) - return pg -} - -func (g *procGenerator) Sync() { - g.globalRangeGenerator.Sync() - g.procRangeGenerator.Sync() -} - -func (g *procGenerator) GoroutineLabel(ctx *traceContext, ev *tracev2.Event) { - l := ev.Label() - g.gStates[l.Resource.Goroutine()].setLabel(l.Label) -} - -func (g *procGenerator) GoroutineRange(ctx *traceContext, ev *tracev2.Event) { - r := ev.Range() - switch ev.Kind() { - case tracev2.EventRangeBegin: - g.gStates[r.Scope.Goroutine()].rangeBegin(ev.Time(), r.Name, ev.Stack()) - case tracev2.EventRangeActive: - g.gStates[r.Scope.Goroutine()].rangeActive(r.Name) - case tracev2.EventRangeEnd: - gs := g.gStates[r.Scope.Goroutine()] - gs.rangeEnd(ev.Time(), r.Name, ev.Stack(), ctx) - } -} - -func (g *procGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event) { - st := ev.StateTransition() - goID := st.Resource.Goroutine() - - // If we haven't seen this goroutine before, create a new - // gState for it. - gs, ok := g.gStates[goID] - if !ok { - gs = newGState[tracev2.ProcID](goID) - g.gStates[goID] = gs - } - // If we haven't already named this goroutine, try to name it. - gs.augmentName(st.Stack) - - // Handle the goroutine state transition. - from, to := st.Goroutine() - if from == to { - // Filter out no-op events. - return - } - if from == tracev2.GoRunning && !to.Executing() { - if to == tracev2.GoWaiting { - // Goroutine started blocking. - gs.block(ev.Time(), ev.Stack(), st.Reason, ctx) - } else { - gs.stop(ev.Time(), ev.Stack(), ctx) - } - } - if !from.Executing() && to == tracev2.GoRunning { - start := ev.Time() - if from == tracev2.GoUndetermined { - // Back-date the event to the start of the trace. - start = ctx.startTime - } - gs.start(start, ev.Proc(), ctx) - } - - if from == tracev2.GoWaiting { - // Goroutine was unblocked. - gs.unblock(ev.Time(), ev.Stack(), ev.Proc(), ctx) - } - if from == tracev2.GoNotExist && to == tracev2.GoRunnable { - // Goroutine was created. - gs.created(ev.Time(), ev.Proc(), ev.Stack()) - } - if from == tracev2.GoSyscall && to != tracev2.GoRunning { - // Goroutine exited a blocked syscall. - gs.blockedSyscallEnd(ev.Time(), ev.Stack(), ctx) - } - - // Handle syscalls. - if to == tracev2.GoSyscall && ev.Proc() != tracev2.NoProc { - start := ev.Time() - if from == tracev2.GoUndetermined { - // Back-date the event to the start of the trace. - start = ctx.startTime - } - // Write down that we've entered a syscall. Note: we might have no P here - // if we're in a cgo callback or this is a transition from GoUndetermined - // (i.e. the G has been blocked in a syscall). - gs.syscallBegin(start, ev.Proc(), ev.Stack()) - g.inSyscall[ev.Proc()] = gs - } - // Check if we're exiting a non-blocking syscall. - _, didNotBlock := g.inSyscall[ev.Proc()] - if from == tracev2.GoSyscall && didNotBlock { - gs.syscallEnd(ev.Time(), false, ctx) - delete(g.inSyscall, ev.Proc()) - } - - // Note down the goroutine transition. - _, inMarkAssist := gs.activeRanges["GC mark assist"] - ctx.GoroutineTransition(ctx.elapsed(ev.Time()), viewerGState(from, inMarkAssist), viewerGState(to, inMarkAssist)) -} - -func (g *procGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { - st := ev.StateTransition() - proc := st.Resource.Proc() - - g.maxProc = max(g.maxProc, proc) - viewerEv := traceviewer.InstantEvent{ - Resource: uint64(proc), - Stack: ctx.Stack(viewerFrames(ev.Stack())), - } - - from, to := st.Proc() - if from == to { - // Filter out no-op events. - return - } - if to.Executing() { - start := ev.Time() - if from == tracev2.ProcUndetermined { - start = ctx.startTime - } - viewerEv.Name = "proc start" - viewerEv.Arg = format.ThreadIDArg{ThreadID: uint64(ev.Thread())} - viewerEv.Ts = ctx.elapsed(start) - ctx.IncThreadStateCount(ctx.elapsed(start), traceviewer.ThreadStateRunning, 1) - } - if from.Executing() { - start := ev.Time() - viewerEv.Name = "proc stop" - viewerEv.Ts = ctx.elapsed(start) - ctx.IncThreadStateCount(ctx.elapsed(start), traceviewer.ThreadStateRunning, -1) - - // Check if this proc was in a syscall before it stopped. - // This means the syscall blocked. We need to emit it to the - // viewer at this point because we only display the time the - // syscall occupied a P when the viewer is in per-P mode. - // - // TODO(mknyszek): We could do better in a per-M mode because - // all events have to happen on *some* thread, and in v2 traces - // we know what that thread is. - gs, ok := g.inSyscall[proc] - if ok { - // Emit syscall slice for blocked syscall. - gs.syscallEnd(start, true, ctx) - gs.stop(start, ev.Stack(), ctx) - delete(g.inSyscall, proc) - } - } - // TODO(mknyszek): Consider modeling procs differently and have them be - // transition to and from NotExist when GOMAXPROCS changes. We can emit - // events for this to clearly delineate GOMAXPROCS changes. - - if viewerEv.Name != "" { - ctx.Instant(viewerEv) - } -} - -func (g *procGenerator) Finish(ctx *traceContext) { - ctx.SetResourceType("PROCS") - - // Finish off ranges first. It doesn't really matter for the global ranges, - // but the proc ranges need to either be a subset of a goroutine slice or - // their own slice entirely. If the former, it needs to end first. - g.procRangeGenerator.Finish(ctx) - g.globalRangeGenerator.Finish(ctx) - - // Finish off all the goroutine slices. - for _, gs := range g.gStates { - gs.finish(ctx) - } - - // Name all the procs to the emitter. - for i := uint64(0); i <= uint64(g.maxProc); i++ { - ctx.Resource(i, fmt.Sprintf("Proc %v", i)) - } -} diff --git a/src/cmd/trace/v2/regions.go b/src/cmd/trace/v2/regions.go deleted file mode 100644 index 01233284ea..0000000000 --- a/src/cmd/trace/v2/regions.go +++ /dev/null @@ -1,529 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - "cmp" - "fmt" - "html/template" - "internal/trace" - "internal/trace/traceviewer" - tracev2 "internal/trace/v2" - "net/http" - "net/url" - "slices" - "sort" - "strconv" - "strings" - "time" -) - -// UserRegionsHandlerFunc returns a HandlerFunc that reports all regions found in the trace. -func UserRegionsHandlerFunc(t *parsedTrace) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - // Summarize all the regions. - summary := make(map[regionFingerprint]regionStats) - for _, g := range t.summary.Goroutines { - for _, r := range g.Regions { - id := fingerprintRegion(r) - stats, ok := summary[id] - if !ok { - stats.regionFingerprint = id - } - stats.add(t, r) - summary[id] = stats - } - } - // Sort regions by PC and name. - userRegions := make([]regionStats, 0, len(summary)) - for _, stats := range summary { - userRegions = append(userRegions, stats) - } - slices.SortFunc(userRegions, func(a, b regionStats) int { - if c := cmp.Compare(a.Type, b.Type); c != 0 { - return c - } - return cmp.Compare(a.Frame.PC, b.Frame.PC) - }) - // Emit table. - err := templUserRegionTypes.Execute(w, userRegions) - if err != nil { - http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) - return - } - } -} - -// regionFingerprint is a way to categorize regions that goes just one step beyond the region's Type -// by including the top stack frame. -type regionFingerprint struct { - Frame tracev2.StackFrame - Type string -} - -func fingerprintRegion(r *trace.UserRegionSummary) regionFingerprint { - return regionFingerprint{ - Frame: regionTopStackFrame(r), - Type: r.Name, - } -} - -func regionTopStackFrame(r *trace.UserRegionSummary) tracev2.StackFrame { - var frame tracev2.StackFrame - if r.Start != nil && r.Start.Stack() != tracev2.NoStack { - r.Start.Stack().Frames(func(f tracev2.StackFrame) bool { - frame = f - return false - }) - } - return frame -} - -type regionStats struct { - regionFingerprint - Histogram traceviewer.TimeHistogram -} - -func (s *regionStats) UserRegionURL() func(min, max time.Duration) string { - return func(min, max time.Duration) string { - return fmt.Sprintf("/userregion?type=%s&pc=%x&latmin=%v&latmax=%v", template.URLQueryEscaper(s.Type), s.Frame.PC, template.URLQueryEscaper(min), template.URLQueryEscaper(max)) - } -} - -func (s *regionStats) add(t *parsedTrace, region *trace.UserRegionSummary) { - s.Histogram.Add(regionInterval(t, region).duration()) -} - -var templUserRegionTypes = template.Must(template.New("").Parse(` - -Regions - - -

Regions

- -Below is a table containing a summary of all the user-defined regions in the trace. -Regions are grouped by the region type and the point at which the region started. -The rightmost column of the table contains a latency histogram for each region group. -Note that this histogram only counts regions that began and ended within the traced -period. -However, the "Count" column includes all regions, including those that only started -or ended during the traced period. -Regions that were active through the trace period were not recorded, and so are not -accounted for at all. -Click on the links to explore a breakdown of time spent for each region by goroutine -and user-defined task. -
-
- - - - - - - -{{range $}} - - - - - -{{end}} -
Region typeCountDuration distribution (complete tasks)
{{printf "%q" .Type}}
{{.Frame.Func}} @ {{printf "0x%x" .Frame.PC}}
{{.Frame.File}}:{{.Frame.Line}}
{{.Histogram.Count}}{{.Histogram.ToHTML (.UserRegionURL)}}
- - -`)) - -// UserRegionHandlerFunc returns a HandlerFunc that presents the details of the selected regions. -func UserRegionHandlerFunc(t *parsedTrace) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - // Construct the filter from the request. - filter, err := newRegionFilter(r) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - // Collect all the regions with their goroutines. - type region struct { - *trace.UserRegionSummary - Goroutine tracev2.GoID - NonOverlappingStats map[string]time.Duration - HasRangeTime bool - } - var regions []region - var maxTotal time.Duration - validNonOverlappingStats := make(map[string]struct{}) - validRangeStats := make(map[string]struct{}) - for _, g := range t.summary.Goroutines { - for _, r := range g.Regions { - if !filter.match(t, r) { - continue - } - nonOverlappingStats := r.NonOverlappingStats() - for name := range nonOverlappingStats { - validNonOverlappingStats[name] = struct{}{} - } - var totalRangeTime time.Duration - for name, dt := range r.RangeTime { - validRangeStats[name] = struct{}{} - totalRangeTime += dt - } - regions = append(regions, region{ - UserRegionSummary: r, - Goroutine: g.ID, - NonOverlappingStats: nonOverlappingStats, - HasRangeTime: totalRangeTime != 0, - }) - if maxTotal < r.TotalTime { - maxTotal = r.TotalTime - } - } - } - - // Sort. - sortBy := r.FormValue("sortby") - if _, ok := validNonOverlappingStats[sortBy]; ok { - slices.SortFunc(regions, func(a, b region) int { - return cmp.Compare(b.NonOverlappingStats[sortBy], a.NonOverlappingStats[sortBy]) - }) - } else { - // Sort by total time by default. - slices.SortFunc(regions, func(a, b region) int { - return cmp.Compare(b.TotalTime, a.TotalTime) - }) - } - - // Write down all the non-overlapping stats and sort them. - allNonOverlappingStats := make([]string, 0, len(validNonOverlappingStats)) - for name := range validNonOverlappingStats { - allNonOverlappingStats = append(allNonOverlappingStats, name) - } - slices.SortFunc(allNonOverlappingStats, func(a, b string) int { - if a == b { - return 0 - } - if a == "Execution time" { - return -1 - } - if b == "Execution time" { - return 1 - } - return cmp.Compare(a, b) - }) - - // Write down all the range stats and sort them. - allRangeStats := make([]string, 0, len(validRangeStats)) - for name := range validRangeStats { - allRangeStats = append(allRangeStats, name) - } - sort.Strings(allRangeStats) - - err = templUserRegionType.Execute(w, struct { - MaxTotal time.Duration - Regions []region - Name string - Filter *regionFilter - NonOverlappingStats []string - RangeStats []string - }{ - MaxTotal: maxTotal, - Regions: regions, - Name: filter.name, - Filter: filter, - NonOverlappingStats: allNonOverlappingStats, - RangeStats: allRangeStats, - }) - if err != nil { - http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) - return - } - } -} - -var templUserRegionType = template.Must(template.New("").Funcs(template.FuncMap{ - "headerStyle": func(statName string) template.HTMLAttr { - return template.HTMLAttr(fmt.Sprintf("style=\"background-color: %s;\"", stat2Color(statName))) - }, - "barStyle": func(statName string, dividend, divisor time.Duration) template.HTMLAttr { - width := "0" - if divisor != 0 { - width = fmt.Sprintf("%.2f%%", float64(dividend)/float64(divisor)*100) - } - return template.HTMLAttr(fmt.Sprintf("style=\"width: %s; background-color: %s;\"", width, stat2Color(statName))) - }, - "filterParams": func(f *regionFilter) template.URL { - return template.URL(f.params.Encode()) - }, -}).Parse(` - -Regions: {{.Name}} - - - - -

Regions: {{.Name}}

- -Table of contents - - -

Summary

- -{{ with $p := filterParams .Filter}} - - - - - - - - - - - - - - - - - -
Network wait profile: graph (download)
Sync block profile: graph (download)
Syscall profile: graph (download)
Scheduler wait profile: graph (download)
-{{ end }} - -

Breakdown

- -The table below breaks down where each goroutine is spent its time during the -traced period. -All of the columns except total time are non-overlapping. -
-
- - - - - - - -{{range $.NonOverlappingStats}} - -{{end}} - -{{range .Regions}} - - - - - - {{$Region := .}} - {{range $.NonOverlappingStats}} - {{$Time := index $Region.NonOverlappingStats .}} - - {{end}} - -{{end}} -
Goroutine Task Total {{.}}
{{.Goroutine}} {{if .TaskID}}{{.TaskID}}{{end}} {{ .TotalTime.String }} -
- {{$Region := .}} - {{range $.NonOverlappingStats}} - {{$Time := index $Region.NonOverlappingStats .}} - {{if $Time}} -   - {{end}} - {{end}} -
-
{{$Time.String}}
- -

Special ranges

- -The table below describes how much of the traced period each goroutine spent in -certain special time ranges. -If a goroutine has spent no time in any special time ranges, it is excluded from -the table. -For example, how much time it spent helping the GC. Note that these times do -overlap with the times from the first table. -In general the goroutine may not be executing in these special time ranges. -For example, it may have blocked while trying to help the GC. -This must be taken into account when interpreting the data. -
-
- - - - - - -{{range $.RangeStats}} - -{{end}} - -{{range .Regions}} - {{if .HasRangeTime}} - - - - - {{$Region := .}} - {{range $.RangeStats}} - {{$Time := index $Region.RangeTime .}} - - {{end}} - - {{end}} -{{end}} -
Goroutine Task Total {{.}}
{{.Goroutine}} {{if .TaskID}}{{.TaskID}}{{end}} {{ .TotalTime.String }} {{$Time.String}}
-`)) - -// regionFilter represents a region filter specified by a user of cmd/trace. -type regionFilter struct { - name string - params url.Values - cond []func(*parsedTrace, *trace.UserRegionSummary) bool -} - -// match returns true if a region, described by its ID and summary, matches -// the filter. -func (f *regionFilter) match(t *parsedTrace, s *trace.UserRegionSummary) bool { - for _, c := range f.cond { - if !c(t, s) { - return false - } - } - return true -} - -// newRegionFilter creates a new region filter from URL query variables. -func newRegionFilter(r *http.Request) (*regionFilter, error) { - if err := r.ParseForm(); err != nil { - return nil, err - } - - var name []string - var conditions []func(*parsedTrace, *trace.UserRegionSummary) bool - filterParams := make(url.Values) - - param := r.Form - if typ, ok := param["type"]; ok && len(typ) > 0 { - name = append(name, fmt.Sprintf("%q", typ[0])) - conditions = append(conditions, func(_ *parsedTrace, r *trace.UserRegionSummary) bool { - return r.Name == typ[0] - }) - filterParams.Add("type", typ[0]) - } - if pc, err := strconv.ParseUint(r.FormValue("pc"), 16, 64); err == nil { - encPC := fmt.Sprintf("0x%x", pc) - name = append(name, "@ "+encPC) - conditions = append(conditions, func(_ *parsedTrace, r *trace.UserRegionSummary) bool { - return regionTopStackFrame(r).PC == pc - }) - filterParams.Add("pc", encPC) - } - - if lat, err := time.ParseDuration(r.FormValue("latmin")); err == nil { - name = append(name, fmt.Sprintf("(latency >= %s)", lat)) - conditions = append(conditions, func(t *parsedTrace, r *trace.UserRegionSummary) bool { - return regionInterval(t, r).duration() >= lat - }) - filterParams.Add("latmin", lat.String()) - } - if lat, err := time.ParseDuration(r.FormValue("latmax")); err == nil { - name = append(name, fmt.Sprintf("(latency <= %s)", lat)) - conditions = append(conditions, func(t *parsedTrace, r *trace.UserRegionSummary) bool { - return regionInterval(t, r).duration() <= lat - }) - filterParams.Add("latmax", lat.String()) - } - - return ®ionFilter{ - name: strings.Join(name, " "), - cond: conditions, - params: filterParams, - }, nil -} - -func regionInterval(t *parsedTrace, s *trace.UserRegionSummary) interval { - var i interval - if s.Start != nil { - i.start = s.Start.Time() - } else { - i.start = t.startTime() - } - if s.End != nil { - i.end = s.End.Time() - } else { - i.end = t.endTime() - } - return i -} diff --git a/src/cmd/trace/v2/tasks.go b/src/cmd/trace/v2/tasks.go deleted file mode 100644 index fb40811565..0000000000 --- a/src/cmd/trace/v2/tasks.go +++ /dev/null @@ -1,477 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - "bytes" - "cmp" - "fmt" - "html/template" - "internal/trace" - "internal/trace/traceviewer" - tracev2 "internal/trace/v2" - "log" - "net/http" - "slices" - "strings" - "time" -) - -// UserTasksHandlerFunc returns a HandlerFunc that reports all tasks found in the trace. -func UserTasksHandlerFunc(t *parsedTrace) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - tasks := t.summary.Tasks - - // Summarize groups of tasks with the same name. - summary := make(map[string]taskStats) - for _, task := range tasks { - stats, ok := summary[task.Name] - if !ok { - stats.Type = task.Name - } - stats.add(task) - summary[task.Name] = stats - } - - // Sort tasks by type. - userTasks := make([]taskStats, 0, len(summary)) - for _, stats := range summary { - userTasks = append(userTasks, stats) - } - slices.SortFunc(userTasks, func(a, b taskStats) int { - return cmp.Compare(a.Type, b.Type) - }) - - // Emit table. - err := templUserTaskTypes.Execute(w, userTasks) - if err != nil { - http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) - return - } - } -} - -type taskStats struct { - Type string - Count int // Complete + incomplete tasks - Histogram traceviewer.TimeHistogram // Complete tasks only -} - -func (s *taskStats) UserTaskURL(complete bool) func(min, max time.Duration) string { - return func(min, max time.Duration) string { - return fmt.Sprintf("/usertask?type=%s&complete=%v&latmin=%v&latmax=%v", template.URLQueryEscaper(s.Type), template.URLQueryEscaper(complete), template.URLQueryEscaper(min), template.URLQueryEscaper(max)) - } -} - -func (s *taskStats) add(task *trace.UserTaskSummary) { - s.Count++ - if task.Complete() { - s.Histogram.Add(task.End.Time().Sub(task.Start.Time())) - } -} - -var templUserTaskTypes = template.Must(template.New("").Parse(` - -Tasks - - -Search log text:

- - - - - - -{{range $}} - - - - - -{{end}} -
Task typeCountDuration distribution (complete tasks)
{{.Type}}{{.Count}}{{.Histogram.ToHTML (.UserTaskURL true)}}
- - -`)) - -// UserTaskHandlerFunc returns a HandlerFunc that presents the details of the selected tasks. -func UserTaskHandlerFunc(t *parsedTrace) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - filter, err := newTaskFilter(r) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - type event struct { - WhenString string - Elapsed time.Duration - Goroutine tracev2.GoID - What string - // TODO: include stack trace of creation time - } - type task struct { - WhenString string - ID tracev2.TaskID - Duration time.Duration - Complete bool - Events []event - Start, End time.Duration // Time since the beginning of the trace - GCTime time.Duration - } - var tasks []task - for _, summary := range t.summary.Tasks { - if !filter.match(t, summary) { - continue - } - - // Collect all the events for the task. - var rawEvents []*tracev2.Event - if summary.Start != nil { - rawEvents = append(rawEvents, summary.Start) - } - if summary.End != nil { - rawEvents = append(rawEvents, summary.End) - } - rawEvents = append(rawEvents, summary.Logs...) - for _, r := range summary.Regions { - if r.Start != nil { - rawEvents = append(rawEvents, r.Start) - } - if r.End != nil { - rawEvents = append(rawEvents, r.End) - } - } - - // Sort them. - slices.SortStableFunc(rawEvents, func(a, b *tracev2.Event) int { - return cmp.Compare(a.Time(), b.Time()) - }) - - // Summarize them. - var events []event - last := t.startTime() - for _, ev := range rawEvents { - what := describeEvent(ev) - if what == "" { - continue - } - sinceStart := ev.Time().Sub(t.startTime()) - events = append(events, event{ - WhenString: fmt.Sprintf("%2.9f", sinceStart.Seconds()), - Elapsed: ev.Time().Sub(last), - What: what, - Goroutine: primaryGoroutine(ev), - }) - last = ev.Time() - } - taskSpan := taskInterval(t, summary) - taskStart := taskSpan.start.Sub(t.startTime()) - - // Produce the task summary. - tasks = append(tasks, task{ - WhenString: fmt.Sprintf("%2.9fs", taskStart.Seconds()), - Duration: taskSpan.duration(), - ID: summary.ID, - Complete: summary.Complete(), - Events: events, - Start: taskStart, - End: taskStart + taskSpan.duration(), - }) - } - // Sort the tasks by duration. - slices.SortFunc(tasks, func(a, b task) int { - return cmp.Compare(a.Duration, b.Duration) - }) - - // Emit table. - err = templUserTaskType.Execute(w, struct { - Name string - Tasks []task - }{ - Name: filter.name, - Tasks: tasks, - }) - if err != nil { - log.Printf("failed to execute template: %v", err) - http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError) - return - } - } -} - -var templUserTaskType = template.Must(template.New("userTask").Funcs(template.FuncMap{ - "elapsed": elapsed, - "asMillisecond": asMillisecond, - "trimSpace": strings.TrimSpace, -}).Parse(` - -Tasks: {{.Name}} - - - -

User Task: {{.Name}}

- -Search log text:
- -

- - - - - - - - - {{range $el := $.Tasks}} - - - - - - - {{range $el.Events}} - - - - - - - {{end}} - {{end}} - - -`)) - -// taskFilter represents a task filter specified by a user of cmd/trace. -type taskFilter struct { - name string - cond []func(*parsedTrace, *trace.UserTaskSummary) bool -} - -// match returns true if a task, described by its ID and summary, matches -// the filter. -func (f *taskFilter) match(t *parsedTrace, task *trace.UserTaskSummary) bool { - if t == nil { - return false - } - for _, c := range f.cond { - if !c(t, task) { - return false - } - } - return true -} - -// newTaskFilter creates a new task filter from URL query variables. -func newTaskFilter(r *http.Request) (*taskFilter, error) { - if err := r.ParseForm(); err != nil { - return nil, err - } - - var name []string - var conditions []func(*parsedTrace, *trace.UserTaskSummary) bool - - param := r.Form - if typ, ok := param["type"]; ok && len(typ) > 0 { - name = append(name, fmt.Sprintf("%q", typ[0])) - conditions = append(conditions, func(_ *parsedTrace, task *trace.UserTaskSummary) bool { - return task.Name == typ[0] - }) - } - if complete := r.FormValue("complete"); complete == "1" { - name = append(name, "complete") - conditions = append(conditions, func(_ *parsedTrace, task *trace.UserTaskSummary) bool { - return task.Complete() - }) - } else if complete == "0" { - name = append(name, "incomplete") - conditions = append(conditions, func(_ *parsedTrace, task *trace.UserTaskSummary) bool { - return !task.Complete() - }) - } - if lat, err := time.ParseDuration(r.FormValue("latmin")); err == nil { - name = append(name, fmt.Sprintf("latency >= %s", lat)) - conditions = append(conditions, func(t *parsedTrace, task *trace.UserTaskSummary) bool { - return task.Complete() && taskInterval(t, task).duration() >= lat - }) - } - if lat, err := time.ParseDuration(r.FormValue("latmax")); err == nil { - name = append(name, fmt.Sprintf("latency <= %s", lat)) - conditions = append(conditions, func(t *parsedTrace, task *trace.UserTaskSummary) bool { - return task.Complete() && taskInterval(t, task).duration() <= lat - }) - } - if text := r.FormValue("logtext"); text != "" { - name = append(name, fmt.Sprintf("log contains %q", text)) - conditions = append(conditions, func(_ *parsedTrace, task *trace.UserTaskSummary) bool { - return taskMatches(task, text) - }) - } - - return &taskFilter{name: strings.Join(name, ","), cond: conditions}, nil -} - -func taskInterval(t *parsedTrace, s *trace.UserTaskSummary) interval { - var i interval - if s.Start != nil { - i.start = s.Start.Time() - } else { - i.start = t.startTime() - } - if s.End != nil { - i.end = s.End.Time() - } else { - i.end = t.endTime() - } - return i -} - -func taskMatches(t *trace.UserTaskSummary, text string) bool { - matches := func(s string) bool { - return strings.Contains(s, text) - } - if matches(t.Name) { - return true - } - for _, r := range t.Regions { - if matches(r.Name) { - return true - } - } - for _, ev := range t.Logs { - log := ev.Log() - if matches(log.Category) { - return true - } - if matches(log.Message) { - return true - } - } - return false -} - -func describeEvent(ev *tracev2.Event) string { - switch ev.Kind() { - case tracev2.EventStateTransition: - st := ev.StateTransition() - if st.Resource.Kind != tracev2.ResourceGoroutine { - return "" - } - old, new := st.Goroutine() - return fmt.Sprintf("%s -> %s", old, new) - case tracev2.EventRegionBegin: - return fmt.Sprintf("region %q begin", ev.Region().Type) - case tracev2.EventRegionEnd: - return fmt.Sprintf("region %q end", ev.Region().Type) - case tracev2.EventTaskBegin: - t := ev.Task() - return fmt.Sprintf("task %q (D %d, parent %d) begin", t.Type, t.ID, t.Parent) - case tracev2.EventTaskEnd: - return "task end" - case tracev2.EventLog: - log := ev.Log() - if log.Category != "" { - return fmt.Sprintf("log %q", log.Message) - } - return fmt.Sprintf("log (category: %s): %q", log.Category, log.Message) - } - return "" -} - -func primaryGoroutine(ev *tracev2.Event) tracev2.GoID { - if ev.Kind() != tracev2.EventStateTransition { - return ev.Goroutine() - } - st := ev.StateTransition() - if st.Resource.Kind != tracev2.ResourceGoroutine { - return tracev2.NoGoroutine - } - return st.Resource.Goroutine() -} - -func elapsed(d time.Duration) string { - b := fmt.Appendf(nil, "%.9f", d.Seconds()) - - // For subsecond durations, blank all zeros before decimal point, - // and all zeros between the decimal point and the first non-zero digit. - if d < time.Second { - dot := bytes.IndexByte(b, '.') - for i := 0; i < dot; i++ { - b[i] = ' ' - } - for i := dot + 1; i < len(b); i++ { - if b[i] == '0' { - b[i] = ' ' - } else { - break - } - } - } - return string(b) -} - -func asMillisecond(d time.Duration) float64 { - return float64(d.Nanoseconds()) / float64(time.Millisecond) -} diff --git a/src/cmd/trace/v2/testdata/generate.go b/src/cmd/trace/v2/testdata/generate.go deleted file mode 100644 index c0658b2329..0000000000 --- a/src/cmd/trace/v2/testdata/generate.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:generate go run mktests.go -package testdata diff --git a/src/cmd/trace/v2/testdata/go122.test b/src/cmd/trace/v2/testdata/go122.test deleted file mode 100644 index 2ec9e88f4f..0000000000 --- a/src/cmd/trace/v2/testdata/go122.test +++ /dev/null @@ -1,4639 +0,0 @@ -Trace Go1.22 -EventBatch gen=1 m=18446744073709551615 time=7689672466239 size=5 -Frequency freq=15625000 -EventBatch gen=1 m=1709048 time=7689670869319 size=423 -ProcStart dt=409 p=7 p_seq=1 -GoStart dt=31 g=34 g_seq=1 -GoStop dt=291990 reason_string=16 stack=50 -GoStart dt=21 g=34 g_seq=2 -GoStop dt=315853 reason_string=16 stack=50 -GoStart dt=30 g=34 g_seq=3 -GoUnblock dt=173432 g=1 g_seq=73 stack=52 -GoDestroy dt=96 -GoStart dt=22 g=1 g_seq=74 -HeapAlloc dt=79 heapalloc_value=26397576 -HeapAlloc dt=51 heapalloc_value=26405640 -GoCreate dt=62 new_g=50 new_stack=53 stack=54 -GoBlock dt=23 reason_string=12 stack=55 -GoStart dt=7 g=50 g_seq=1 -HeapAlloc dt=301 heapalloc_value=26413776 -HeapAlloc dt=30 heapalloc_value=26421680 -GoSyscallBegin dt=35 p_seq=2 stack=56 -GoSyscallEnd dt=39 -GoSyscallBegin dt=13 p_seq=3 stack=57 -GoSyscallEnd dt=16 -GoSyscallBegin dt=396 p_seq=4 stack=58 -GoSyscallEnd dt=16 -GoSyscallBegin dt=15 p_seq=5 stack=59 -GoSyscallEnd dt=14 -HeapAlloc dt=305 heapalloc_value=26429872 -HeapAlloc dt=34 heapalloc_value=26437248 -HeapAlloc dt=42 heapalloc_value=26445120 -GoSyscallBegin dt=42 p_seq=6 stack=60 -GoSyscallEnd dt=18 -GoSyscallBegin dt=10 p_seq=7 stack=61 -GoSyscallEnd dt=14 -GoSyscallBegin dt=23 p_seq=8 stack=62 -ProcStart dt=787251 p=7 p_seq=15 -GoSyscallEndBlocked dt=7 -GoStart dt=1 g=50 g_seq=2 -GoUnblock dt=48 g=1 g_seq=75 stack=65 -GoDestroy dt=143 -GoStart dt=30 g=1 g_seq=76 -HeapAlloc dt=621 heapalloc_value=26468232 -GoStop dt=656 reason_string=16 stack=66 -GoStart dt=103 g=1 g_seq=77 -HeapAlloc dt=42 heapalloc_value=26476424 -HeapAlloc dt=87 heapalloc_value=26484360 -GoSyscallBegin dt=18 p_seq=16 stack=67 -GoSyscallEnd dt=456 -GoSyscallBegin dt=41 p_seq=17 stack=68 -GoSyscallEnd dt=25 -GoSyscallBegin dt=16 p_seq=18 stack=69 -GoSyscallEnd dt=18 -HeapAlloc dt=193 heapalloc_value=26549896 -GoSyscallBegin dt=69 p_seq=19 stack=70 -GoSyscallEnd dt=227 -GoSyscallBegin dt=12 p_seq=20 stack=70 -GoSyscallEnd dt=105 -GoSyscallBegin dt=87 p_seq=21 stack=71 -GoSyscallEnd dt=48 -GoSyscallBegin dt=37 p_seq=22 stack=72 -GoSyscallEnd dt=51 -GoSyscallBegin dt=49 p_seq=23 stack=73 -GoSyscallEnd dt=158 -GoSyscallBegin dt=12 p_seq=24 stack=74 -GoSyscallEnd dt=67 -HeapAlloc dt=126 heapalloc_value=26558088 -HeapAlloc dt=30 heapalloc_value=26566160 -GoCreate dt=34 new_g=52 new_stack=75 stack=76 -HeapAlloc dt=205 heapalloc_value=26573872 -GoSyscallBegin dt=890 p_seq=25 stack=77 -GoSyscallEnd dt=1128 -GoBlock dt=96 reason_string=7 stack=80 -ProcStop dt=29 -ProcStart dt=384 p=6 p_seq=7 -GoStart dt=14 g=52 g_seq=4 -GoSyscallBegin dt=16 p_seq=8 stack=78 -ProcStart dt=160 p=5 p_seq=13 -GoSyscallEndBlocked dt=3 -GoStart dt=1 g=52 g_seq=5 -HeapAlloc dt=297 heapalloc_value=26581840 -HeapAlloc dt=31 heapalloc_value=26590032 -HeapAlloc dt=164 heapalloc_value=26598224 -GoSyscallBegin dt=34 p_seq=14 stack=88 -GoSyscallEnd dt=33 -GoSyscallBegin dt=14 p_seq=15 stack=89 -GoSyscallEnd dt=36 -GoSyscallBegin dt=12 p_seq=16 stack=90 -GoSyscallEnd dt=22 -GoSyscallBegin dt=15 p_seq=17 stack=91 -GoSyscallEnd dt=28 -HeapAlloc dt=18 heapalloc_value=26606416 -HeapAlloc dt=20 heapalloc_value=26614608 -GoBlock dt=16 reason_string=19 stack=92 -ProcStop dt=136 -ProcStart dt=17788 p=6 p_seq=12 -GoUnblock dt=41 g=1 g_seq=80 stack=0 -GoStart dt=136 g=1 g_seq=81 -GoSyscallBegin dt=14 p_seq=13 stack=86 -GoSyscallEnd dt=65 -GoSyscallBegin dt=72 p_seq=14 stack=95 -GoSyscallEnd dt=534 -HeapAlloc dt=284 heapalloc_value=26630992 -HeapAlloc dt=38 heapalloc_value=26639120 -EventBatch gen=1 m=1709047 time=7689670866279 size=202 -ProcStart dt=437 p=6 p_seq=2 -HeapAlloc dt=131 heapalloc_value=26373928 -HeapAlloc dt=368 heapalloc_value=26382120 -HeapAlloc dt=55 heapalloc_value=26390056 -GoStart dt=1030 g=36 g_seq=1 -GoStop dt=293329 reason_string=16 stack=50 -GoStart dt=25 g=36 g_seq=2 -GoStop dt=315834 reason_string=16 stack=50 -GoStart dt=24 g=36 g_seq=3 -GoDestroy dt=172079 -ProcStop dt=60 -ProcStart dt=1749 p=6 p_seq=3 -ProcStop dt=1621 -ProcStart dt=64901 p=5 p_seq=4 -ProcStop dt=24 -ProcStart dt=722061 p=5 p_seq=5 -ProcStop dt=31 -ProcStart dt=2847 p=5 p_seq=8 -ProcStop dt=20 -ProcStart dt=3166 p=7 p_seq=26 -GoUnblock dt=6 g=52 g_seq=3 stack=0 -GoUnblock dt=90 g=1 g_seq=78 stack=0 -GoStart dt=5 g=1 g_seq=79 -GoSyscallBegin dt=31 p_seq=27 stack=81 -GoSyscallEnd dt=35 -GoSyscallBegin dt=134 p_seq=28 stack=82 -GoSyscallEnd dt=29 -GoSyscallBegin dt=17 p_seq=29 stack=83 -GoSyscallEnd dt=30 -GoSyscallBegin dt=8 p_seq=30 stack=84 -GoSyscallEnd dt=19 -GoSyscallBegin dt=11 p_seq=31 stack=85 -GoSyscallEnd dt=24 -GoSyscallBegin dt=65 p_seq=32 stack=86 -GoSyscallEnd dt=57 -GoBlock dt=19 reason_string=7 stack=87 -ProcStop dt=38 -ProcStart dt=458 p=6 p_seq=11 -ProcStop dt=30 -ProcStart dt=377 p=5 p_seq=18 -ProcStop dt=23 -ProcStart dt=17141 p=5 p_seq=19 -GoUnblock dt=19 g=52 g_seq=6 stack=0 -GoStart dt=111 g=52 g_seq=7 -HeapAlloc dt=38 heapalloc_value=26622800 -GoSyscallBegin dt=36 p_seq=20 stack=93 -GoSyscallEnd dt=554 -GoSyscallBegin dt=83 p_seq=21 stack=94 -GoSyscallEnd dt=196 -GoDestroy dt=15 -ProcStop dt=37 -EventBatch gen=1 m=1709046 time=7689670697530 size=167 -ProcStart dt=236 p=5 p_seq=1 -ProcStop dt=281 -ProcStart dt=1683 p=2 p_seq=14 -ProcStop dt=33 -ProcStart dt=147800 p=2 p_seq=16 -ProcStop dt=29 -ProcStart dt=3880 p=1 p_seq=28 -ProcStop dt=30 -ProcStart dt=801175 p=5 p_seq=3 -ProcStop dt=19 -ProcStart dt=47961 p=6 p_seq=4 -ProcStop dt=15 -ProcStart dt=16716 p=6 p_seq=5 -GoUnblock dt=60 g=6 g_seq=2 stack=0 -GoStart dt=90 g=6 g_seq=3 -HeapAlloc dt=193 heapalloc_value=26453304 -GoBlock dt=29 reason_string=12 stack=15 -ProcStop dt=12 -ProcStart dt=704555 p=7 p_seq=10 -ProcStop dt=25 -ProcStart dt=16755 p=7 p_seq=11 -HeapAlloc dt=61 heapalloc_value=26461496 -GoCreate dt=72 new_g=51 new_stack=63 stack=0 -GoStart dt=98 g=51 g_seq=1 -GoSyscallBegin dt=45 p_seq=12 stack=64 -ProcStart dt=206 p=7 p_seq=14 -GoSyscallEndBlocked dt=3 -GoStart dt=1 g=51 g_seq=2 -GoDestroy dt=12 -ProcStop dt=18 -ProcStart dt=849 p=5 p_seq=6 -ProcStop dt=16 -ProcStart dt=1359 p=5 p_seq=7 -ProcStop dt=12 -ProcStart dt=2079 p=5 p_seq=9 -GoStart dt=1134 g=52 g_seq=1 -GoSyscallBegin dt=39 p_seq=10 stack=78 -ProcStart dt=232 p=5 p_seq=12 -GoSyscallEndBlocked dt=2 -GoStart dt=1 g=52 g_seq=2 -GoBlock dt=27 reason_string=7 stack=79 -ProcStop dt=20 -EventBatch gen=1 m=1709045 time=7689670544102 size=3297 -ProcStart dt=84 p=4 p_seq=5 -GoUnblock dt=91 g=1 g_seq=34 stack=0 -GoStart dt=157 g=1 g_seq=35 -HeapAlloc dt=117 heapalloc_value=8105520 -HeapAlloc dt=67 heapalloc_value=8113712 -HeapAlloc dt=36 heapalloc_value=8121904 -HeapAlloc dt=25 heapalloc_value=8130096 -HeapAlloc dt=25 heapalloc_value=8138288 -HeapAlloc dt=25 heapalloc_value=8146480 -HeapAlloc dt=21 heapalloc_value=8154672 -HeapAlloc dt=26 heapalloc_value=8162864 -HeapAlloc dt=18 heapalloc_value=8171056 -HeapAlloc dt=24 heapalloc_value=8179248 -HeapAlloc dt=15 heapalloc_value=8187440 -HeapAlloc dt=133 heapalloc_value=8195632 -HeapAlloc dt=105 heapalloc_value=8203824 -HeapAlloc dt=20 heapalloc_value=8212016 -HeapAlloc dt=18 heapalloc_value=8220208 -HeapAlloc dt=8 heapalloc_value=8228400 -HeapAlloc dt=8 heapalloc_value=8236592 -HeapAlloc dt=9 heapalloc_value=8244784 -GCMarkAssistBegin dt=27 stack=31 -HeapAlloc dt=69 heapalloc_value=8252784 -GoBlock dt=31 reason_string=10 stack=36 -ProcStop dt=156 -ProcStart dt=993 p=0 p_seq=11 -GoStart dt=192 g=1 g_seq=37 -GCMarkAssistEnd dt=12 -HeapAlloc dt=35 heapalloc_value=8746312 -GCSweepBegin dt=26 stack=42 -GCSweepEnd dt=777 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=22 heapalloc_value=8754504 -GCSweepBegin dt=47 stack=42 -GCSweepEnd dt=662 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=11 heapalloc_value=8762696 -GCSweepBegin dt=25 stack=42 -GCSweepEnd dt=712 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=39 heapalloc_value=8770888 -GCSweepBegin dt=27 stack=42 -GCSweepEnd dt=630 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=9 heapalloc_value=8779080 -GCSweepBegin dt=25 stack=42 -GCSweepEnd dt=1256 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=8 heapalloc_value=8787272 -GCSweepBegin dt=40 stack=42 -GCSweepEnd dt=529 swept_value=360448 reclaimed_value=0 -HeapAlloc dt=9 heapalloc_value=8795464 -HeapAlloc dt=24 heapalloc_value=8803656 -HeapAlloc dt=24 heapalloc_value=8811848 -HeapAlloc dt=25 heapalloc_value=8820040 -HeapAlloc dt=23 heapalloc_value=8828232 -HeapAlloc dt=18 heapalloc_value=8836424 -HeapAlloc dt=95 heapalloc_value=8844616 -HeapAlloc dt=25 heapalloc_value=8852808 -HeapAlloc dt=23 heapalloc_value=8861000 -HeapAlloc dt=19 heapalloc_value=8869192 -HeapAlloc dt=93 heapalloc_value=8877384 -HeapAlloc dt=23 heapalloc_value=8885576 -HeapAlloc dt=23 heapalloc_value=8893768 -HeapAlloc dt=23 heapalloc_value=8901960 -HeapAlloc dt=22 heapalloc_value=8910152 -HeapAlloc dt=18 heapalloc_value=8918344 -HeapAlloc dt=174 heapalloc_value=8926536 -HeapAlloc dt=31 heapalloc_value=8934728 -HeapAlloc dt=38 heapalloc_value=8942920 -HeapAlloc dt=31 heapalloc_value=8951112 -HeapAlloc dt=57 heapalloc_value=8959304 -HeapAlloc dt=58 heapalloc_value=8967496 -HeapAlloc dt=60 heapalloc_value=8975688 -HeapAlloc dt=44 heapalloc_value=8983880 -HeapAlloc dt=53 heapalloc_value=8992072 -HeapAlloc dt=57 heapalloc_value=9000264 -HeapAlloc dt=63 heapalloc_value=9008456 -HeapAlloc dt=55 heapalloc_value=9016648 -HeapAlloc dt=28 heapalloc_value=9024840 -HeapAlloc dt=12 heapalloc_value=9033032 -HeapAlloc dt=9 heapalloc_value=9041224 -HeapAlloc dt=8 heapalloc_value=9049416 -HeapAlloc dt=7 heapalloc_value=9057608 -HeapAlloc dt=8 heapalloc_value=9065800 -HeapAlloc dt=14 heapalloc_value=9073992 -HeapAlloc dt=8 heapalloc_value=9082184 -HeapAlloc dt=45 heapalloc_value=9090376 -HeapAlloc dt=10 heapalloc_value=9098568 -HeapAlloc dt=14 heapalloc_value=9106760 -HeapAlloc dt=8 heapalloc_value=9114952 -HeapAlloc dt=10 heapalloc_value=9123144 -HeapAlloc dt=15 heapalloc_value=9131336 -HeapAlloc dt=53 heapalloc_value=9139528 -HeapAlloc dt=27 heapalloc_value=9147720 -HeapAlloc dt=38 heapalloc_value=9155912 -HeapAlloc dt=33 heapalloc_value=9164104 -HeapAlloc dt=33 heapalloc_value=9172296 -HeapAlloc dt=34 heapalloc_value=9180488 -HeapAlloc dt=36 heapalloc_value=9188680 -HeapAlloc dt=39 heapalloc_value=9196872 -HeapAlloc dt=40 heapalloc_value=9205064 -HeapAlloc dt=59 heapalloc_value=9213256 -HeapAlloc dt=28 heapalloc_value=9221448 -HeapAlloc dt=22 heapalloc_value=9229640 -HeapAlloc dt=20 heapalloc_value=9237832 -HeapAlloc dt=25 heapalloc_value=9246024 -HeapAlloc dt=20 heapalloc_value=9254216 -HeapAlloc dt=16 heapalloc_value=9262408 -HeapAlloc dt=14 heapalloc_value=9270600 -HeapAlloc dt=18 heapalloc_value=9278792 -HeapAlloc dt=32 heapalloc_value=9286984 -HeapAlloc dt=21 heapalloc_value=9295176 -HeapAlloc dt=49 heapalloc_value=9303368 -HeapAlloc dt=23 heapalloc_value=9311560 -HeapAlloc dt=16 heapalloc_value=9319752 -HeapAlloc dt=15 heapalloc_value=9327944 -HeapAlloc dt=13 heapalloc_value=9336136 -HeapAlloc dt=15 heapalloc_value=9344328 -HeapAlloc dt=14 heapalloc_value=9352520 -HeapAlloc dt=16 heapalloc_value=9360712 -HeapAlloc dt=14 heapalloc_value=9368904 -HeapAlloc dt=19 heapalloc_value=9377096 -HeapAlloc dt=16 heapalloc_value=9385288 -HeapAlloc dt=15 heapalloc_value=9393480 -HeapAlloc dt=14 heapalloc_value=9401672 -HeapAlloc dt=16 heapalloc_value=9409864 -HeapAlloc dt=15 heapalloc_value=9418056 -HeapAlloc dt=15 heapalloc_value=9426248 -HeapAlloc dt=15 heapalloc_value=9434440 -HeapAlloc dt=18 heapalloc_value=9442632 -HeapAlloc dt=94 heapalloc_value=9450824 -HeapAlloc dt=17 heapalloc_value=9459016 -HeapAlloc dt=14 heapalloc_value=9467208 -HeapAlloc dt=16 heapalloc_value=9475400 -HeapAlloc dt=15 heapalloc_value=9483592 -HeapAlloc dt=15 heapalloc_value=9491784 -HeapAlloc dt=15 heapalloc_value=9499976 -HeapAlloc dt=49 heapalloc_value=9508168 -HeapAlloc dt=16 heapalloc_value=9516360 -HeapAlloc dt=14 heapalloc_value=9524552 -HeapAlloc dt=15 heapalloc_value=9532744 -HeapAlloc dt=15 heapalloc_value=9540936 -HeapAlloc dt=15 heapalloc_value=9549128 -HeapAlloc dt=17 heapalloc_value=9557320 -HeapAlloc dt=15 heapalloc_value=9565512 -HeapAlloc dt=21 heapalloc_value=9573704 -HeapAlloc dt=15 heapalloc_value=9581896 -HeapAlloc dt=16 heapalloc_value=9590088 -HeapAlloc dt=14 heapalloc_value=9598280 -HeapAlloc dt=16 heapalloc_value=9606472 -HeapAlloc dt=14 heapalloc_value=9614664 -HeapAlloc dt=16 heapalloc_value=9622856 -GoBlock dt=21 reason_string=19 stack=21 -ProcStop dt=157 -ProcStart dt=17320 p=2 p_seq=6 -ProcStop dt=15 -ProcStart dt=2411 p=0 p_seq=14 -ProcStop dt=8 -ProcStart dt=16766 p=0 p_seq=15 -GoUnblock dt=9 g=1 g_seq=40 stack=0 -GoStart dt=91 g=1 g_seq=41 -HeapAlloc dt=19 heapalloc_value=10859848 -HeapAlloc dt=9 heapalloc_value=10868040 -HeapAlloc dt=7 heapalloc_value=10876232 -HeapAlloc dt=6 heapalloc_value=10884424 -HeapAlloc dt=6 heapalloc_value=10892616 -HeapAlloc dt=6 heapalloc_value=10900808 -HeapAlloc dt=6 heapalloc_value=10909000 -HeapAlloc dt=6 heapalloc_value=10917192 -HeapAlloc dt=6 heapalloc_value=10925384 -HeapAlloc dt=6 heapalloc_value=10933576 -HeapAlloc dt=6 heapalloc_value=10941768 -HeapAlloc dt=6 heapalloc_value=10949960 -HeapAlloc dt=6 heapalloc_value=10958152 -HeapAlloc dt=5 heapalloc_value=10966344 -HeapAlloc dt=6 heapalloc_value=10974536 -HeapAlloc dt=6 heapalloc_value=10982728 -HeapAlloc dt=6 heapalloc_value=10990920 -HeapAlloc dt=6 heapalloc_value=10999112 -HeapAlloc dt=6 heapalloc_value=11007304 -HeapAlloc dt=5 heapalloc_value=11015496 -HeapAlloc dt=7 heapalloc_value=11023688 -HeapAlloc dt=6 heapalloc_value=11031880 -HeapAlloc dt=14 heapalloc_value=11040072 -HeapAlloc dt=7 heapalloc_value=11048264 -HeapAlloc dt=6 heapalloc_value=11056456 -HeapAlloc dt=6 heapalloc_value=11064648 -HeapAlloc dt=5 heapalloc_value=11072840 -HeapAlloc dt=6 heapalloc_value=11081032 -HeapAlloc dt=6 heapalloc_value=11089224 -HeapAlloc dt=6 heapalloc_value=11097416 -HeapAlloc dt=6 heapalloc_value=11105608 -HeapAlloc dt=6 heapalloc_value=11113800 -HeapAlloc dt=59 heapalloc_value=11121992 -HeapAlloc dt=9 heapalloc_value=11130184 -HeapAlloc dt=7 heapalloc_value=11138376 -HeapAlloc dt=6 heapalloc_value=11146568 -HeapAlloc dt=6 heapalloc_value=11154760 -HeapAlloc dt=5 heapalloc_value=11162952 -HeapAlloc dt=6 heapalloc_value=11171144 -HeapAlloc dt=6 heapalloc_value=11179336 -HeapAlloc dt=6 heapalloc_value=11187528 -HeapAlloc dt=5 heapalloc_value=11195720 -HeapAlloc dt=6 heapalloc_value=11203912 -HeapAlloc dt=6 heapalloc_value=11212104 -HeapAlloc dt=84 heapalloc_value=11220296 -HeapAlloc dt=7 heapalloc_value=11228488 -HeapAlloc dt=6 heapalloc_value=11236680 -HeapAlloc dt=6 heapalloc_value=11244872 -HeapAlloc dt=5 heapalloc_value=11253064 -HeapAlloc dt=6 heapalloc_value=11261256 -HeapAlloc dt=6 heapalloc_value=11269448 -HeapAlloc dt=6 heapalloc_value=11277640 -HeapAlloc dt=5 heapalloc_value=11285832 -HeapAlloc dt=6 heapalloc_value=11294024 -HeapAlloc dt=6 heapalloc_value=11302216 -HeapAlloc dt=5 heapalloc_value=11310408 -HeapAlloc dt=6 heapalloc_value=11318600 -HeapAlloc dt=38 heapalloc_value=11326792 -HeapAlloc dt=7 heapalloc_value=11334984 -HeapAlloc dt=6 heapalloc_value=11343176 -HeapAlloc dt=6 heapalloc_value=11351368 -HeapAlloc dt=5 heapalloc_value=11359560 -HeapAlloc dt=6 heapalloc_value=11367752 -HeapAlloc dt=6 heapalloc_value=11375944 -HeapAlloc dt=6 heapalloc_value=11384136 -HeapAlloc dt=6 heapalloc_value=11392328 -HeapAlloc dt=5 heapalloc_value=11400520 -HeapAlloc dt=6 heapalloc_value=11408712 -HeapAlloc dt=6 heapalloc_value=11416904 -HeapAlloc dt=5 heapalloc_value=11425096 -HeapAlloc dt=6 heapalloc_value=11433288 -HeapAlloc dt=6 heapalloc_value=11441480 -HeapAlloc dt=6 heapalloc_value=11449672 -HeapAlloc dt=5 heapalloc_value=11457864 -HeapAlloc dt=6 heapalloc_value=11466056 -HeapAlloc dt=79 heapalloc_value=11474248 -HeapAlloc dt=6 heapalloc_value=11482440 -HeapAlloc dt=5 heapalloc_value=11490632 -HeapAlloc dt=6 heapalloc_value=11498824 -HeapAlloc dt=6 heapalloc_value=11507016 -HeapAlloc dt=6 heapalloc_value=11515208 -HeapAlloc dt=5 heapalloc_value=11523400 -HeapAlloc dt=6 heapalloc_value=11531592 -HeapAlloc dt=5 heapalloc_value=11539784 -HeapAlloc dt=6 heapalloc_value=11547976 -HeapAlloc dt=6 heapalloc_value=11556168 -HeapAlloc dt=10 heapalloc_value=11564360 -HeapAlloc dt=6 heapalloc_value=11572552 -HeapAlloc dt=24 heapalloc_value=11580744 -HeapAlloc dt=7 heapalloc_value=11588936 -HeapAlloc dt=5 heapalloc_value=11597128 -HeapAlloc dt=6 heapalloc_value=11605320 -HeapAlloc dt=6 heapalloc_value=11613512 -HeapAlloc dt=6 heapalloc_value=11621704 -HeapAlloc dt=5 heapalloc_value=11629896 -HeapAlloc dt=6 heapalloc_value=11638088 -HeapAlloc dt=6 heapalloc_value=11646280 -HeapAlloc dt=5 heapalloc_value=11654472 -HeapAlloc dt=6 heapalloc_value=11662664 -HeapAlloc dt=6 heapalloc_value=11670856 -HeapAlloc dt=6 heapalloc_value=11679048 -HeapAlloc dt=5 heapalloc_value=11687240 -HeapAlloc dt=6 heapalloc_value=11695432 -HeapAlloc dt=6 heapalloc_value=11703624 -HeapAlloc dt=6 heapalloc_value=11711816 -HeapAlloc dt=5 heapalloc_value=11720008 -HeapAlloc dt=6 heapalloc_value=11728200 -HeapAlloc dt=6 heapalloc_value=11736392 -HeapAlloc dt=70 heapalloc_value=11744584 -HeapAlloc dt=8 heapalloc_value=11752776 -HeapAlloc dt=5 heapalloc_value=11760968 -HeapAlloc dt=6 heapalloc_value=11769160 -HeapAlloc dt=5 heapalloc_value=11777352 -HeapAlloc dt=6 heapalloc_value=11785544 -HeapAlloc dt=6 heapalloc_value=11793736 -HeapAlloc dt=6 heapalloc_value=11801928 -HeapAlloc dt=5 heapalloc_value=11810120 -HeapAlloc dt=6 heapalloc_value=11818312 -HeapAlloc dt=6 heapalloc_value=11826504 -HeapAlloc dt=6 heapalloc_value=11834696 -HeapAlloc dt=6 heapalloc_value=11842888 -HeapAlloc dt=5 heapalloc_value=11851080 -HeapAlloc dt=6 heapalloc_value=11859272 -HeapAlloc dt=5 heapalloc_value=11867464 -HeapAlloc dt=6 heapalloc_value=11875656 -GoBlock dt=9 reason_string=19 stack=21 -ProcStop dt=105 -ProcStart dt=17283 p=2 p_seq=8 -ProcStop dt=12 -ProcStart dt=4008 p=0 p_seq=18 -ProcStop dt=9 -ProcStart dt=16692 p=0 p_seq=19 -GoUnblock dt=9 g=1 g_seq=44 stack=0 -GoStart dt=76 g=1 g_seq=45 -HeapAlloc dt=16 heapalloc_value=13169992 -HeapAlloc dt=9 heapalloc_value=13178184 -HeapAlloc dt=7 heapalloc_value=13186376 -HeapAlloc dt=5 heapalloc_value=13194568 -HeapAlloc dt=6 heapalloc_value=13202760 -HeapAlloc dt=6 heapalloc_value=13210952 -HeapAlloc dt=5 heapalloc_value=13219144 -HeapAlloc dt=6 heapalloc_value=13227336 -HeapAlloc dt=6 heapalloc_value=13235528 -HeapAlloc dt=6 heapalloc_value=13243720 -HeapAlloc dt=6 heapalloc_value=13251912 -HeapAlloc dt=59 heapalloc_value=13260104 -HeapAlloc dt=8 heapalloc_value=13268296 -HeapAlloc dt=6 heapalloc_value=13276488 -HeapAlloc dt=5 heapalloc_value=13284680 -HeapAlloc dt=6 heapalloc_value=13292872 -HeapAlloc dt=5 heapalloc_value=13301064 -HeapAlloc dt=6 heapalloc_value=13309256 -HeapAlloc dt=5 heapalloc_value=13317448 -HeapAlloc dt=6 heapalloc_value=13325640 -HeapAlloc dt=6 heapalloc_value=13333832 -HeapAlloc dt=6 heapalloc_value=13342024 -HeapAlloc dt=5 heapalloc_value=13350216 -HeapAlloc dt=6 heapalloc_value=13358408 -HeapAlloc dt=6 heapalloc_value=13366600 -HeapAlloc dt=5 heapalloc_value=13374792 -HeapAlloc dt=6 heapalloc_value=13382984 -HeapAlloc dt=6 heapalloc_value=13391176 -HeapAlloc dt=6 heapalloc_value=13399368 -HeapAlloc dt=5 heapalloc_value=13407560 -HeapAlloc dt=8 heapalloc_value=13415752 -HeapAlloc dt=6 heapalloc_value=13423944 -HeapAlloc dt=7 heapalloc_value=13432136 -HeapAlloc dt=5 heapalloc_value=13440328 -HeapAlloc dt=6 heapalloc_value=13448520 -HeapAlloc dt=5 heapalloc_value=13456712 -HeapAlloc dt=6 heapalloc_value=13464904 -HeapAlloc dt=6 heapalloc_value=13473096 -HeapAlloc dt=6 heapalloc_value=13481288 -HeapAlloc dt=5 heapalloc_value=13489480 -HeapAlloc dt=5 heapalloc_value=13497672 -HeapAlloc dt=6 heapalloc_value=13505864 -HeapAlloc dt=5 heapalloc_value=13514056 -HeapAlloc dt=6 heapalloc_value=13522248 -HeapAlloc dt=5 heapalloc_value=13530440 -HeapAlloc dt=6 heapalloc_value=13538632 -HeapAlloc dt=5 heapalloc_value=13546824 -HeapAlloc dt=6 heapalloc_value=13555016 -HeapAlloc dt=6 heapalloc_value=13563208 -HeapAlloc dt=48 heapalloc_value=13571400 -HeapAlloc dt=7 heapalloc_value=13579592 -HeapAlloc dt=6 heapalloc_value=13587784 -HeapAlloc dt=5 heapalloc_value=13595976 -HeapAlloc dt=6 heapalloc_value=13604168 -HeapAlloc dt=5 heapalloc_value=13612360 -HeapAlloc dt=6 heapalloc_value=13620552 -HeapAlloc dt=5 heapalloc_value=13628744 -HeapAlloc dt=6 heapalloc_value=13636936 -HeapAlloc dt=5 heapalloc_value=13645128 -HeapAlloc dt=6 heapalloc_value=13653320 -HeapAlloc dt=14 heapalloc_value=13661512 -HeapAlloc dt=6 heapalloc_value=13669704 -HeapAlloc dt=6 heapalloc_value=13677896 -HeapAlloc dt=35 heapalloc_value=13686088 -HeapAlloc dt=7 heapalloc_value=13694280 -HeapAlloc dt=6 heapalloc_value=13702472 -HeapAlloc dt=6 heapalloc_value=13710664 -HeapAlloc dt=5 heapalloc_value=13718856 -HeapAlloc dt=6 heapalloc_value=13727048 -HeapAlloc dt=6 heapalloc_value=13735240 -HeapAlloc dt=5 heapalloc_value=13743432 -HeapAlloc dt=6 heapalloc_value=13751624 -HeapAlloc dt=5 heapalloc_value=13759816 -HeapAlloc dt=6 heapalloc_value=13768008 -HeapAlloc dt=5 heapalloc_value=13776200 -HeapAlloc dt=5 heapalloc_value=13784392 -HeapAlloc dt=6 heapalloc_value=13792584 -HeapAlloc dt=6 heapalloc_value=13800776 -HeapAlloc dt=5 heapalloc_value=13808968 -HeapAlloc dt=6 heapalloc_value=13817160 -HeapAlloc dt=5 heapalloc_value=13825352 -HeapAlloc dt=6 heapalloc_value=13833544 -HeapAlloc dt=5 heapalloc_value=13841736 -HeapAlloc dt=6 heapalloc_value=13849928 -HeapAlloc dt=5 heapalloc_value=13858120 -HeapAlloc dt=6 heapalloc_value=13866312 -HeapAlloc dt=5 heapalloc_value=13874504 -HeapAlloc dt=5 heapalloc_value=13882696 -HeapAlloc dt=6 heapalloc_value=13890888 -HeapAlloc dt=5 heapalloc_value=13899080 -HeapAlloc dt=6 heapalloc_value=13907272 -HeapAlloc dt=5 heapalloc_value=13915464 -HeapAlloc dt=6 heapalloc_value=13923656 -HeapAlloc dt=21 heapalloc_value=13931848 -HeapAlloc dt=6 heapalloc_value=13940040 -HeapAlloc dt=6 heapalloc_value=13948232 -HeapAlloc dt=6 heapalloc_value=13956424 -HeapAlloc dt=6 heapalloc_value=13964616 -HeapAlloc dt=5 heapalloc_value=13972808 -HeapAlloc dt=5 heapalloc_value=13981000 -HeapAlloc dt=6 heapalloc_value=13989192 -HeapAlloc dt=6 heapalloc_value=13997384 -HeapAlloc dt=5 heapalloc_value=14005576 -HeapAlloc dt=6 heapalloc_value=14013768 -HeapAlloc dt=5 heapalloc_value=14021960 -HeapAlloc dt=6 heapalloc_value=14030152 -HeapAlloc dt=6 heapalloc_value=14038344 -HeapAlloc dt=5 heapalloc_value=14046536 -HeapAlloc dt=6 heapalloc_value=14054728 -HeapAlloc dt=5 heapalloc_value=14062920 -HeapAlloc dt=6 heapalloc_value=14071112 -HeapAlloc dt=5 heapalloc_value=14079304 -HeapAlloc dt=5 heapalloc_value=14087496 -HeapAlloc dt=76 heapalloc_value=14095688 -HeapAlloc dt=35 heapalloc_value=14103880 -HeapAlloc dt=7 heapalloc_value=14112072 -HeapAlloc dt=5 heapalloc_value=14120264 -HeapAlloc dt=6 heapalloc_value=14128456 -HeapAlloc dt=7 heapalloc_value=14136648 -HeapAlloc dt=5 heapalloc_value=14144840 -HeapAlloc dt=5 heapalloc_value=14153032 -HeapAlloc dt=6 heapalloc_value=14161224 -HeapAlloc dt=5 heapalloc_value=14169416 -HeapAlloc dt=6 heapalloc_value=14177608 -HeapAlloc dt=10 heapalloc_value=14185800 -GoBlock dt=9 reason_string=19 stack=21 -ProcStop dt=108 -ProcStart dt=17296 p=2 p_seq=10 -ProcStop dt=12 -ProcStart dt=3626 p=0 p_seq=22 -ProcStop dt=8 -ProcStart dt=16715 p=0 p_seq=23 -GoUnblock dt=6 g=1 g_seq=48 stack=0 -GoStart dt=79 g=1 g_seq=49 -HeapAlloc dt=15 heapalloc_value=15553864 -HeapAlloc dt=13 heapalloc_value=15562056 -HeapAlloc dt=15 heapalloc_value=15570248 -HeapAlloc dt=7 heapalloc_value=15578440 -HeapAlloc dt=6 heapalloc_value=15586632 -HeapAlloc dt=6 heapalloc_value=15594824 -HeapAlloc dt=6 heapalloc_value=15603016 -HeapAlloc dt=6 heapalloc_value=15611208 -HeapAlloc dt=5 heapalloc_value=15619400 -HeapAlloc dt=6 heapalloc_value=15627592 -HeapAlloc dt=6 heapalloc_value=15635784 -HeapAlloc dt=5 heapalloc_value=15643976 -HeapAlloc dt=6 heapalloc_value=15652168 -HeapAlloc dt=5 heapalloc_value=15660360 -HeapAlloc dt=6 heapalloc_value=15668552 -HeapAlloc dt=6 heapalloc_value=15676744 -HeapAlloc dt=57 heapalloc_value=15684936 -HeapAlloc dt=7 heapalloc_value=15693128 -HeapAlloc dt=6 heapalloc_value=15701320 -HeapAlloc dt=6 heapalloc_value=15709512 -HeapAlloc dt=5 heapalloc_value=15717704 -HeapAlloc dt=6 heapalloc_value=15725896 -HeapAlloc dt=5 heapalloc_value=15734088 -HeapAlloc dt=6 heapalloc_value=15742280 -HeapAlloc dt=6 heapalloc_value=15750472 -HeapAlloc dt=10 heapalloc_value=15758664 -HeapAlloc dt=6 heapalloc_value=15766856 -HeapAlloc dt=6 heapalloc_value=15775048 -HeapAlloc dt=5 heapalloc_value=15783240 -HeapAlloc dt=6 heapalloc_value=15791432 -HeapAlloc dt=6 heapalloc_value=15799624 -HeapAlloc dt=6 heapalloc_value=15807816 -HeapAlloc dt=6 heapalloc_value=15816008 -HeapAlloc dt=7 heapalloc_value=15824200 -HeapAlloc dt=6 heapalloc_value=15832392 -HeapAlloc dt=6 heapalloc_value=15840584 -HeapAlloc dt=5 heapalloc_value=15848776 -HeapAlloc dt=6 heapalloc_value=15856968 -HeapAlloc dt=6 heapalloc_value=15865160 -HeapAlloc dt=6 heapalloc_value=15873352 -HeapAlloc dt=5 heapalloc_value=15881544 -HeapAlloc dt=6 heapalloc_value=15889736 -HeapAlloc dt=6 heapalloc_value=15897928 -HeapAlloc dt=5 heapalloc_value=15906120 -HeapAlloc dt=6 heapalloc_value=15914312 -HeapAlloc dt=5 heapalloc_value=15922504 -HeapAlloc dt=6 heapalloc_value=15930696 -HeapAlloc dt=5 heapalloc_value=15938888 -HeapAlloc dt=6 heapalloc_value=15947080 -HeapAlloc dt=5 heapalloc_value=15955272 -HeapAlloc dt=6 heapalloc_value=15963464 -HeapAlloc dt=6 heapalloc_value=15971656 -HeapAlloc dt=5 heapalloc_value=15979848 -HeapAlloc dt=6 heapalloc_value=15988040 -HeapAlloc dt=44 heapalloc_value=15996232 -HeapAlloc dt=8 heapalloc_value=16004424 -HeapAlloc dt=5 heapalloc_value=16012616 -HeapAlloc dt=6 heapalloc_value=16020808 -HeapAlloc dt=5 heapalloc_value=16029000 -HeapAlloc dt=6 heapalloc_value=16037192 -HeapAlloc dt=5 heapalloc_value=16045384 -HeapAlloc dt=6 heapalloc_value=16053576 -HeapAlloc dt=5 heapalloc_value=16061768 -HeapAlloc dt=6 heapalloc_value=16069960 -HeapAlloc dt=5 heapalloc_value=16078152 -HeapAlloc dt=6 heapalloc_value=16086344 -HeapAlloc dt=5 heapalloc_value=16094536 -HeapAlloc dt=6 heapalloc_value=16102728 -HeapAlloc dt=36 heapalloc_value=16110920 -HeapAlloc dt=8 heapalloc_value=16119112 -HeapAlloc dt=6 heapalloc_value=16127304 -HeapAlloc dt=5 heapalloc_value=16135496 -HeapAlloc dt=6 heapalloc_value=16143688 -HeapAlloc dt=5 heapalloc_value=16151880 -HeapAlloc dt=5 heapalloc_value=16160072 -HeapAlloc dt=5 heapalloc_value=16168264 -HeapAlloc dt=5 heapalloc_value=16176456 -HeapAlloc dt=5 heapalloc_value=16184648 -HeapAlloc dt=6 heapalloc_value=16192840 -HeapAlloc dt=5 heapalloc_value=16201032 -HeapAlloc dt=5 heapalloc_value=16209224 -HeapAlloc dt=5 heapalloc_value=16217416 -HeapAlloc dt=5 heapalloc_value=16225608 -HeapAlloc dt=6 heapalloc_value=16233800 -HeapAlloc dt=5 heapalloc_value=16241992 -HeapAlloc dt=73 heapalloc_value=16250184 -HeapAlloc dt=6 heapalloc_value=16258376 -HeapAlloc dt=5 heapalloc_value=16266568 -HeapAlloc dt=6 heapalloc_value=16274760 -HeapAlloc dt=371 heapalloc_value=16282952 -HeapAlloc dt=13 heapalloc_value=16291144 -HeapAlloc dt=7 heapalloc_value=16299336 -HeapAlloc dt=6 heapalloc_value=16307528 -HeapAlloc dt=6 heapalloc_value=16315720 -HeapAlloc dt=5 heapalloc_value=16323912 -HeapAlloc dt=6 heapalloc_value=16332104 -HeapAlloc dt=5 heapalloc_value=16340296 -HeapAlloc dt=5 heapalloc_value=16348488 -HeapAlloc dt=22 heapalloc_value=16356680 -HeapAlloc dt=6 heapalloc_value=16364872 -HeapAlloc dt=5 heapalloc_value=16373064 -HeapAlloc dt=6 heapalloc_value=16381256 -HeapAlloc dt=5 heapalloc_value=16389448 -HeapAlloc dt=5 heapalloc_value=16397640 -HeapAlloc dt=5 heapalloc_value=16405832 -HeapAlloc dt=5 heapalloc_value=16414024 -HeapAlloc dt=5 heapalloc_value=16422216 -HeapAlloc dt=6 heapalloc_value=16430408 -HeapAlloc dt=5 heapalloc_value=16438600 -HeapAlloc dt=6 heapalloc_value=16446792 -HeapAlloc dt=5 heapalloc_value=16454984 -HeapAlloc dt=5 heapalloc_value=16463176 -HeapAlloc dt=6 heapalloc_value=16471368 -HeapAlloc dt=5 heapalloc_value=16479560 -HeapAlloc dt=5 heapalloc_value=16487752 -HeapAlloc dt=5 heapalloc_value=16495944 -HeapAlloc dt=6 heapalloc_value=16504136 -HeapAlloc dt=5 heapalloc_value=16512328 -HeapAlloc dt=45 heapalloc_value=16520520 -HeapAlloc dt=38 heapalloc_value=16528712 -HeapAlloc dt=7 heapalloc_value=16536904 -HeapAlloc dt=5 heapalloc_value=16545096 -HeapAlloc dt=5 heapalloc_value=16553288 -HeapAlloc dt=6 heapalloc_value=16561480 -HeapAlloc dt=5 heapalloc_value=16569672 -GoBlock dt=11 reason_string=19 stack=21 -ProcStop dt=109 -ProcStart dt=18122 p=2 p_seq=12 -ProcStop dt=23 -ProcStart dt=803 p=1 p_seq=12 -GoUnblock dt=12 g=24 g_seq=10 stack=0 -GoStart dt=143 g=24 g_seq=11 -GoLabel dt=2 label_string=2 -GoBlock dt=3389 reason_string=15 stack=27 -ProcStop dt=2403 -ProcStart dt=161103 p=4 p_seq=8 -GoStart dt=172 g=38 g_seq=1 -GoStop dt=304901 reason_string=16 stack=50 -GoStart dt=21 g=38 g_seq=2 -GoStop dt=315468 reason_string=16 stack=50 -GoStart dt=20 g=38 g_seq=3 -GoDestroy dt=160861 -ProcStop dt=34 -EventBatch gen=1 m=1709044 time=7689670489757 size=2312 -ProcStart dt=310 p=3 p_seq=2 -ProcStop dt=39 -ProcStart dt=1386 p=3 p_seq=3 -ProcStop dt=138 -ProcStart dt=3920 p=0 p_seq=5 -GoStart dt=266 g=24 g_seq=7 -GoUnblock dt=50 g=1 g_seq=25 stack=41 -GoBlock dt=13 reason_string=15 stack=27 -GoStart dt=7 g=1 g_seq=26 -GCMarkAssistEnd dt=6 -HeapAlloc dt=29 heapalloc_value=3843824 -GCSweepBegin dt=57 stack=42 -GCSweepEnd dt=816 swept_value=827392 reclaimed_value=0 -GCSweepBegin dt=310 stack=43 -GCSweepEnd dt=63 swept_value=67108864 reclaimed_value=0 -HeapAlloc dt=23 heapalloc_value=3852016 -HeapAlloc dt=46 heapalloc_value=3860208 -HeapAlloc dt=27 heapalloc_value=3868400 -HeapAlloc dt=16 heapalloc_value=3876592 -HeapAlloc dt=109 heapalloc_value=3884784 -HeapAlloc dt=32 heapalloc_value=3892976 -HeapAlloc dt=33 heapalloc_value=3901168 -HeapAlloc dt=26 heapalloc_value=3909360 -HeapAlloc dt=35 heapalloc_value=3917552 -HeapAlloc dt=16 heapalloc_value=3925744 -HeapAlloc dt=16 heapalloc_value=3933936 -HeapAlloc dt=16 heapalloc_value=3942128 -HeapAlloc dt=68 heapalloc_value=3950320 -HeapAlloc dt=21 heapalloc_value=3958512 -HeapAlloc dt=20 heapalloc_value=3966704 -HeapAlloc dt=15 heapalloc_value=3974896 -HeapAlloc dt=24 heapalloc_value=3983088 -HeapAlloc dt=15 heapalloc_value=3991280 -HeapAlloc dt=16 heapalloc_value=3999472 -HeapAlloc dt=15 heapalloc_value=4007664 -HeapAlloc dt=18 heapalloc_value=4015856 -HeapAlloc dt=15 heapalloc_value=4024048 -HeapAlloc dt=21 heapalloc_value=4032240 -HeapAlloc dt=26 heapalloc_value=4040432 -HeapAlloc dt=28 heapalloc_value=4048624 -HeapAlloc dt=16 heapalloc_value=4056816 -HeapAlloc dt=16 heapalloc_value=4065008 -HeapAlloc dt=16 heapalloc_value=4073200 -HeapAlloc dt=17 heapalloc_value=4081392 -HeapAlloc dt=15 heapalloc_value=4089584 -HeapAlloc dt=19 heapalloc_value=4097776 -HeapAlloc dt=15 heapalloc_value=4105968 -HeapAlloc dt=20 heapalloc_value=4114160 -HeapAlloc dt=15 heapalloc_value=4122352 -HeapAlloc dt=16 heapalloc_value=4130544 -HeapAlloc dt=16 heapalloc_value=4138736 -HeapAlloc dt=17 heapalloc_value=4146928 -HeapAlloc dt=15 heapalloc_value=4155120 -HeapAlloc dt=20 heapalloc_value=4163312 -HeapAlloc dt=18 heapalloc_value=4171504 -HeapAlloc dt=23 heapalloc_value=4179696 -HeapAlloc dt=18 heapalloc_value=4187888 -HeapAlloc dt=20 heapalloc_value=4196080 -HeapAlloc dt=19 heapalloc_value=4204272 -HeapAlloc dt=19 heapalloc_value=4212464 -HeapAlloc dt=105 heapalloc_value=4220656 -HeapAlloc dt=45 heapalloc_value=4228848 -HeapAlloc dt=22 heapalloc_value=4237040 -HeapAlloc dt=23 heapalloc_value=4245232 -HeapAlloc dt=29 heapalloc_value=4253424 -HeapAlloc dt=21 heapalloc_value=4261616 -HeapAlloc dt=56 heapalloc_value=4269808 -HeapAlloc dt=21 heapalloc_value=4278000 -HeapAlloc dt=25 heapalloc_value=4286192 -HeapAlloc dt=15 heapalloc_value=4294384 -HeapAlloc dt=60 heapalloc_value=4302576 -HeapAlloc dt=40 heapalloc_value=4359920 -HeapAlloc dt=152 heapalloc_value=4368112 -HeapAlloc dt=30 heapalloc_value=4376304 -HeapAlloc dt=27 heapalloc_value=4384496 -HeapAlloc dt=20 heapalloc_value=4392688 -HeapAlloc dt=32 heapalloc_value=4400880 -HeapAlloc dt=25 heapalloc_value=4409072 -HeapAlloc dt=48 heapalloc_value=4417264 -HeapAlloc dt=58 heapalloc_value=4425456 -HeapAlloc dt=30 heapalloc_value=4433648 -HeapAlloc dt=23 heapalloc_value=4441840 -HeapAlloc dt=16 heapalloc_value=4450032 -HeapAlloc dt=17 heapalloc_value=4458224 -HeapAlloc dt=16 heapalloc_value=4466416 -HeapAlloc dt=19 heapalloc_value=4474608 -HeapAlloc dt=16 heapalloc_value=4482800 -HeapAlloc dt=15 heapalloc_value=4490992 -HeapAlloc dt=16 heapalloc_value=4499184 -HeapAlloc dt=16 heapalloc_value=4507376 -HeapAlloc dt=15 heapalloc_value=4515568 -HeapAlloc dt=16 heapalloc_value=4523760 -HeapAlloc dt=16 heapalloc_value=4531952 -HeapAlloc dt=21 heapalloc_value=4540144 -HeapAlloc dt=25 heapalloc_value=4548336 -HeapAlloc dt=22 heapalloc_value=4556528 -HeapAlloc dt=59 heapalloc_value=4564720 -HeapAlloc dt=21 heapalloc_value=4572912 -HeapAlloc dt=16 heapalloc_value=4581104 -HeapAlloc dt=16 heapalloc_value=4589296 -HeapAlloc dt=15 heapalloc_value=4597488 -HeapAlloc dt=24 heapalloc_value=4605680 -HeapAlloc dt=12 heapalloc_value=4613872 -HeapAlloc dt=8 heapalloc_value=4622064 -HeapAlloc dt=11 heapalloc_value=4630256 -HeapAlloc dt=7 heapalloc_value=4638448 -HeapAlloc dt=7 heapalloc_value=4646640 -HeapAlloc dt=7 heapalloc_value=4654832 -GoBlock dt=31 reason_string=19 stack=21 -ProcStop dt=34 -ProcStart dt=6196 p=4 p_seq=2 -ProcStop dt=26 -ProcStart dt=1578 p=0 p_seq=7 -ProcStop dt=12 -ProcStart dt=16743 p=0 p_seq=8 -GoUnblock dt=21 g=1 g_seq=29 stack=0 -GoStart dt=147 g=1 g_seq=30 -HeapAlloc dt=51 heapalloc_value=5768944 -HeapAlloc dt=22 heapalloc_value=5777136 -HeapAlloc dt=16 heapalloc_value=5785328 -HeapAlloc dt=15 heapalloc_value=5793520 -HeapAlloc dt=16 heapalloc_value=5801712 -HeapAlloc dt=18 heapalloc_value=5809904 -HeapAlloc dt=15 heapalloc_value=5818096 -HeapAlloc dt=15 heapalloc_value=5826288 -HeapAlloc dt=12 heapalloc_value=5834480 -HeapAlloc dt=12 heapalloc_value=5842672 -HeapAlloc dt=15 heapalloc_value=5850864 -HeapAlloc dt=16 heapalloc_value=5859056 -HeapAlloc dt=12 heapalloc_value=5867248 -HeapAlloc dt=12 heapalloc_value=5875440 -HeapAlloc dt=6 heapalloc_value=5883632 -HeapAlloc dt=8 heapalloc_value=5891824 -HeapAlloc dt=6 heapalloc_value=5900016 -HeapAlloc dt=6 heapalloc_value=5908208 -HeapAlloc dt=98 heapalloc_value=5916400 -HeapAlloc dt=21 heapalloc_value=5924592 -HeapAlloc dt=5 heapalloc_value=5932784 -HeapAlloc dt=7 heapalloc_value=5940976 -HeapAlloc dt=6 heapalloc_value=5949168 -HeapAlloc dt=9 heapalloc_value=5957360 -HeapAlloc dt=6 heapalloc_value=5965552 -HeapAlloc dt=5 heapalloc_value=5973744 -HeapAlloc dt=7 heapalloc_value=5981936 -HeapAlloc dt=5 heapalloc_value=5990128 -HeapAlloc dt=6 heapalloc_value=5998320 -HeapAlloc dt=5 heapalloc_value=6006512 -HeapAlloc dt=6 heapalloc_value=6014704 -HeapAlloc dt=9 heapalloc_value=6022896 -HeapAlloc dt=5 heapalloc_value=6031088 -HeapAlloc dt=6 heapalloc_value=6039280 -HeapAlloc dt=6 heapalloc_value=6047472 -HeapAlloc dt=40 heapalloc_value=6055664 -HeapAlloc dt=6 heapalloc_value=6063856 -HeapAlloc dt=35 heapalloc_value=6072048 -HeapAlloc dt=8 heapalloc_value=6080240 -HeapAlloc dt=9 heapalloc_value=6088432 -HeapAlloc dt=5 heapalloc_value=6096624 -HeapAlloc dt=6 heapalloc_value=6104816 -HeapAlloc dt=5 heapalloc_value=6113008 -HeapAlloc dt=6 heapalloc_value=6121200 -HeapAlloc dt=6 heapalloc_value=6129392 -HeapAlloc dt=6 heapalloc_value=6137584 -HeapAlloc dt=5 heapalloc_value=6145776 -HeapAlloc dt=9 heapalloc_value=6153968 -HeapAlloc dt=5 heapalloc_value=6162160 -HeapAlloc dt=6 heapalloc_value=6170352 -HeapAlloc dt=6 heapalloc_value=6178544 -HeapAlloc dt=8 heapalloc_value=6186736 -HeapAlloc dt=11 heapalloc_value=6301424 -HeapAlloc dt=2483 heapalloc_value=6309616 -HeapAlloc dt=9 heapalloc_value=6317808 -HeapAlloc dt=7 heapalloc_value=6326000 -HeapAlloc dt=11 heapalloc_value=6334192 -HeapAlloc dt=6 heapalloc_value=6342384 -HeapAlloc dt=6 heapalloc_value=6350576 -HeapAlloc dt=6 heapalloc_value=6358768 -HeapAlloc dt=7 heapalloc_value=6366960 -HeapAlloc dt=9 heapalloc_value=6375152 -HeapAlloc dt=5 heapalloc_value=6383344 -HeapAlloc dt=6 heapalloc_value=6391536 -HeapAlloc dt=6 heapalloc_value=6399728 -HeapAlloc dt=5 heapalloc_value=6407920 -HeapAlloc dt=5 heapalloc_value=6416112 -HeapAlloc dt=6 heapalloc_value=6424304 -HeapAlloc dt=9 heapalloc_value=6432496 -HeapAlloc dt=8 heapalloc_value=6440688 -HeapAlloc dt=9 heapalloc_value=6448880 -HeapAlloc dt=6 heapalloc_value=6457072 -HeapAlloc dt=13 heapalloc_value=6465264 -HeapAlloc dt=6 heapalloc_value=6473456 -HeapAlloc dt=5 heapalloc_value=6481648 -HeapAlloc dt=6 heapalloc_value=6489840 -HeapAlloc dt=5 heapalloc_value=6498032 -HeapAlloc dt=6 heapalloc_value=6506224 -HeapAlloc dt=8 heapalloc_value=6514416 -HeapAlloc dt=6 heapalloc_value=6522608 -HeapAlloc dt=6 heapalloc_value=6530800 -HeapAlloc dt=5 heapalloc_value=6538992 -HeapAlloc dt=81 heapalloc_value=6547184 -HeapAlloc dt=7 heapalloc_value=6555376 -HeapAlloc dt=6 heapalloc_value=6563568 -HeapAlloc dt=5 heapalloc_value=6571760 -HeapAlloc dt=20 heapalloc_value=6579952 -HeapAlloc dt=6 heapalloc_value=6588144 -HeapAlloc dt=56 heapalloc_value=6596336 -HeapAlloc dt=7 heapalloc_value=6604528 -HeapAlloc dt=7 heapalloc_value=6612720 -HeapAlloc dt=6 heapalloc_value=6620912 -HeapAlloc dt=5 heapalloc_value=6629104 -HeapAlloc dt=5 heapalloc_value=6637296 -HeapAlloc dt=6 heapalloc_value=6645488 -HeapAlloc dt=5 heapalloc_value=6653680 -HeapAlloc dt=5 heapalloc_value=6661872 -HeapAlloc dt=6 heapalloc_value=6670064 -HeapAlloc dt=5 heapalloc_value=6678256 -HeapAlloc dt=5 heapalloc_value=6686448 -HeapAlloc dt=6 heapalloc_value=6694640 -HeapAlloc dt=5 heapalloc_value=6702832 -HeapAlloc dt=5 heapalloc_value=6711024 -HeapAlloc dt=6 heapalloc_value=6719216 -HeapAlloc dt=9 heapalloc_value=6727408 -HeapAlloc dt=7 heapalloc_value=6735600 -HeapAlloc dt=5 heapalloc_value=6743792 -HeapAlloc dt=5 heapalloc_value=6751984 -HeapAlloc dt=6 heapalloc_value=6760176 -HeapAlloc dt=5 heapalloc_value=6768368 -HeapAlloc dt=5 heapalloc_value=6776560 -HeapAlloc dt=6 heapalloc_value=6784752 -HeapAlloc dt=5 heapalloc_value=6792944 -HeapAlloc dt=6 heapalloc_value=6801136 -HeapAlloc dt=36 heapalloc_value=6809328 -HeapAlloc dt=7 heapalloc_value=6817520 -HeapAlloc dt=5 heapalloc_value=6825712 -HeapAlloc dt=6 heapalloc_value=6833904 -HeapAlloc dt=6 heapalloc_value=6842096 -HeapAlloc dt=5 heapalloc_value=6850288 -HeapAlloc dt=6 heapalloc_value=6858480 -HeapAlloc dt=5 heapalloc_value=6866672 -HeapAlloc dt=5 heapalloc_value=6874864 -HeapAlloc dt=5 heapalloc_value=6883056 -HeapAlloc dt=5 heapalloc_value=6891248 -HeapAlloc dt=6 heapalloc_value=6899440 -GoBlock dt=14 reason_string=19 stack=21 -ProcStop dt=198 -ProcStart dt=2996 p=0 p_seq=10 -GoUnblock dt=12 g=1 g_seq=31 stack=0 -GoStart dt=135 g=1 g_seq=32 -HeapAlloc dt=25 heapalloc_value=6907632 -HeapAlloc dt=9 heapalloc_value=6915824 -HeapAlloc dt=6 heapalloc_value=6924016 -HeapAlloc dt=5 heapalloc_value=6932208 -HeapAlloc dt=6 heapalloc_value=6940400 -HeapAlloc dt=5 heapalloc_value=6948592 -HeapAlloc dt=5 heapalloc_value=6956784 -HeapAlloc dt=6 heapalloc_value=6964976 -HeapAlloc dt=5 heapalloc_value=6973168 -HeapAlloc dt=6 heapalloc_value=6981360 -HeapAlloc dt=5 heapalloc_value=6989552 -HeapAlloc dt=5 heapalloc_value=6997744 -HeapAlloc dt=5 heapalloc_value=7005936 -HeapAlloc dt=97 heapalloc_value=7014128 -HeapAlloc dt=7 heapalloc_value=7022320 -HeapAlloc dt=5 heapalloc_value=7030512 -HeapAlloc dt=6 heapalloc_value=7038704 -HeapAlloc dt=5 heapalloc_value=7046896 -HeapAlloc dt=5 heapalloc_value=7055088 -HeapAlloc dt=5 heapalloc_value=7063280 -HeapAlloc dt=50 heapalloc_value=7071472 -HeapAlloc dt=7 heapalloc_value=7079664 -HeapAlloc dt=6 heapalloc_value=7087856 -HeapAlloc dt=5 heapalloc_value=7096048 -HeapAlloc dt=20 heapalloc_value=7104240 -HeapAlloc dt=6 heapalloc_value=7112432 -HeapAlloc dt=8 heapalloc_value=7120624 -HeapAlloc dt=6 heapalloc_value=7128816 -HeapAlloc dt=5 heapalloc_value=7137008 -HeapAlloc dt=6 heapalloc_value=7145200 -HeapAlloc dt=8 heapalloc_value=7153392 -HeapAlloc dt=6 heapalloc_value=7161584 -HeapAlloc dt=5 heapalloc_value=7169776 -HeapAlloc dt=5 heapalloc_value=7177968 -HeapAlloc dt=6 heapalloc_value=7186160 -HeapAlloc dt=5 heapalloc_value=7194352 -HeapAlloc dt=5 heapalloc_value=7202544 -HeapAlloc dt=6 heapalloc_value=7210736 -HeapAlloc dt=5 heapalloc_value=7218928 -HeapAlloc dt=35 heapalloc_value=7227120 -HeapAlloc dt=10 heapalloc_value=7235312 -HeapAlloc dt=5 heapalloc_value=7243504 -HeapAlloc dt=5 heapalloc_value=7251696 -HeapAlloc dt=6 heapalloc_value=7259888 -HeapAlloc dt=5 heapalloc_value=7268080 -HeapAlloc dt=5 heapalloc_value=7276272 -HeapAlloc dt=5 heapalloc_value=7284464 -HeapAlloc dt=6 heapalloc_value=7292656 -HeapAlloc dt=6 heapalloc_value=7300848 -HeapAlloc dt=5 heapalloc_value=7309040 -HeapAlloc dt=13 heapalloc_value=7317232 -HeapAlloc dt=5 heapalloc_value=7325424 -HeapAlloc dt=6 heapalloc_value=7333616 -HeapAlloc dt=8 heapalloc_value=7341808 -HeapAlloc dt=5 heapalloc_value=7350000 -HeapAlloc dt=9 heapalloc_value=7358192 -HeapAlloc dt=5 heapalloc_value=7366384 -HeapAlloc dt=6 heapalloc_value=7374576 -HeapAlloc dt=5 heapalloc_value=7382768 -HeapAlloc dt=5 heapalloc_value=7390960 -HeapAlloc dt=5 heapalloc_value=7399152 -HeapAlloc dt=6 heapalloc_value=7407344 -HeapAlloc dt=5 heapalloc_value=7415536 -HeapAlloc dt=5 heapalloc_value=7423728 -HeapAlloc dt=6 heapalloc_value=7431920 -HeapAlloc dt=5 heapalloc_value=7440112 -HeapAlloc dt=5 heapalloc_value=7448304 -HeapAlloc dt=5 heapalloc_value=7456496 -HeapAlloc dt=6 heapalloc_value=7464688 -HeapAlloc dt=5 heapalloc_value=7472880 -HeapAlloc dt=5 heapalloc_value=7481072 -HeapAlloc dt=5 heapalloc_value=7489264 -HeapAlloc dt=6 heapalloc_value=7497456 -HeapAlloc dt=5 heapalloc_value=7505648 -HeapAlloc dt=5 heapalloc_value=7513840 -HeapAlloc dt=5 heapalloc_value=7522032 -HeapAlloc dt=5 heapalloc_value=7530224 -HeapAlloc dt=6 heapalloc_value=7538416 -HeapAlloc dt=5 heapalloc_value=7546608 -HeapAlloc dt=6 heapalloc_value=7554800 -HeapAlloc dt=5 heapalloc_value=7562992 -HeapAlloc dt=5 heapalloc_value=7571184 -HeapAlloc dt=6 heapalloc_value=7579376 -HeapAlloc dt=5 heapalloc_value=7587568 -HeapAlloc dt=45 heapalloc_value=7595760 -HeapAlloc dt=7 heapalloc_value=7603952 -HeapAlloc dt=5 heapalloc_value=7612144 -HeapAlloc dt=6 heapalloc_value=7620336 -HeapAlloc dt=376 heapalloc_value=7628528 -HeapAlloc dt=13 heapalloc_value=7636720 -HeapAlloc dt=7 heapalloc_value=7644912 -HeapAlloc dt=35 heapalloc_value=7653104 -GCBegin dt=23 gc_seq=3 stack=22 -STWBegin dt=73 kind_string=22 stack=28 -GoUnblock dt=258 g=4 g_seq=5 stack=29 -ProcsChange dt=80 procs_value=8 stack=30 -STWEnd dt=37 -GCMarkAssistBegin dt=96 stack=31 -GCMarkAssistEnd dt=4606 -HeapAlloc dt=187 heapalloc_value=7671600 -HeapAlloc dt=26 heapalloc_value=7679792 -HeapAlloc dt=17 heapalloc_value=7687984 -HeapAlloc dt=29 heapalloc_value=7696176 -HeapAlloc dt=16 heapalloc_value=7704368 -HeapAlloc dt=12 heapalloc_value=7712560 -HeapAlloc dt=48 heapalloc_value=7868208 -GoStop dt=4635 reason_string=16 stack=45 -GoStart dt=48 g=1 g_seq=33 -HeapAlloc dt=27 heapalloc_value=7884336 -HeapAlloc dt=11 heapalloc_value=7892528 -HeapAlloc dt=8 heapalloc_value=7900720 -HeapAlloc dt=12 heapalloc_value=7908912 -HeapAlloc dt=9 heapalloc_value=7917104 -HeapAlloc dt=9 heapalloc_value=7925296 -HeapAlloc dt=9 heapalloc_value=7933488 -HeapAlloc dt=8 heapalloc_value=7941680 -HeapAlloc dt=10 heapalloc_value=7949872 -HeapAlloc dt=8 heapalloc_value=7958064 -HeapAlloc dt=10 heapalloc_value=7966256 -HeapAlloc dt=12 heapalloc_value=7974448 -HeapAlloc dt=8 heapalloc_value=7982640 -HeapAlloc dt=8 heapalloc_value=7990832 -HeapAlloc dt=9 heapalloc_value=7999024 -HeapAlloc dt=8 heapalloc_value=8007216 -HeapAlloc dt=54 heapalloc_value=8015408 -HeapAlloc dt=10 heapalloc_value=8023600 -HeapAlloc dt=8 heapalloc_value=8031792 -HeapAlloc dt=9 heapalloc_value=8039984 -HeapAlloc dt=8 heapalloc_value=8048176 -HeapAlloc dt=9 heapalloc_value=8056368 -HeapAlloc dt=8 heapalloc_value=8064560 -HeapAlloc dt=9 heapalloc_value=8072752 -HeapAlloc dt=8 heapalloc_value=8080944 -HeapAlloc dt=9 heapalloc_value=8089136 -HeapAlloc dt=8 heapalloc_value=8097328 -GoBlock dt=20 reason_string=19 stack=21 -ProcStop dt=35 -ProcStart dt=147580 p=3 p_seq=6 -GoStart dt=144 g=4 g_seq=10 -GoBlock dt=38 reason_string=15 stack=32 -GoUnblock dt=41 g=25 g_seq=4 stack=0 -GoStart dt=6 g=25 g_seq=5 -GoLabel dt=1 label_string=4 -GoBlock dt=5825 reason_string=15 stack=27 -ProcStop dt=299 -ProcStart dt=158874 p=3 p_seq=7 -GoStart dt=231 g=35 g_seq=1 -GoStop dt=305629 reason_string=16 stack=51 -GoStart dt=79 g=35 g_seq=2 -GoStop dt=315206 reason_string=16 stack=50 -GoStart dt=36 g=35 g_seq=3 -GoDestroy dt=160337 -ProcStop dt=68 -EventBatch gen=1 m=1709042 time=7689670149213 size=4550 -ProcStart dt=287 p=2 p_seq=1 -GoStart dt=328 g=7 g_seq=1 -HeapAlloc dt=7006 heapalloc_value=2793472 -HeapAlloc dt=74 heapalloc_value=2801664 -GoBlock dt=275 reason_string=12 stack=18 -ProcStop dt=34 -ProcStart dt=327698 p=0 p_seq=3 -ProcStop dt=7 -ProcStart dt=2124 p=2 p_seq=3 -GoUnblock dt=32 g=24 g_seq=2 stack=0 -HeapAlloc dt=302 heapalloc_value=4038656 -HeapAlloc dt=104 heapalloc_value=4046848 -HeapAlloc dt=52 heapalloc_value=4055040 -GoStart dt=1147 g=24 g_seq=3 -GoLabel dt=5 label_string=2 -GoBlock dt=128 reason_string=15 stack=27 -GoUnblock dt=72 g=1 g_seq=21 stack=0 -GoStart dt=11 g=1 g_seq=22 -HeapAlloc dt=44 heapalloc_value=4063232 -HeapAlloc dt=43 heapalloc_value=4071424 -HeapAlloc dt=28 heapalloc_value=4079616 -HeapAlloc dt=24 heapalloc_value=4087808 -HeapAlloc dt=84 heapalloc_value=4096000 -HeapAlloc dt=25 heapalloc_value=4104192 -HeapAlloc dt=20 heapalloc_value=4112384 -HeapAlloc dt=24 heapalloc_value=4120576 -HeapAlloc dt=20 heapalloc_value=4128768 -HeapAlloc dt=19 heapalloc_value=4136960 -HeapAlloc dt=24 heapalloc_value=4145152 -HeapAlloc dt=20 heapalloc_value=4153344 -HeapAlloc dt=19 heapalloc_value=4161536 -HeapAlloc dt=20 heapalloc_value=4169728 -HeapAlloc dt=24 heapalloc_value=4177920 -HeapAlloc dt=33 heapalloc_value=4186112 -HeapAlloc dt=26 heapalloc_value=4194304 -HeapAlloc dt=31 heapalloc_value=4235264 -HeapAlloc dt=363 heapalloc_value=4243456 -HeapAlloc dt=61 heapalloc_value=4251648 -HeapAlloc dt=14 heapalloc_value=4259840 -HeapAlloc dt=12 heapalloc_value=4268032 -HeapAlloc dt=9 heapalloc_value=4276224 -HeapAlloc dt=9 heapalloc_value=4284416 -HeapAlloc dt=9 heapalloc_value=4292608 -HeapAlloc dt=8 heapalloc_value=4300800 -HeapAlloc dt=162 heapalloc_value=4308992 -HeapAlloc dt=14 heapalloc_value=4317184 -HeapAlloc dt=8 heapalloc_value=4325376 -HeapAlloc dt=53 heapalloc_value=4333568 -HeapAlloc dt=10 heapalloc_value=4341760 -HeapAlloc dt=16 heapalloc_value=4349952 -HeapAlloc dt=14 heapalloc_value=4358144 -GCMarkAssistBegin dt=27 stack=31 -GCMarkAssistEnd dt=18 -GCMarkAssistBegin dt=4 stack=31 -GoBlock dt=198 reason_string=13 stack=33 -ProcStop dt=19 -ProcStart dt=387 p=2 p_seq=4 -GoUnblock dt=265 g=24 g_seq=4 stack=0 -GoStart dt=69 g=24 g_seq=5 -GoLabel dt=1 label_string=2 -GoBlock dt=132 reason_string=10 stack=35 -GoStart dt=20 g=1 g_seq=24 -GCMarkAssistEnd dt=2 -HeapAlloc dt=13 heapalloc_value=4366336 -GCMarkAssistBegin dt=7 stack=31 -GoBlock dt=25 reason_string=10 stack=36 -ProcStop dt=24 -ProcStart dt=4689 p=1 p_seq=7 -ProcStop dt=23 -ProcStart dt=36183 p=1 p_seq=8 -ProcStop dt=24 -ProcStart dt=1076 p=1 p_seq=9 -GoUnblock dt=12 g=22 g_seq=4 stack=0 -GoStart dt=118 g=22 g_seq=5 -GoLabel dt=1 label_string=2 -GoBlock dt=7117 reason_string=15 stack=27 -ProcStop dt=41 -ProcStart dt=150567 p=4 p_seq=7 -GoUnblock dt=41 g=23 g_seq=4 stack=0 -HeapAlloc dt=108 heapalloc_value=17163592 -HeapAlloc dt=61 heapalloc_value=17166856 -HeapAlloc dt=2994 heapalloc_value=17608712 -GoStart dt=1008 g=23 g_seq=5 -GoLabel dt=4 label_string=4 -GoBlock dt=40 reason_string=15 stack=27 -GoUnblock dt=49 g=1 g_seq=52 stack=0 -GoStart dt=7 g=1 g_seq=53 -HeapAlloc dt=30 heapalloc_value=17616904 -HeapAlloc dt=52 heapalloc_value=17625096 -HeapAlloc dt=35 heapalloc_value=17633288 -HeapAlloc dt=27 heapalloc_value=17641480 -HeapAlloc dt=28 heapalloc_value=17649672 -HeapAlloc dt=87 heapalloc_value=17657864 -HeapAlloc dt=32 heapalloc_value=17666056 -HeapAlloc dt=24 heapalloc_value=17674248 -HeapAlloc dt=22 heapalloc_value=17682440 -HeapAlloc dt=16 heapalloc_value=17690632 -HeapAlloc dt=15 heapalloc_value=17698824 -HeapAlloc dt=20 heapalloc_value=17707016 -HeapAlloc dt=19 heapalloc_value=17715208 -HeapAlloc dt=15 heapalloc_value=17723400 -HeapAlloc dt=18 heapalloc_value=17731592 -HeapAlloc dt=20 heapalloc_value=17739784 -HeapAlloc dt=15 heapalloc_value=17747976 -HeapAlloc dt=17 heapalloc_value=17756168 -HeapAlloc dt=67 heapalloc_value=17764360 -HeapAlloc dt=28 heapalloc_value=17772552 -HeapAlloc dt=22 heapalloc_value=17780744 -HeapAlloc dt=19 heapalloc_value=17788936 -HeapAlloc dt=22 heapalloc_value=17797128 -HeapAlloc dt=19 heapalloc_value=17805320 -HeapAlloc dt=19 heapalloc_value=17813512 -HeapAlloc dt=19 heapalloc_value=17821704 -HeapAlloc dt=15 heapalloc_value=17829896 -HeapAlloc dt=21 heapalloc_value=17838088 -HeapAlloc dt=19 heapalloc_value=17846280 -HeapAlloc dt=16 heapalloc_value=17854472 -HeapAlloc dt=14 heapalloc_value=17862664 -HeapAlloc dt=18 heapalloc_value=17870856 -HeapAlloc dt=58 heapalloc_value=17879048 -HeapAlloc dt=19 heapalloc_value=17887240 -HeapAlloc dt=15 heapalloc_value=17895432 -HeapAlloc dt=19 heapalloc_value=17903624 -HeapAlloc dt=21 heapalloc_value=17911816 -HeapAlloc dt=17 heapalloc_value=17920008 -HeapAlloc dt=19 heapalloc_value=17928200 -HeapAlloc dt=19 heapalloc_value=17936392 -HeapAlloc dt=16 heapalloc_value=17944584 -HeapAlloc dt=15 heapalloc_value=17952776 -HeapAlloc dt=15 heapalloc_value=17960968 -HeapAlloc dt=19 heapalloc_value=17969160 -HeapAlloc dt=16 heapalloc_value=17977352 -HeapAlloc dt=16 heapalloc_value=17985544 -HeapAlloc dt=16 heapalloc_value=17993736 -HeapAlloc dt=19 heapalloc_value=18001928 -HeapAlloc dt=15 heapalloc_value=18010120 -HeapAlloc dt=16 heapalloc_value=18018312 -HeapAlloc dt=15 heapalloc_value=18026504 -HeapAlloc dt=19 heapalloc_value=18034696 -HeapAlloc dt=14 heapalloc_value=18042888 -HeapAlloc dt=17 heapalloc_value=18051080 -HeapAlloc dt=18 heapalloc_value=18059272 -HeapAlloc dt=20 heapalloc_value=18067464 -HeapAlloc dt=17 heapalloc_value=18075656 -HeapAlloc dt=125 heapalloc_value=18083848 -GoStop dt=20 reason_string=16 stack=46 -GoUnblock dt=288 g=25 g_seq=6 stack=0 -GoStart dt=7 g=25 g_seq=7 -GoLabel dt=1 label_string=2 -HeapAlloc dt=255 heapalloc_value=18091752 -GoBlock dt=30 reason_string=10 stack=35 -GoStart dt=5 g=1 g_seq=54 -HeapAlloc dt=25 heapalloc_value=18099944 -HeapAlloc dt=19 heapalloc_value=18108136 -HeapAlloc dt=45 heapalloc_value=18116328 -HeapAlloc dt=9 heapalloc_value=18124520 -HeapAlloc dt=80 heapalloc_value=18132712 -HeapAlloc dt=11 heapalloc_value=18140904 -HeapAlloc dt=6 heapalloc_value=18149096 -HeapAlloc dt=7 heapalloc_value=18157288 -HeapAlloc dt=7 heapalloc_value=18165480 -HeapAlloc dt=12 heapalloc_value=18173672 -HeapAlloc dt=11 heapalloc_value=18181864 -HeapAlloc dt=11 heapalloc_value=18190056 -HeapAlloc dt=7 heapalloc_value=18198248 -HeapAlloc dt=62 heapalloc_value=18206440 -HeapAlloc dt=8 heapalloc_value=18214632 -HeapAlloc dt=7 heapalloc_value=18222824 -HeapAlloc dt=6 heapalloc_value=18231016 -HeapAlloc dt=7 heapalloc_value=18239208 -HeapAlloc dt=11 heapalloc_value=18247400 -HeapAlloc dt=6 heapalloc_value=18255592 -HeapAlloc dt=7 heapalloc_value=18263784 -HeapAlloc dt=11 heapalloc_value=18271976 -HeapAlloc dt=6 heapalloc_value=18280168 -HeapAlloc dt=7 heapalloc_value=18288360 -HeapAlloc dt=7 heapalloc_value=18296552 -HeapAlloc dt=6 heapalloc_value=18304744 -HeapAlloc dt=10 heapalloc_value=18312936 -HeapAlloc dt=7 heapalloc_value=18321128 -HeapAlloc dt=7 heapalloc_value=18329320 -HeapAlloc dt=7 heapalloc_value=18337512 -HeapAlloc dt=31 heapalloc_value=18345704 -HeapAlloc dt=17 heapalloc_value=18353896 -HeapAlloc dt=7 heapalloc_value=18362088 -HeapAlloc dt=13 heapalloc_value=18370280 -HeapAlloc dt=6 heapalloc_value=18378472 -HeapAlloc dt=7 heapalloc_value=18386664 -HeapAlloc dt=7 heapalloc_value=18394856 -HeapAlloc dt=11 heapalloc_value=18403048 -HeapAlloc dt=6 heapalloc_value=18411240 -HeapAlloc dt=7 heapalloc_value=18419432 -HeapAlloc dt=7 heapalloc_value=18427624 -HeapAlloc dt=6 heapalloc_value=18435816 -HeapAlloc dt=7 heapalloc_value=18444008 -HeapAlloc dt=7 heapalloc_value=18452200 -GCMarkAssistBegin dt=13 stack=31 -GoBlock dt=35 reason_string=10 stack=36 -ProcStop dt=22 -ProcStart dt=936 p=1 p_seq=13 -GoStart dt=212 g=25 g_seq=9 -GoUnblock dt=31 g=1 g_seq=55 stack=41 -GoBlock dt=7 reason_string=15 stack=27 -GoStart dt=13 g=1 g_seq=56 -GCMarkAssistEnd dt=4 -HeapAlloc dt=30 heapalloc_value=16971400 -GCSweepBegin dt=41 stack=42 -GCSweepEnd dt=310 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=23 heapalloc_value=16979592 -GCSweepBegin dt=30 stack=42 -GCSweepEnd dt=934 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=80 heapalloc_value=16987784 -GCSweepBegin dt=43 stack=42 -GCSweepEnd dt=1671 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=6 heapalloc_value=16995976 -GCSweepBegin dt=41 stack=42 -GCSweepEnd dt=1680 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=13 heapalloc_value=17004168 -GCSweepBegin dt=44 stack=42 -GCSweepEnd dt=1555 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=12 heapalloc_value=17012360 -GCSweepBegin dt=46 stack=42 -GCSweepEnd dt=1914 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=16 heapalloc_value=17020552 -GCSweepBegin dt=47 stack=42 -GCSweepEnd dt=1545 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=10 heapalloc_value=17028744 -GCSweepBegin dt=37 stack=42 -GCSweepEnd dt=1763 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=9 heapalloc_value=17036936 -GCSweepBegin dt=37 stack=42 -GCSweepEnd dt=1712 swept_value=827392 reclaimed_value=0 -HeapAlloc dt=18 heapalloc_value=17045128 -GCSweepBegin dt=34 stack=42 -GCSweepEnd dt=1009 swept_value=466944 reclaimed_value=0 -HeapAlloc dt=9 heapalloc_value=17053320 -HeapAlloc dt=28 heapalloc_value=17061512 -HeapAlloc dt=25 heapalloc_value=17069704 -HeapAlloc dt=34 heapalloc_value=17077896 -HeapAlloc dt=39 heapalloc_value=17086088 -HeapAlloc dt=72 heapalloc_value=17094280 -HeapAlloc dt=32 heapalloc_value=17102472 -HeapAlloc dt=16 heapalloc_value=17110664 -HeapAlloc dt=15 heapalloc_value=17118856 -HeapAlloc dt=14 heapalloc_value=17127048 -HeapAlloc dt=16 heapalloc_value=17135240 -HeapAlloc dt=15 heapalloc_value=17143432 -HeapAlloc dt=19 heapalloc_value=17151624 -HeapAlloc dt=15 heapalloc_value=17159816 -HeapAlloc dt=54 heapalloc_value=17585800 -GoBlock dt=482 reason_string=19 stack=21 -ProcStop dt=210 -ProcStart dt=17621 p=0 p_seq=26 -ProcStop dt=24 -ProcStart dt=5194 p=1 p_seq=16 -ProcStop dt=17 -ProcStart dt=16724 p=1 p_seq=17 -GoUnblock dt=27 g=1 g_seq=59 stack=0 -GoStart dt=127 g=1 g_seq=60 -HeapAlloc dt=55 heapalloc_value=18617992 -HeapAlloc dt=64 heapalloc_value=18626184 -HeapAlloc dt=65 heapalloc_value=18634376 -HeapAlloc dt=61 heapalloc_value=18642568 -HeapAlloc dt=54 heapalloc_value=18650760 -HeapAlloc dt=66 heapalloc_value=18658952 -HeapAlloc dt=67 heapalloc_value=18667144 -HeapAlloc dt=54 heapalloc_value=18675336 -HeapAlloc dt=57 heapalloc_value=18683528 -HeapAlloc dt=45 heapalloc_value=18691720 -HeapAlloc dt=84 heapalloc_value=18699912 -HeapAlloc dt=26 heapalloc_value=18708104 -HeapAlloc dt=18 heapalloc_value=18716296 -HeapAlloc dt=15 heapalloc_value=18724488 -HeapAlloc dt=24 heapalloc_value=18732680 -HeapAlloc dt=26 heapalloc_value=18740872 -HeapAlloc dt=21 heapalloc_value=18749064 -HeapAlloc dt=15 heapalloc_value=18757256 -HeapAlloc dt=31 heapalloc_value=18765448 -HeapAlloc dt=7 heapalloc_value=18773640 -HeapAlloc dt=7 heapalloc_value=18781832 -HeapAlloc dt=113 heapalloc_value=18790024 -HeapAlloc dt=8 heapalloc_value=18798216 -HeapAlloc dt=6 heapalloc_value=18806408 -HeapAlloc dt=7 heapalloc_value=18814600 -HeapAlloc dt=6 heapalloc_value=18822792 -HeapAlloc dt=6 heapalloc_value=18830984 -HeapAlloc dt=7 heapalloc_value=18839176 -HeapAlloc dt=6 heapalloc_value=18847368 -HeapAlloc dt=6 heapalloc_value=18855560 -HeapAlloc dt=6 heapalloc_value=18863752 -HeapAlloc dt=6 heapalloc_value=18871944 -HeapAlloc dt=6 heapalloc_value=18880136 -HeapAlloc dt=6 heapalloc_value=18888328 -HeapAlloc dt=6 heapalloc_value=18896520 -HeapAlloc dt=7 heapalloc_value=18904712 -HeapAlloc dt=6 heapalloc_value=18912904 -HeapAlloc dt=38 heapalloc_value=18921096 -HeapAlloc dt=7 heapalloc_value=18929288 -HeapAlloc dt=6 heapalloc_value=18937480 -HeapAlloc dt=14 heapalloc_value=18945672 -HeapAlloc dt=6 heapalloc_value=18953864 -HeapAlloc dt=6 heapalloc_value=18962056 -HeapAlloc dt=6 heapalloc_value=18970248 -HeapAlloc dt=7 heapalloc_value=18978440 -HeapAlloc dt=6 heapalloc_value=18986632 -HeapAlloc dt=6 heapalloc_value=18994824 -HeapAlloc dt=13 heapalloc_value=19003016 -HeapAlloc dt=7 heapalloc_value=19011208 -HeapAlloc dt=6 heapalloc_value=19019400 -HeapAlloc dt=6 heapalloc_value=19027592 -HeapAlloc dt=6 heapalloc_value=19035784 -HeapAlloc dt=7 heapalloc_value=19043976 -HeapAlloc dt=6 heapalloc_value=19052168 -HeapAlloc dt=6 heapalloc_value=19060360 -HeapAlloc dt=6 heapalloc_value=19068552 -HeapAlloc dt=6 heapalloc_value=19076744 -HeapAlloc dt=7 heapalloc_value=19084936 -HeapAlloc dt=6 heapalloc_value=19093128 -HeapAlloc dt=6 heapalloc_value=19101320 -HeapAlloc dt=6 heapalloc_value=19109512 -HeapAlloc dt=7 heapalloc_value=19117704 -HeapAlloc dt=5 heapalloc_value=19125896 -HeapAlloc dt=7 heapalloc_value=19134088 -HeapAlloc dt=6 heapalloc_value=19142280 -HeapAlloc dt=6 heapalloc_value=19150472 -HeapAlloc dt=6 heapalloc_value=19158664 -HeapAlloc dt=6 heapalloc_value=19166856 -HeapAlloc dt=7 heapalloc_value=19175048 -HeapAlloc dt=6 heapalloc_value=19183240 -HeapAlloc dt=6 heapalloc_value=19191432 -HeapAlloc dt=6 heapalloc_value=19199624 -HeapAlloc dt=7 heapalloc_value=19207816 -HeapAlloc dt=6 heapalloc_value=19216008 -HeapAlloc dt=6 heapalloc_value=19224200 -HeapAlloc dt=6 heapalloc_value=19232392 -HeapAlloc dt=7 heapalloc_value=19240584 -HeapAlloc dt=6 heapalloc_value=19248776 -HeapAlloc dt=6 heapalloc_value=19256968 -HeapAlloc dt=6 heapalloc_value=19265160 -HeapAlloc dt=6 heapalloc_value=19273352 -HeapAlloc dt=6 heapalloc_value=19281544 -HeapAlloc dt=6 heapalloc_value=19289736 -HeapAlloc dt=7 heapalloc_value=19297928 -HeapAlloc dt=6 heapalloc_value=19306120 -HeapAlloc dt=62 heapalloc_value=19314312 -HeapAlloc dt=7 heapalloc_value=19322504 -HeapAlloc dt=6 heapalloc_value=19330696 -HeapAlloc dt=6 heapalloc_value=19338888 -HeapAlloc dt=35 heapalloc_value=19347080 -HeapAlloc dt=7 heapalloc_value=19355272 -HeapAlloc dt=6 heapalloc_value=19363464 -HeapAlloc dt=6 heapalloc_value=19371656 -HeapAlloc dt=6 heapalloc_value=19379848 -HeapAlloc dt=6 heapalloc_value=19388040 -HeapAlloc dt=6 heapalloc_value=19396232 -HeapAlloc dt=7 heapalloc_value=19404424 -HeapAlloc dt=6 heapalloc_value=19412616 -HeapAlloc dt=7 heapalloc_value=19420808 -HeapAlloc dt=6 heapalloc_value=19429000 -HeapAlloc dt=6 heapalloc_value=19437192 -HeapAlloc dt=6 heapalloc_value=19445384 -HeapAlloc dt=7 heapalloc_value=19453576 -HeapAlloc dt=6 heapalloc_value=19461768 -HeapAlloc dt=10 heapalloc_value=19469960 -HeapAlloc dt=6 heapalloc_value=19478152 -HeapAlloc dt=6 heapalloc_value=19486344 -HeapAlloc dt=6 heapalloc_value=19494536 -HeapAlloc dt=6 heapalloc_value=19502728 -HeapAlloc dt=7 heapalloc_value=19510920 -HeapAlloc dt=6 heapalloc_value=19519112 -HeapAlloc dt=6 heapalloc_value=19527304 -HeapAlloc dt=6 heapalloc_value=19535496 -HeapAlloc dt=6 heapalloc_value=19543688 -HeapAlloc dt=35 heapalloc_value=19551880 -HeapAlloc dt=7 heapalloc_value=19560072 -HeapAlloc dt=6 heapalloc_value=19568264 -HeapAlloc dt=6 heapalloc_value=19576456 -HeapAlloc dt=6 heapalloc_value=19584648 -HeapAlloc dt=7 heapalloc_value=19592840 -HeapAlloc dt=7 heapalloc_value=19601032 -HeapAlloc dt=6 heapalloc_value=19609224 -HeapAlloc dt=6 heapalloc_value=19617416 -HeapAlloc dt=6 heapalloc_value=19625608 -HeapAlloc dt=6 heapalloc_value=19633800 -GoBlock dt=12 reason_string=19 stack=21 -ProcStop dt=171 -ProcStart dt=17527 p=0 p_seq=28 -ProcStop dt=24 -ProcStart dt=1830 p=1 p_seq=20 -ProcStop dt=13 -ProcStart dt=16742 p=1 p_seq=21 -GoUnblock dt=20 g=1 g_seq=63 stack=0 -GoStart dt=121 g=1 g_seq=64 -HeapAlloc dt=62 heapalloc_value=20665992 -HeapAlloc dt=21 heapalloc_value=20674184 -HeapAlloc dt=25 heapalloc_value=20682376 -HeapAlloc dt=20 heapalloc_value=20690568 -HeapAlloc dt=12 heapalloc_value=20698760 -HeapAlloc dt=16 heapalloc_value=20706952 -HeapAlloc dt=15 heapalloc_value=20715144 -HeapAlloc dt=18 heapalloc_value=20723336 -HeapAlloc dt=12 heapalloc_value=20731528 -HeapAlloc dt=16 heapalloc_value=20739720 -HeapAlloc dt=12 heapalloc_value=20747912 -HeapAlloc dt=12 heapalloc_value=20756104 -HeapAlloc dt=12 heapalloc_value=20764296 -HeapAlloc dt=12 heapalloc_value=20772488 -HeapAlloc dt=9 heapalloc_value=20780680 -HeapAlloc dt=5 heapalloc_value=20788872 -HeapAlloc dt=6 heapalloc_value=20797064 -HeapAlloc dt=9 heapalloc_value=20805256 -HeapAlloc dt=5 heapalloc_value=20813448 -HeapAlloc dt=6 heapalloc_value=20821640 -HeapAlloc dt=5 heapalloc_value=20829832 -HeapAlloc dt=6 heapalloc_value=20838024 -HeapAlloc dt=15 heapalloc_value=20846216 -HeapAlloc dt=12 heapalloc_value=20854408 -HeapAlloc dt=11 heapalloc_value=20862600 -HeapAlloc dt=13 heapalloc_value=20870792 -HeapAlloc dt=5 heapalloc_value=20878984 -HeapAlloc dt=106 heapalloc_value=20887176 -HeapAlloc dt=8 heapalloc_value=20895368 -HeapAlloc dt=5 heapalloc_value=20903560 -HeapAlloc dt=6 heapalloc_value=20911752 -HeapAlloc dt=6 heapalloc_value=20919944 -HeapAlloc dt=5 heapalloc_value=20928136 -HeapAlloc dt=9 heapalloc_value=20936328 -HeapAlloc dt=6 heapalloc_value=20944520 -HeapAlloc dt=5 heapalloc_value=20952712 -HeapAlloc dt=6 heapalloc_value=20960904 -HeapAlloc dt=5 heapalloc_value=20969096 -HeapAlloc dt=6 heapalloc_value=20977288 -HeapAlloc dt=5 heapalloc_value=20985480 -HeapAlloc dt=5 heapalloc_value=20993672 -HeapAlloc dt=10 heapalloc_value=21001864 -HeapAlloc dt=6 heapalloc_value=21010056 -HeapAlloc dt=37 heapalloc_value=21018248 -HeapAlloc dt=7 heapalloc_value=21026440 -HeapAlloc dt=6 heapalloc_value=21034632 -HeapAlloc dt=34 heapalloc_value=21042824 -HeapAlloc dt=6 heapalloc_value=21051016 -HeapAlloc dt=6 heapalloc_value=21059208 -HeapAlloc dt=11 heapalloc_value=21067400 -HeapAlloc dt=6 heapalloc_value=21075592 -HeapAlloc dt=5 heapalloc_value=21083784 -HeapAlloc dt=6 heapalloc_value=21091976 -HeapAlloc dt=5 heapalloc_value=21100168 -HeapAlloc dt=9 heapalloc_value=21108360 -HeapAlloc dt=6 heapalloc_value=21116552 -HeapAlloc dt=6 heapalloc_value=21124744 -HeapAlloc dt=10 heapalloc_value=21132936 -HeapAlloc dt=5 heapalloc_value=21141128 -HeapAlloc dt=6 heapalloc_value=21149320 -HeapAlloc dt=5 heapalloc_value=21157512 -HeapAlloc dt=6 heapalloc_value=21165704 -HeapAlloc dt=5 heapalloc_value=21173896 -HeapAlloc dt=6 heapalloc_value=21182088 -HeapAlloc dt=5 heapalloc_value=21190280 -HeapAlloc dt=9 heapalloc_value=21198472 -HeapAlloc dt=6 heapalloc_value=21206664 -HeapAlloc dt=6 heapalloc_value=21214856 -HeapAlloc dt=6 heapalloc_value=21223048 -HeapAlloc dt=5 heapalloc_value=21231240 -HeapAlloc dt=6 heapalloc_value=21239432 -HeapAlloc dt=5 heapalloc_value=21247624 -HeapAlloc dt=6 heapalloc_value=21255816 -HeapAlloc dt=5 heapalloc_value=21264008 -HeapAlloc dt=6 heapalloc_value=21272200 -HeapAlloc dt=5 heapalloc_value=21280392 -HeapAlloc dt=6 heapalloc_value=21288584 -HeapAlloc dt=5 heapalloc_value=21296776 -HeapAlloc dt=6 heapalloc_value=21304968 -HeapAlloc dt=5 heapalloc_value=21313160 -HeapAlloc dt=6 heapalloc_value=21321352 -HeapAlloc dt=6 heapalloc_value=21329544 -HeapAlloc dt=6 heapalloc_value=21337736 -HeapAlloc dt=6 heapalloc_value=21345928 -HeapAlloc dt=6 heapalloc_value=21354120 -HeapAlloc dt=5 heapalloc_value=21362312 -HeapAlloc dt=6 heapalloc_value=21370504 -HeapAlloc dt=6 heapalloc_value=21378696 -HeapAlloc dt=6 heapalloc_value=21386888 -HeapAlloc dt=5 heapalloc_value=21395080 -HeapAlloc dt=6 heapalloc_value=21403272 -HeapAlloc dt=96 heapalloc_value=21411464 -HeapAlloc dt=7 heapalloc_value=21419656 -HeapAlloc dt=6 heapalloc_value=21427848 -HeapAlloc dt=21 heapalloc_value=21968520 -HeapAlloc dt=1835 heapalloc_value=21976712 -HeapAlloc dt=11 heapalloc_value=21984904 -HeapAlloc dt=8 heapalloc_value=21993096 -HeapAlloc dt=7 heapalloc_value=22001288 -HeapAlloc dt=8 heapalloc_value=22009480 -HeapAlloc dt=7 heapalloc_value=22017672 -HeapAlloc dt=8 heapalloc_value=22025864 -HeapAlloc dt=7 heapalloc_value=22034056 -HeapAlloc dt=8 heapalloc_value=22042248 -HeapAlloc dt=7 heapalloc_value=22050440 -HeapAlloc dt=7 heapalloc_value=22058632 -HeapAlloc dt=8 heapalloc_value=22066824 -HeapAlloc dt=7 heapalloc_value=22075016 -HeapAlloc dt=8 heapalloc_value=22083208 -HeapAlloc dt=7 heapalloc_value=22091400 -HeapAlloc dt=7 heapalloc_value=22099592 -HeapAlloc dt=14 heapalloc_value=22107784 -HeapAlloc dt=5 heapalloc_value=22115976 -HeapAlloc dt=6 heapalloc_value=22124168 -HeapAlloc dt=6 heapalloc_value=22132360 -HeapAlloc dt=5 heapalloc_value=22140552 -HeapAlloc dt=6 heapalloc_value=22148744 -HeapAlloc dt=5 heapalloc_value=22156936 -HeapAlloc dt=6 heapalloc_value=22165128 -HeapAlloc dt=6 heapalloc_value=22173320 -HeapAlloc dt=38 heapalloc_value=22181512 -HeapAlloc dt=7 heapalloc_value=22189704 -HeapAlloc dt=5 heapalloc_value=22197896 -HeapAlloc dt=6 heapalloc_value=22206088 -HeapAlloc dt=6 heapalloc_value=22214280 -HeapAlloc dt=5 heapalloc_value=22222472 -GoBlock dt=9 reason_string=19 stack=21 -ProcStop dt=163 -ProcStart dt=16841 p=0 p_seq=30 -ProcStop dt=23 -ProcStart dt=1498 p=1 p_seq=24 -ProcStop dt=11 -ProcStart dt=16726 p=1 p_seq=25 -GoUnblock dt=19 g=1 g_seq=67 stack=0 -GoStart dt=117 g=1 g_seq=68 -HeapAlloc dt=46 heapalloc_value=23254664 -HeapAlloc dt=19 heapalloc_value=23262856 -HeapAlloc dt=20 heapalloc_value=23271048 -HeapAlloc dt=16 heapalloc_value=23279240 -HeapAlloc dt=12 heapalloc_value=23287432 -HeapAlloc dt=12 heapalloc_value=23295624 -HeapAlloc dt=13 heapalloc_value=23303816 -HeapAlloc dt=15 heapalloc_value=23312008 -HeapAlloc dt=13 heapalloc_value=23320200 -HeapAlloc dt=13 heapalloc_value=23328392 -HeapAlloc dt=12 heapalloc_value=23336584 -HeapAlloc dt=12 heapalloc_value=23344776 -HeapAlloc dt=5 heapalloc_value=23352968 -HeapAlloc dt=100 heapalloc_value=23361160 -HeapAlloc dt=14 heapalloc_value=23369352 -HeapAlloc dt=16 heapalloc_value=23377544 -HeapAlloc dt=13 heapalloc_value=23385736 -HeapAlloc dt=5 heapalloc_value=23393928 -HeapAlloc dt=6 heapalloc_value=23402120 -HeapAlloc dt=9 heapalloc_value=23410312 -HeapAlloc dt=6 heapalloc_value=23418504 -HeapAlloc dt=6 heapalloc_value=23426696 -HeapAlloc dt=5 heapalloc_value=23434888 -HeapAlloc dt=6 heapalloc_value=23443080 -HeapAlloc dt=5 heapalloc_value=23451272 -HeapAlloc dt=6 heapalloc_value=23459464 -HeapAlloc dt=6 heapalloc_value=23467656 -HeapAlloc dt=6 heapalloc_value=23475848 -HeapAlloc dt=6 heapalloc_value=23484040 -HeapAlloc dt=5 heapalloc_value=23492232 -HeapAlloc dt=6 heapalloc_value=23500424 -HeapAlloc dt=5 heapalloc_value=23508616 -HeapAlloc dt=83 heapalloc_value=23516808 -HeapAlloc dt=8 heapalloc_value=23525000 -HeapAlloc dt=5 heapalloc_value=23533192 -HeapAlloc dt=6 heapalloc_value=23541384 -HeapAlloc dt=6 heapalloc_value=23549576 -HeapAlloc dt=5 heapalloc_value=23557768 -HeapAlloc dt=7 heapalloc_value=23565960 -HeapAlloc dt=7 heapalloc_value=23574152 -HeapAlloc dt=6 heapalloc_value=23582344 -HeapAlloc dt=5 heapalloc_value=23590536 -HeapAlloc dt=6 heapalloc_value=23598728 -HeapAlloc dt=6 heapalloc_value=23606920 -HeapAlloc dt=5 heapalloc_value=23615112 -HeapAlloc dt=6 heapalloc_value=23623304 -HeapAlloc dt=6 heapalloc_value=23631496 -HeapAlloc dt=5 heapalloc_value=23639688 -HeapAlloc dt=38 heapalloc_value=23647880 -HeapAlloc dt=8 heapalloc_value=23656072 -HeapAlloc dt=37 heapalloc_value=23664264 -HeapAlloc dt=6 heapalloc_value=23672456 -HeapAlloc dt=6 heapalloc_value=23680648 -HeapAlloc dt=6 heapalloc_value=23688840 -HeapAlloc dt=6 heapalloc_value=23697032 -HeapAlloc dt=6 heapalloc_value=23705224 -HeapAlloc dt=5 heapalloc_value=23713416 -HeapAlloc dt=6 heapalloc_value=23721608 -HeapAlloc dt=10 heapalloc_value=23729800 -HeapAlloc dt=5 heapalloc_value=23737992 -HeapAlloc dt=6 heapalloc_value=23746184 -HeapAlloc dt=6 heapalloc_value=23754376 -HeapAlloc dt=5 heapalloc_value=23762568 -HeapAlloc dt=6 heapalloc_value=23770760 -HeapAlloc dt=6 heapalloc_value=23778952 -HeapAlloc dt=5 heapalloc_value=23787144 -HeapAlloc dt=9 heapalloc_value=23795336 -HeapAlloc dt=6 heapalloc_value=23803528 -HeapAlloc dt=6 heapalloc_value=23811720 -HeapAlloc dt=5 heapalloc_value=23819912 -HeapAlloc dt=6 heapalloc_value=23828104 -HeapAlloc dt=6 heapalloc_value=23836296 -HeapAlloc dt=6 heapalloc_value=23844488 -HeapAlloc dt=5 heapalloc_value=23852680 -HeapAlloc dt=6 heapalloc_value=23860872 -HeapAlloc dt=6 heapalloc_value=23869064 -HeapAlloc dt=6 heapalloc_value=23877256 -HeapAlloc dt=6 heapalloc_value=23885448 -HeapAlloc dt=5 heapalloc_value=23893640 -HeapAlloc dt=6 heapalloc_value=23901832 -HeapAlloc dt=5 heapalloc_value=23910024 -HeapAlloc dt=6 heapalloc_value=23918216 -HeapAlloc dt=6 heapalloc_value=23926408 -HeapAlloc dt=6 heapalloc_value=23934600 -HeapAlloc dt=6 heapalloc_value=23942792 -HeapAlloc dt=5 heapalloc_value=23950984 -HeapAlloc dt=6 heapalloc_value=23959176 -HeapAlloc dt=5 heapalloc_value=23967368 -HeapAlloc dt=6 heapalloc_value=23975560 -HeapAlloc dt=7 heapalloc_value=23983752 -HeapAlloc dt=5 heapalloc_value=23991944 -HeapAlloc dt=6 heapalloc_value=24000136 -HeapAlloc dt=5 heapalloc_value=24008328 -HeapAlloc dt=6 heapalloc_value=24016520 -HeapAlloc dt=6 heapalloc_value=24024712 -HeapAlloc dt=5 heapalloc_value=24032904 -HeapAlloc dt=50 heapalloc_value=24041096 -HeapAlloc dt=7 heapalloc_value=24049288 -HeapAlloc dt=6 heapalloc_value=24057480 -HeapAlloc dt=5 heapalloc_value=24065672 -HeapAlloc dt=34 heapalloc_value=24073864 -HeapAlloc dt=7 heapalloc_value=24082056 -HeapAlloc dt=6 heapalloc_value=24090248 -HeapAlloc dt=6 heapalloc_value=24098440 -HeapAlloc dt=6 heapalloc_value=24106632 -HeapAlloc dt=5 heapalloc_value=24114824 -HeapAlloc dt=6 heapalloc_value=24123016 -HeapAlloc dt=6 heapalloc_value=24131208 -HeapAlloc dt=6 heapalloc_value=24139400 -HeapAlloc dt=6 heapalloc_value=24147592 -HeapAlloc dt=5 heapalloc_value=24155784 -HeapAlloc dt=6 heapalloc_value=24163976 -HeapAlloc dt=5 heapalloc_value=24172168 -HeapAlloc dt=6 heapalloc_value=24180360 -HeapAlloc dt=365 heapalloc_value=24188552 -HeapAlloc dt=13 heapalloc_value=24196744 -HeapAlloc dt=6 heapalloc_value=24204936 -HeapAlloc dt=6 heapalloc_value=24213128 -HeapAlloc dt=5 heapalloc_value=24221320 -HeapAlloc dt=6 heapalloc_value=24229512 -HeapAlloc dt=6 heapalloc_value=24237704 -HeapAlloc dt=6 heapalloc_value=24245896 -HeapAlloc dt=6 heapalloc_value=24254088 -HeapAlloc dt=6 heapalloc_value=24262280 -HeapAlloc dt=6 heapalloc_value=24270472 -GoBlock dt=10 reason_string=19 stack=21 -ProcStop dt=157 -ProcStart dt=12778 p=1 p_seq=27 -GoUnblock dt=12 g=1 g_seq=69 stack=0 -GoStart dt=143 g=1 g_seq=70 -HeapAlloc dt=61 heapalloc_value=24278664 -HeapAlloc dt=11 heapalloc_value=24286856 -HeapAlloc dt=5 heapalloc_value=24295048 -HeapAlloc dt=6 heapalloc_value=24303240 -HeapAlloc dt=5 heapalloc_value=24311432 -HeapAlloc dt=6 heapalloc_value=24319624 -HeapAlloc dt=6 heapalloc_value=24327816 -HeapAlloc dt=6 heapalloc_value=24336008 -HeapAlloc dt=7 heapalloc_value=24344200 -HeapAlloc dt=5 heapalloc_value=24352392 -HeapAlloc dt=7 heapalloc_value=24360584 -HeapAlloc dt=5 heapalloc_value=24368776 -HeapAlloc dt=6 heapalloc_value=24376968 -HeapAlloc dt=6 heapalloc_value=24385160 -HeapAlloc dt=5 heapalloc_value=24393352 -HeapAlloc dt=6 heapalloc_value=24401544 -HeapAlloc dt=6 heapalloc_value=24409736 -HeapAlloc dt=6 heapalloc_value=24417928 -HeapAlloc dt=6 heapalloc_value=24426120 -HeapAlloc dt=5 heapalloc_value=24434312 -HeapAlloc dt=6 heapalloc_value=24442504 -HeapAlloc dt=6 heapalloc_value=24450696 -HeapAlloc dt=6 heapalloc_value=24458888 -HeapAlloc dt=6 heapalloc_value=24467080 -HeapAlloc dt=5 heapalloc_value=24475272 -HeapAlloc dt=6 heapalloc_value=24483464 -HeapAlloc dt=5 heapalloc_value=24491656 -HeapAlloc dt=6 heapalloc_value=24499848 -HeapAlloc dt=6 heapalloc_value=24508040 -HeapAlloc dt=5 heapalloc_value=24516232 -HeapAlloc dt=6 heapalloc_value=24524424 -HeapAlloc dt=6 heapalloc_value=24532616 -HeapAlloc dt=5 heapalloc_value=24540808 -HeapAlloc dt=6 heapalloc_value=24549000 -HeapAlloc dt=5 heapalloc_value=24557192 -HeapAlloc dt=49 heapalloc_value=24565384 -HeapAlloc dt=7 heapalloc_value=24573576 -HeapAlloc dt=5 heapalloc_value=24581768 -HeapAlloc dt=6 heapalloc_value=24589960 -HeapAlloc dt=17 heapalloc_value=24598152 -HeapAlloc dt=12 heapalloc_value=24606344 -HeapAlloc dt=5 heapalloc_value=24614536 -HeapAlloc dt=6 heapalloc_value=24622728 -HeapAlloc dt=5 heapalloc_value=24630920 -HeapAlloc dt=6 heapalloc_value=24639112 -HeapAlloc dt=6 heapalloc_value=24647304 -HeapAlloc dt=5 heapalloc_value=24655496 -HeapAlloc dt=6 heapalloc_value=24663688 -HeapAlloc dt=37 heapalloc_value=24671880 -HeapAlloc dt=6 heapalloc_value=24680072 -HeapAlloc dt=6 heapalloc_value=24688264 -HeapAlloc dt=36 heapalloc_value=24696456 -HeapAlloc dt=7 heapalloc_value=24704648 -HeapAlloc dt=12 heapalloc_value=24712840 -HeapAlloc dt=6 heapalloc_value=24721032 -HeapAlloc dt=17 heapalloc_value=24729224 -HeapAlloc dt=5 heapalloc_value=24737416 -HeapAlloc dt=6 heapalloc_value=24745608 -HeapAlloc dt=19 heapalloc_value=24753800 -HeapAlloc dt=5 heapalloc_value=24761992 -HeapAlloc dt=6 heapalloc_value=24770184 -HeapAlloc dt=79 heapalloc_value=24778376 -HeapAlloc dt=7 heapalloc_value=24786568 -HeapAlloc dt=6 heapalloc_value=24794760 -HeapAlloc dt=5 heapalloc_value=24802952 -HeapAlloc dt=6 heapalloc_value=24811144 -HeapAlloc dt=6 heapalloc_value=24819336 -HeapAlloc dt=6 heapalloc_value=24827528 -HeapAlloc dt=5 heapalloc_value=24835720 -HeapAlloc dt=6 heapalloc_value=24843912 -HeapAlloc dt=6 heapalloc_value=24852104 -HeapAlloc dt=6 heapalloc_value=24860296 -HeapAlloc dt=6 heapalloc_value=24868488 -HeapAlloc dt=5 heapalloc_value=24876680 -HeapAlloc dt=6 heapalloc_value=24884872 -HeapAlloc dt=6 heapalloc_value=24893064 -HeapAlloc dt=5 heapalloc_value=24901256 -HeapAlloc dt=6 heapalloc_value=24909448 -HeapAlloc dt=6 heapalloc_value=24917640 -HeapAlloc dt=5 heapalloc_value=24925832 -HeapAlloc dt=6 heapalloc_value=24934024 -HeapAlloc dt=5 heapalloc_value=24942216 -HeapAlloc dt=6 heapalloc_value=24950408 -HeapAlloc dt=6 heapalloc_value=24958600 -HeapAlloc dt=6 heapalloc_value=24966792 -HeapAlloc dt=5 heapalloc_value=24974984 -HeapAlloc dt=6 heapalloc_value=24983176 -HeapAlloc dt=6 heapalloc_value=24991368 -HeapAlloc dt=6 heapalloc_value=24999560 -HeapAlloc dt=5 heapalloc_value=25007752 -HeapAlloc dt=6 heapalloc_value=25015944 -HeapAlloc dt=5 heapalloc_value=25024136 -HeapAlloc dt=6 heapalloc_value=25032328 -HeapAlloc dt=6 heapalloc_value=25040520 -HeapAlloc dt=6 heapalloc_value=25048712 -HeapAlloc dt=6 heapalloc_value=25056904 -HeapAlloc dt=5 heapalloc_value=25065096 -HeapAlloc dt=6 heapalloc_value=25073288 -HeapAlloc dt=6 heapalloc_value=25081480 -HeapAlloc dt=46 heapalloc_value=25089672 -HeapAlloc dt=7 heapalloc_value=25097864 -HeapAlloc dt=6 heapalloc_value=25106056 -HeapAlloc dt=5 heapalloc_value=25114248 -HeapAlloc dt=36 heapalloc_value=25122440 -HeapAlloc dt=7 heapalloc_value=25130632 -HeapAlloc dt=6 heapalloc_value=25138824 -HeapAlloc dt=6 heapalloc_value=25147016 -HeapAlloc dt=5 heapalloc_value=25155208 -HeapAlloc dt=6 heapalloc_value=25163400 -HeapAlloc dt=5 heapalloc_value=25171592 -HeapAlloc dt=6 heapalloc_value=25179784 -HeapAlloc dt=5 heapalloc_value=25187976 -HeapAlloc dt=6 heapalloc_value=25196168 -HeapAlloc dt=5 heapalloc_value=25204360 -HeapAlloc dt=6 heapalloc_value=25212552 -HeapAlloc dt=5 heapalloc_value=25220744 -HeapAlloc dt=6 heapalloc_value=25228936 -HeapAlloc dt=10 heapalloc_value=25237128 -HeapAlloc dt=5 heapalloc_value=25245320 -HeapAlloc dt=6 heapalloc_value=25253512 -HeapAlloc dt=5 heapalloc_value=25261704 -HeapAlloc dt=6 heapalloc_value=25269896 -HeapAlloc dt=6 heapalloc_value=25278088 -HeapAlloc dt=5 heapalloc_value=25286280 -HeapAlloc dt=6 heapalloc_value=25294472 -GoBlock dt=10 reason_string=19 stack=21 -ProcStop dt=14 -ProcStart dt=7152 p=1 p_seq=29 -GoStart dt=199 g=37 g_seq=1 -GoStop dt=306782 reason_string=16 stack=50 -GoStart dt=57 g=37 g_seq=2 -GoStop dt=315218 reason_string=16 stack=50 -GoStart dt=17 g=37 g_seq=3 -GoDestroy dt=159214 -ProcStop dt=60 -EventBatch gen=1 m=1709041 time=7689670150297 size=5255 -ProcStart dt=316 p=3 p_seq=1 -ProcStop dt=37 -ProcStart dt=311299 p=1 p_seq=5 -ProcStop dt=17 -ProcStart dt=16759 p=1 p_seq=6 -GoUnblock dt=47 g=1 g_seq=3 stack=0 -GoStart dt=137 g=1 g_seq=4 -HeapAlloc dt=56 heapalloc_value=2809856 -HeapAlloc dt=29 heapalloc_value=2818048 -HeapAlloc dt=19 heapalloc_value=2826240 -HeapAlloc dt=22 heapalloc_value=2834432 -HeapAlloc dt=91 heapalloc_value=2842624 -HeapAlloc dt=21 heapalloc_value=2850816 -HeapAlloc dt=24 heapalloc_value=2859008 -HeapAlloc dt=7 heapalloc_value=2867200 -HeapAlloc dt=15 heapalloc_value=2875392 -HeapAlloc dt=16 heapalloc_value=2883584 -HeapAlloc dt=12 heapalloc_value=2899968 -HeapAlloc dt=9 heapalloc_value=2908160 -HeapAlloc dt=16 heapalloc_value=2916352 -HeapAlloc dt=15 heapalloc_value=2924544 -HeapAlloc dt=12 heapalloc_value=2932736 -HeapAlloc dt=12 heapalloc_value=2940928 -HeapAlloc dt=7 heapalloc_value=2949120 -HeapAlloc dt=18 heapalloc_value=2957312 -HeapAlloc dt=14 heapalloc_value=2965504 -HeapAlloc dt=12 heapalloc_value=2973696 -HeapAlloc dt=13 heapalloc_value=2981888 -HeapAlloc dt=12 heapalloc_value=2990080 -HeapAlloc dt=11 heapalloc_value=2998272 -HeapAlloc dt=12 heapalloc_value=3006464 -HeapAlloc dt=13 heapalloc_value=3014656 -HeapAlloc dt=12 heapalloc_value=3022848 -HeapAlloc dt=11 heapalloc_value=3031040 -HeapAlloc dt=11 heapalloc_value=3039232 -HeapAlloc dt=13 heapalloc_value=3047424 -HeapAlloc dt=11 heapalloc_value=3055616 -HeapAlloc dt=20 heapalloc_value=3063808 -HeapAlloc dt=12 heapalloc_value=3072000 -HeapAlloc dt=12 heapalloc_value=3080192 -HeapAlloc dt=11 heapalloc_value=3088384 -HeapAlloc dt=12 heapalloc_value=3096576 -HeapAlloc dt=11 heapalloc_value=3104768 -HeapAlloc dt=11 heapalloc_value=3112960 -HeapAlloc dt=12 heapalloc_value=3121152 -HeapAlloc dt=11 heapalloc_value=3129344 -HeapAlloc dt=15 heapalloc_value=3137536 -HeapAlloc dt=15 heapalloc_value=3145728 -HeapAlloc dt=18 heapalloc_value=3153920 -HeapAlloc dt=13 heapalloc_value=3162112 -HeapAlloc dt=12 heapalloc_value=3170304 -HeapAlloc dt=16 heapalloc_value=3178496 -HeapAlloc dt=11 heapalloc_value=3186688 -HeapAlloc dt=12 heapalloc_value=3194880 -HeapAlloc dt=11 heapalloc_value=3203072 -HeapAlloc dt=13 heapalloc_value=3211264 -HeapAlloc dt=12 heapalloc_value=3219456 -HeapAlloc dt=11 heapalloc_value=3227648 -HeapAlloc dt=13 heapalloc_value=3244032 -HeapAlloc dt=734 heapalloc_value=3252224 -HeapAlloc dt=16 heapalloc_value=3260416 -HeapAlloc dt=8 heapalloc_value=3268608 -HeapAlloc dt=5 heapalloc_value=3276800 -HeapAlloc dt=8 heapalloc_value=3284992 -HeapAlloc dt=88 heapalloc_value=3293184 -HeapAlloc dt=7 heapalloc_value=3301376 -HeapAlloc dt=5 heapalloc_value=3309568 -HeapAlloc dt=6 heapalloc_value=3317760 -HeapAlloc dt=5 heapalloc_value=3325952 -HeapAlloc dt=5 heapalloc_value=3334144 -HeapAlloc dt=5 heapalloc_value=3342336 -HeapAlloc dt=5 heapalloc_value=3350528 -HeapAlloc dt=6 heapalloc_value=3358720 -HeapAlloc dt=5 heapalloc_value=3366912 -HeapAlloc dt=5 heapalloc_value=3375104 -HeapAlloc dt=7 heapalloc_value=3383296 -HeapAlloc dt=6 heapalloc_value=3391488 -HeapAlloc dt=5 heapalloc_value=3399680 -HeapAlloc dt=5 heapalloc_value=3407872 -HeapAlloc dt=5 heapalloc_value=3416064 -HeapAlloc dt=6 heapalloc_value=3424256 -HeapAlloc dt=5 heapalloc_value=3432448 -HeapAlloc dt=5 heapalloc_value=3440640 -HeapAlloc dt=5 heapalloc_value=3448832 -HeapAlloc dt=6 heapalloc_value=3457024 -HeapAlloc dt=5 heapalloc_value=3465216 -HeapAlloc dt=38 heapalloc_value=3473408 -HeapAlloc dt=6 heapalloc_value=3481600 -HeapAlloc dt=5 heapalloc_value=3489792 -HeapAlloc dt=6 heapalloc_value=3497984 -HeapAlloc dt=5 heapalloc_value=3506176 -HeapAlloc dt=6 heapalloc_value=3514368 -HeapAlloc dt=5 heapalloc_value=3522560 -HeapAlloc dt=5 heapalloc_value=3530752 -HeapAlloc dt=5 heapalloc_value=3538944 -HeapAlloc dt=5 heapalloc_value=3547136 -HeapAlloc dt=6 heapalloc_value=3555328 -HeapAlloc dt=5 heapalloc_value=3563520 -HeapAlloc dt=5 heapalloc_value=3571712 -HeapAlloc dt=5 heapalloc_value=3579904 -HeapAlloc dt=5 heapalloc_value=3588096 -HeapAlloc dt=6 heapalloc_value=3596288 -HeapAlloc dt=10 heapalloc_value=3678208 -HeapAlloc dt=2433 heapalloc_value=3686400 -HeapAlloc dt=6 heapalloc_value=3694592 -HeapAlloc dt=6 heapalloc_value=3702784 -HeapAlloc dt=6 heapalloc_value=3710976 -HeapAlloc dt=5 heapalloc_value=3719168 -HeapAlloc dt=6 heapalloc_value=3727360 -HeapAlloc dt=5 heapalloc_value=3735552 -HeapAlloc dt=5 heapalloc_value=3743744 -HeapAlloc dt=5 heapalloc_value=3751936 -HeapAlloc dt=6 heapalloc_value=3760128 -HeapAlloc dt=5 heapalloc_value=3768320 -HeapAlloc dt=11 heapalloc_value=3776512 -HeapAlloc dt=31 heapalloc_value=3784704 -HeapAlloc dt=7 heapalloc_value=3792896 -HeapAlloc dt=6 heapalloc_value=3801088 -HeapAlloc dt=5 heapalloc_value=3809280 -HeapAlloc dt=6 heapalloc_value=3817472 -HeapAlloc dt=5 heapalloc_value=3825664 -HeapAlloc dt=5 heapalloc_value=3833856 -HeapAlloc dt=6 heapalloc_value=3842048 -HeapAlloc dt=5 heapalloc_value=3850240 -HeapAlloc dt=5 heapalloc_value=3858432 -HeapAlloc dt=6 heapalloc_value=3866624 -HeapAlloc dt=5 heapalloc_value=3874816 -HeapAlloc dt=5 heapalloc_value=3883008 -HeapAlloc dt=78 heapalloc_value=3891200 -HeapAlloc dt=7 heapalloc_value=3899392 -HeapAlloc dt=6 heapalloc_value=3907584 -HeapAlloc dt=5 heapalloc_value=3915776 -HeapAlloc dt=5 heapalloc_value=3923968 -HeapAlloc dt=5 heapalloc_value=3932160 -HeapAlloc dt=6 heapalloc_value=3940352 -HeapAlloc dt=5 heapalloc_value=3948544 -HeapAlloc dt=5 heapalloc_value=3956736 -HeapAlloc dt=5 heapalloc_value=3964928 -HeapAlloc dt=5 heapalloc_value=3973120 -HeapAlloc dt=6 heapalloc_value=3981312 -HeapAlloc dt=5 heapalloc_value=3989504 -HeapAlloc dt=6 heapalloc_value=3997696 -GCBegin dt=38 gc_seq=1 stack=22 -HeapAlloc dt=42 heapalloc_value=4005888 -HeapAlloc dt=14 heapalloc_value=4014080 -GoCreate dt=73 new_g=18 new_stack=23 stack=24 -GoBlock dt=235 reason_string=12 stack=25 -GoStart dt=11 g=18 g_seq=1 -HeapAlloc dt=16 heapalloc_value=4022272 -GoUnblock dt=15 g=1 g_seq=5 stack=26 -GoBlock dt=9 reason_string=15 stack=27 -GoStart dt=12 g=1 g_seq=6 -GoCreate dt=44 new_g=19 new_stack=23 stack=24 -GoBlock dt=4 reason_string=12 stack=25 -GoStart dt=3 g=19 g_seq=1 -GoUnblock dt=5 g=1 g_seq=7 stack=26 -GoBlock dt=2 reason_string=15 stack=27 -GoStart dt=2 g=1 g_seq=8 -GoCreate dt=8 new_g=20 new_stack=23 stack=24 -GoBlock dt=3 reason_string=12 stack=25 -GoStart dt=2 g=20 g_seq=1 -GoUnblock dt=3 g=1 g_seq=9 stack=26 -GoBlock dt=1 reason_string=15 stack=27 -GoStart dt=2 g=1 g_seq=10 -GoCreate dt=6 new_g=21 new_stack=23 stack=24 -GoBlock dt=3 reason_string=12 stack=25 -GoStart dt=1 g=21 g_seq=1 -GoUnblock dt=6 g=1 g_seq=11 stack=26 -GoBlock dt=1 reason_string=15 stack=27 -GoStart dt=8 g=1 g_seq=12 -GoCreate dt=7 new_g=22 new_stack=23 stack=24 -GoBlock dt=2 reason_string=12 stack=25 -GoStart dt=2 g=22 g_seq=1 -GoUnblock dt=2 g=1 g_seq=13 stack=26 -GoBlock dt=6 reason_string=15 stack=27 -GoStart dt=4 g=1 g_seq=14 -GoCreate dt=15 new_g=23 new_stack=23 stack=24 -GoBlock dt=166 reason_string=12 stack=25 -GoStart dt=4 g=23 g_seq=1 -GoUnblock dt=3 g=1 g_seq=15 stack=26 -GoBlock dt=3 reason_string=15 stack=27 -GoStart dt=3 g=1 g_seq=16 -HeapAlloc dt=18 heapalloc_value=4030464 -GoCreate dt=11 new_g=24 new_stack=23 stack=24 -GoBlock dt=3 reason_string=12 stack=25 -GoStart dt=1 g=24 g_seq=1 -GoUnblock dt=3 g=1 g_seq=17 stack=26 -GoBlock dt=2 reason_string=15 stack=27 -GoStart dt=1 g=1 g_seq=18 -GoCreate dt=6 new_g=25 new_stack=23 stack=24 -GoBlock dt=3 reason_string=12 stack=25 -GoStart dt=1 g=25 g_seq=1 -GoUnblock dt=2 g=1 g_seq=19 stack=26 -GoBlock dt=2 reason_string=15 stack=27 -GoStart dt=1 g=1 g_seq=20 -STWBegin dt=118 kind_string=22 stack=28 -GoStatus dt=1398 g=4 m=18446744073709551615 gstatus=4 -GoUnblock dt=83 g=4 g_seq=1 stack=29 -ProcsChange dt=91 procs_value=8 stack=30 -STWEnd dt=31 -GCMarkAssistBegin dt=149 stack=31 -GCMarkAssistEnd dt=1458 -GoBlock dt=23 reason_string=19 stack=21 -GoStart dt=166 g=4 g_seq=2 -GoBlock dt=22 reason_string=15 stack=32 -GoUnblock dt=35 g=23 g_seq=2 stack=0 -GoStart dt=4 g=23 g_seq=3 -GoLabel dt=1 label_string=4 -GoBlock dt=441 reason_string=15 stack=27 -ProcStop dt=23 -ProcStart dt=16781 p=0 p_seq=6 -GoUnblock dt=28 g=1 g_seq=27 stack=0 -GoStart dt=162 g=1 g_seq=28 -HeapAlloc dt=69 heapalloc_value=4663024 -HeapAlloc dt=23 heapalloc_value=4671216 -HeapAlloc dt=15 heapalloc_value=4679408 -HeapAlloc dt=10 heapalloc_value=4687600 -HeapAlloc dt=12 heapalloc_value=4695792 -HeapAlloc dt=8 heapalloc_value=4703984 -HeapAlloc dt=6 heapalloc_value=4712176 -HeapAlloc dt=12 heapalloc_value=4720368 -HeapAlloc dt=12 heapalloc_value=4728560 -HeapAlloc dt=12 heapalloc_value=4736752 -HeapAlloc dt=15 heapalloc_value=4744944 -HeapAlloc dt=9 heapalloc_value=4753136 -HeapAlloc dt=9 heapalloc_value=4761328 -HeapAlloc dt=7 heapalloc_value=4769520 -HeapAlloc dt=8 heapalloc_value=4777712 -HeapAlloc dt=9 heapalloc_value=4785904 -HeapAlloc dt=112 heapalloc_value=4794096 -HeapAlloc dt=7 heapalloc_value=4802288 -HeapAlloc dt=9 heapalloc_value=4810480 -HeapAlloc dt=13 heapalloc_value=4818672 -HeapAlloc dt=14 heapalloc_value=4826864 -HeapAlloc dt=6 heapalloc_value=4835056 -HeapAlloc dt=5 heapalloc_value=4843248 -HeapAlloc dt=6 heapalloc_value=4851440 -HeapAlloc dt=14 heapalloc_value=4859632 -HeapAlloc dt=10 heapalloc_value=4867824 -HeapAlloc dt=10 heapalloc_value=4876016 -HeapAlloc dt=6 heapalloc_value=4884208 -HeapAlloc dt=9 heapalloc_value=4892400 -HeapAlloc dt=72 heapalloc_value=4900592 -HeapAlloc dt=6 heapalloc_value=4908784 -HeapAlloc dt=5 heapalloc_value=4916976 -HeapAlloc dt=6 heapalloc_value=4925168 -HeapAlloc dt=6 heapalloc_value=4933360 -HeapAlloc dt=9 heapalloc_value=4941552 -HeapAlloc dt=46 heapalloc_value=4949744 -HeapAlloc dt=10 heapalloc_value=4957936 -HeapAlloc dt=6 heapalloc_value=4966128 -HeapAlloc dt=6 heapalloc_value=4974320 -HeapAlloc dt=6 heapalloc_value=4982512 -HeapAlloc dt=5 heapalloc_value=4990704 -HeapAlloc dt=6 heapalloc_value=4998896 -HeapAlloc dt=45 heapalloc_value=5007088 -HeapAlloc dt=6 heapalloc_value=5015280 -HeapAlloc dt=9 heapalloc_value=5023472 -HeapAlloc dt=6 heapalloc_value=5031664 -HeapAlloc dt=5 heapalloc_value=5039856 -HeapAlloc dt=6 heapalloc_value=5048048 -HeapAlloc dt=6 heapalloc_value=5056240 -HeapAlloc dt=15 heapalloc_value=5138160 -HeapAlloc dt=81 heapalloc_value=5146352 -HeapAlloc dt=6 heapalloc_value=5154544 -HeapAlloc dt=6 heapalloc_value=5162736 -HeapAlloc dt=5 heapalloc_value=5170928 -HeapAlloc dt=6 heapalloc_value=5179120 -HeapAlloc dt=5 heapalloc_value=5187312 -HeapAlloc dt=6 heapalloc_value=5195504 -HeapAlloc dt=7 heapalloc_value=5203696 -HeapAlloc dt=5 heapalloc_value=5211888 -HeapAlloc dt=6 heapalloc_value=5220080 -HeapAlloc dt=6 heapalloc_value=5228272 -HeapAlloc dt=37 heapalloc_value=5236464 -HeapAlloc dt=7 heapalloc_value=5244656 -HeapAlloc dt=6 heapalloc_value=5252848 -HeapAlloc dt=5 heapalloc_value=5261040 -HeapAlloc dt=8 heapalloc_value=5269232 -HeapAlloc dt=6 heapalloc_value=5277424 -HeapAlloc dt=6 heapalloc_value=5285616 -HeapAlloc dt=5 heapalloc_value=5293808 -HeapAlloc dt=7 heapalloc_value=5302000 -HeapAlloc dt=5 heapalloc_value=5310192 -HeapAlloc dt=5 heapalloc_value=5318384 -HeapAlloc dt=6 heapalloc_value=5326576 -HeapAlloc dt=7 heapalloc_value=5334768 -HeapAlloc dt=6 heapalloc_value=5342960 -HeapAlloc dt=5 heapalloc_value=5351152 -HeapAlloc dt=6 heapalloc_value=5359344 -HeapAlloc dt=5 heapalloc_value=5367536 -HeapAlloc dt=13 heapalloc_value=5375728 -HeapAlloc dt=6 heapalloc_value=5383920 -HeapAlloc dt=100 heapalloc_value=5392112 -HeapAlloc dt=8 heapalloc_value=5400304 -HeapAlloc dt=6 heapalloc_value=5408496 -HeapAlloc dt=6 heapalloc_value=5416688 -HeapAlloc dt=5 heapalloc_value=5424880 -HeapAlloc dt=6 heapalloc_value=5433072 -HeapAlloc dt=33 heapalloc_value=5441264 -HeapAlloc dt=7 heapalloc_value=5449456 -HeapAlloc dt=5 heapalloc_value=5457648 -HeapAlloc dt=8 heapalloc_value=5465840 -HeapAlloc dt=6 heapalloc_value=5474032 -HeapAlloc dt=5 heapalloc_value=5482224 -HeapAlloc dt=6 heapalloc_value=5490416 -HeapAlloc dt=5 heapalloc_value=5498608 -HeapAlloc dt=6 heapalloc_value=5506800 -HeapAlloc dt=6 heapalloc_value=5514992 -HeapAlloc dt=5 heapalloc_value=5523184 -HeapAlloc dt=12 heapalloc_value=5531376 -HeapAlloc dt=6 heapalloc_value=5539568 -HeapAlloc dt=6 heapalloc_value=5547760 -HeapAlloc dt=5 heapalloc_value=5555952 -HeapAlloc dt=6 heapalloc_value=5564144 -HeapAlloc dt=5 heapalloc_value=5572336 -HeapAlloc dt=6 heapalloc_value=5580528 -HeapAlloc dt=5 heapalloc_value=5588720 -HeapAlloc dt=7 heapalloc_value=5596912 -HeapAlloc dt=6 heapalloc_value=5605104 -HeapAlloc dt=5 heapalloc_value=5613296 -HeapAlloc dt=6 heapalloc_value=5621488 -HeapAlloc dt=5 heapalloc_value=5629680 -HeapAlloc dt=6 heapalloc_value=5637872 -HeapAlloc dt=6 heapalloc_value=5646064 -HeapAlloc dt=37 heapalloc_value=5654256 -HeapAlloc dt=7 heapalloc_value=5662448 -HeapAlloc dt=6 heapalloc_value=5670640 -HeapAlloc dt=5 heapalloc_value=5678832 -HeapAlloc dt=6 heapalloc_value=5687024 -HeapAlloc dt=5 heapalloc_value=5695216 -HeapAlloc dt=6 heapalloc_value=5703408 -HeapAlloc dt=6 heapalloc_value=5711600 -HeapAlloc dt=5 heapalloc_value=5719792 -HeapAlloc dt=5 heapalloc_value=5727984 -HeapAlloc dt=6 heapalloc_value=5736176 -HeapAlloc dt=6 heapalloc_value=5744368 -HeapAlloc dt=5 heapalloc_value=5752560 -HeapAlloc dt=5 heapalloc_value=5760752 -GoBlock dt=15 reason_string=19 stack=21 -ProcStop dt=178 -ProcStart dt=17613 p=4 p_seq=3 -ProcStop dt=26 -ProcStart dt=3944 p=0 p_seq=9 -ProcStop dt=12 -ProcStart dt=16762 p=4 p_seq=6 -ProcStop dt=14 -ProcStart dt=9275 p=0 p_seq=12 -ProcStop dt=9 -ProcStart dt=16732 p=0 p_seq=13 -GoUnblock dt=9 g=1 g_seq=38 stack=0 -GoStart dt=84 g=1 g_seq=39 -HeapAlloc dt=23 heapalloc_value=9631048 -HeapAlloc dt=24 heapalloc_value=9639240 -HeapAlloc dt=15 heapalloc_value=9647432 -HeapAlloc dt=15 heapalloc_value=9655624 -HeapAlloc dt=15 heapalloc_value=9663816 -HeapAlloc dt=16 heapalloc_value=9672008 -HeapAlloc dt=14 heapalloc_value=9680200 -HeapAlloc dt=18 heapalloc_value=9688392 -HeapAlloc dt=14 heapalloc_value=9696584 -HeapAlloc dt=19 heapalloc_value=9704776 -HeapAlloc dt=15 heapalloc_value=9712968 -HeapAlloc dt=76 heapalloc_value=9721160 -HeapAlloc dt=18 heapalloc_value=9729352 -HeapAlloc dt=17 heapalloc_value=9737544 -HeapAlloc dt=14 heapalloc_value=9745736 -HeapAlloc dt=15 heapalloc_value=9753928 -HeapAlloc dt=16 heapalloc_value=9762120 -HeapAlloc dt=28 heapalloc_value=9770312 -HeapAlloc dt=23 heapalloc_value=9778504 -HeapAlloc dt=19 heapalloc_value=9786696 -HeapAlloc dt=14 heapalloc_value=9794888 -HeapAlloc dt=26 heapalloc_value=9803080 -HeapAlloc dt=18 heapalloc_value=9811272 -HeapAlloc dt=16 heapalloc_value=9819464 -HeapAlloc dt=15 heapalloc_value=9827656 -HeapAlloc dt=19 heapalloc_value=9835848 -HeapAlloc dt=16 heapalloc_value=9844040 -HeapAlloc dt=15 heapalloc_value=9852232 -HeapAlloc dt=15 heapalloc_value=9860424 -HeapAlloc dt=15 heapalloc_value=9868616 -HeapAlloc dt=15 heapalloc_value=9876808 -HeapAlloc dt=15 heapalloc_value=9885000 -HeapAlloc dt=15 heapalloc_value=9893192 -HeapAlloc dt=15 heapalloc_value=9901384 -HeapAlloc dt=16 heapalloc_value=9909576 -HeapAlloc dt=16 heapalloc_value=9917768 -HeapAlloc dt=15 heapalloc_value=9925960 -HeapAlloc dt=15 heapalloc_value=9934152 -HeapAlloc dt=15 heapalloc_value=9942344 -HeapAlloc dt=15 heapalloc_value=9950536 -HeapAlloc dt=16 heapalloc_value=9958728 -HeapAlloc dt=15 heapalloc_value=9966920 -HeapAlloc dt=63 heapalloc_value=9975112 -HeapAlloc dt=20 heapalloc_value=9983304 -HeapAlloc dt=14 heapalloc_value=9991496 -HeapAlloc dt=15 heapalloc_value=9999688 -HeapAlloc dt=14 heapalloc_value=10007880 -HeapAlloc dt=15 heapalloc_value=10016072 -HeapAlloc dt=16 heapalloc_value=10024264 -HeapAlloc dt=16 heapalloc_value=10032456 -HeapAlloc dt=16 heapalloc_value=10040648 -HeapAlloc dt=16 heapalloc_value=10048840 -HeapAlloc dt=15 heapalloc_value=10057032 -HeapAlloc dt=16 heapalloc_value=10065224 -HeapAlloc dt=14 heapalloc_value=10073416 -HeapAlloc dt=16 heapalloc_value=10081608 -HeapAlloc dt=15 heapalloc_value=10089800 -HeapAlloc dt=16 heapalloc_value=10097992 -HeapAlloc dt=16 heapalloc_value=10106184 -HeapAlloc dt=17 heapalloc_value=10114376 -HeapAlloc dt=15 heapalloc_value=10122568 -HeapAlloc dt=33 heapalloc_value=10327368 -HeapAlloc dt=367 heapalloc_value=10335560 -HeapAlloc dt=21 heapalloc_value=10343752 -HeapAlloc dt=16 heapalloc_value=10351944 -HeapAlloc dt=15 heapalloc_value=10360136 -HeapAlloc dt=16 heapalloc_value=10368328 -HeapAlloc dt=16 heapalloc_value=10376520 -HeapAlloc dt=16 heapalloc_value=10384712 -HeapAlloc dt=15 heapalloc_value=10392904 -HeapAlloc dt=15 heapalloc_value=10401096 -HeapAlloc dt=15 heapalloc_value=10409288 -HeapAlloc dt=15 heapalloc_value=10417480 -HeapAlloc dt=15 heapalloc_value=10425672 -HeapAlloc dt=17 heapalloc_value=10433864 -HeapAlloc dt=15 heapalloc_value=10442056 -HeapAlloc dt=15 heapalloc_value=10450248 -HeapAlloc dt=15 heapalloc_value=10458440 -HeapAlloc dt=15 heapalloc_value=10466632 -HeapAlloc dt=15 heapalloc_value=10474824 -HeapAlloc dt=15 heapalloc_value=10483016 -HeapAlloc dt=14 heapalloc_value=10491208 -HeapAlloc dt=22 heapalloc_value=10499400 -HeapAlloc dt=7 heapalloc_value=10507592 -HeapAlloc dt=9 heapalloc_value=10515784 -HeapAlloc dt=7 heapalloc_value=10523976 -HeapAlloc dt=6 heapalloc_value=10532168 -HeapAlloc dt=5 heapalloc_value=10540360 -HeapAlloc dt=6 heapalloc_value=10548552 -HeapAlloc dt=6 heapalloc_value=10556744 -HeapAlloc dt=5 heapalloc_value=10564936 -HeapAlloc dt=6 heapalloc_value=10573128 -HeapAlloc dt=6 heapalloc_value=10581320 -HeapAlloc dt=5 heapalloc_value=10589512 -HeapAlloc dt=6 heapalloc_value=10597704 -HeapAlloc dt=6 heapalloc_value=10605896 -HeapAlloc dt=5 heapalloc_value=10614088 -HeapAlloc dt=6 heapalloc_value=10622280 -HeapAlloc dt=5 heapalloc_value=10630472 -HeapAlloc dt=6 heapalloc_value=10638664 -HeapAlloc dt=6 heapalloc_value=10646856 -HeapAlloc dt=5 heapalloc_value=10655048 -HeapAlloc dt=6 heapalloc_value=10663240 -HeapAlloc dt=5 heapalloc_value=10671432 -HeapAlloc dt=6 heapalloc_value=10679624 -HeapAlloc dt=5 heapalloc_value=10687816 -HeapAlloc dt=221 heapalloc_value=10696008 -HeapAlloc dt=9 heapalloc_value=10704200 -HeapAlloc dt=6 heapalloc_value=10712392 -HeapAlloc dt=5 heapalloc_value=10720584 -HeapAlloc dt=6 heapalloc_value=10728776 -HeapAlloc dt=6 heapalloc_value=10736968 -HeapAlloc dt=5 heapalloc_value=10745160 -HeapAlloc dt=6 heapalloc_value=10753352 -HeapAlloc dt=5 heapalloc_value=10761544 -HeapAlloc dt=6 heapalloc_value=10769736 -HeapAlloc dt=5 heapalloc_value=10777928 -HeapAlloc dt=5 heapalloc_value=10786120 -HeapAlloc dt=6 heapalloc_value=10794312 -HeapAlloc dt=6 heapalloc_value=10802504 -HeapAlloc dt=5 heapalloc_value=10810696 -HeapAlloc dt=6 heapalloc_value=10818888 -HeapAlloc dt=5 heapalloc_value=10827080 -HeapAlloc dt=6 heapalloc_value=10835272 -HeapAlloc dt=5 heapalloc_value=10843464 -HeapAlloc dt=6 heapalloc_value=10851656 -GoBlock dt=11 reason_string=19 stack=21 -ProcStop dt=119 -ProcStart dt=17350 p=2 p_seq=7 -ProcStop dt=13 -ProcStart dt=1133 p=0 p_seq=16 -ProcStop dt=8 -ProcStart dt=16748 p=0 p_seq=17 -GoUnblock dt=7 g=1 g_seq=42 stack=0 -GoStart dt=84 g=1 g_seq=43 -HeapAlloc dt=15 heapalloc_value=11883848 -HeapAlloc dt=10 heapalloc_value=11892040 -HeapAlloc dt=6 heapalloc_value=11900232 -HeapAlloc dt=6 heapalloc_value=11908424 -HeapAlloc dt=6 heapalloc_value=11916616 -HeapAlloc dt=6 heapalloc_value=11924808 -HeapAlloc dt=8 heapalloc_value=11933000 -HeapAlloc dt=5 heapalloc_value=11941192 -HeapAlloc dt=6 heapalloc_value=11949384 -HeapAlloc dt=62 heapalloc_value=11957576 -HeapAlloc dt=7 heapalloc_value=11965768 -HeapAlloc dt=6 heapalloc_value=11973960 -HeapAlloc dt=6 heapalloc_value=11982152 -HeapAlloc dt=5 heapalloc_value=11990344 -HeapAlloc dt=6 heapalloc_value=11998536 -HeapAlloc dt=6 heapalloc_value=12006728 -HeapAlloc dt=5 heapalloc_value=12014920 -HeapAlloc dt=6 heapalloc_value=12023112 -HeapAlloc dt=5 heapalloc_value=12031304 -HeapAlloc dt=6 heapalloc_value=12039496 -HeapAlloc dt=5 heapalloc_value=12047688 -HeapAlloc dt=6 heapalloc_value=12055880 -HeapAlloc dt=6 heapalloc_value=12064072 -HeapAlloc dt=6 heapalloc_value=12072264 -HeapAlloc dt=5 heapalloc_value=12080456 -HeapAlloc dt=352 heapalloc_value=12088648 -HeapAlloc dt=14 heapalloc_value=12096840 -HeapAlloc dt=7 heapalloc_value=12105032 -HeapAlloc dt=5 heapalloc_value=12113224 -HeapAlloc dt=6 heapalloc_value=12121416 -HeapAlloc dt=41 heapalloc_value=12129608 -HeapAlloc dt=7 heapalloc_value=12137800 -HeapAlloc dt=5 heapalloc_value=12145992 -HeapAlloc dt=6 heapalloc_value=12154184 -HeapAlloc dt=6 heapalloc_value=12162376 -HeapAlloc dt=6 heapalloc_value=12170568 -HeapAlloc dt=5 heapalloc_value=12178760 -HeapAlloc dt=6 heapalloc_value=12186952 -HeapAlloc dt=5 heapalloc_value=12195144 -HeapAlloc dt=7 heapalloc_value=12203336 -HeapAlloc dt=5 heapalloc_value=12211528 -HeapAlloc dt=6 heapalloc_value=12219720 -HeapAlloc dt=5 heapalloc_value=12227912 -HeapAlloc dt=6 heapalloc_value=12236104 -HeapAlloc dt=6 heapalloc_value=12244296 -HeapAlloc dt=6 heapalloc_value=12252488 -HeapAlloc dt=5 heapalloc_value=12260680 -HeapAlloc dt=46 heapalloc_value=12268872 -HeapAlloc dt=6 heapalloc_value=12277064 -HeapAlloc dt=6 heapalloc_value=12285256 -HeapAlloc dt=6 heapalloc_value=12293448 -HeapAlloc dt=5 heapalloc_value=12301640 -HeapAlloc dt=6 heapalloc_value=12309832 -HeapAlloc dt=5 heapalloc_value=12318024 -HeapAlloc dt=6 heapalloc_value=12326216 -HeapAlloc dt=5 heapalloc_value=12334408 -HeapAlloc dt=6 heapalloc_value=12342600 -HeapAlloc dt=5 heapalloc_value=12350792 -HeapAlloc dt=6 heapalloc_value=12358984 -HeapAlloc dt=5 heapalloc_value=12367176 -HeapAlloc dt=6 heapalloc_value=12375368 -HeapAlloc dt=37 heapalloc_value=12383560 -HeapAlloc dt=7 heapalloc_value=12391752 -HeapAlloc dt=6 heapalloc_value=12399944 -HeapAlloc dt=5 heapalloc_value=12408136 -HeapAlloc dt=6 heapalloc_value=12416328 -HeapAlloc dt=6 heapalloc_value=12424520 -HeapAlloc dt=13 heapalloc_value=12686664 -HeapAlloc dt=2516 heapalloc_value=12694856 -HeapAlloc dt=9 heapalloc_value=12703048 -HeapAlloc dt=8 heapalloc_value=12711240 -HeapAlloc dt=7 heapalloc_value=12719432 -HeapAlloc dt=8 heapalloc_value=12727624 -HeapAlloc dt=7 heapalloc_value=12735816 -HeapAlloc dt=8 heapalloc_value=12744008 -HeapAlloc dt=7 heapalloc_value=12752200 -HeapAlloc dt=8 heapalloc_value=12760392 -HeapAlloc dt=7 heapalloc_value=12768584 -HeapAlloc dt=7 heapalloc_value=12776776 -HeapAlloc dt=8 heapalloc_value=12784968 -HeapAlloc dt=7 heapalloc_value=12793160 -HeapAlloc dt=8 heapalloc_value=12801352 -HeapAlloc dt=8 heapalloc_value=12809544 -HeapAlloc dt=7 heapalloc_value=12817736 -HeapAlloc dt=7 heapalloc_value=12825928 -HeapAlloc dt=8 heapalloc_value=12834120 -HeapAlloc dt=7 heapalloc_value=12842312 -HeapAlloc dt=8 heapalloc_value=12850504 -HeapAlloc dt=8 heapalloc_value=12858696 -HeapAlloc dt=7 heapalloc_value=12866888 -HeapAlloc dt=13 heapalloc_value=12875080 -HeapAlloc dt=8 heapalloc_value=12883272 -HeapAlloc dt=5 heapalloc_value=12891464 -HeapAlloc dt=6 heapalloc_value=12899656 -HeapAlloc dt=6 heapalloc_value=12907848 -HeapAlloc dt=5 heapalloc_value=12916040 -HeapAlloc dt=6 heapalloc_value=12924232 -HeapAlloc dt=6 heapalloc_value=12932424 -HeapAlloc dt=5 heapalloc_value=12940616 -HeapAlloc dt=6 heapalloc_value=12948808 -HeapAlloc dt=5 heapalloc_value=12957000 -HeapAlloc dt=6 heapalloc_value=12965192 -HeapAlloc dt=5 heapalloc_value=12973384 -HeapAlloc dt=6 heapalloc_value=12981576 -HeapAlloc dt=6 heapalloc_value=12989768 -HeapAlloc dt=5 heapalloc_value=12997960 -HeapAlloc dt=6 heapalloc_value=13006152 -HeapAlloc dt=6 heapalloc_value=13014344 -HeapAlloc dt=5 heapalloc_value=13022536 -HeapAlloc dt=6 heapalloc_value=13030728 -HeapAlloc dt=5 heapalloc_value=13038920 -HeapAlloc dt=62 heapalloc_value=13047112 -HeapAlloc dt=39 heapalloc_value=13055304 -HeapAlloc dt=7 heapalloc_value=13063496 -HeapAlloc dt=6 heapalloc_value=13071688 -HeapAlloc dt=6 heapalloc_value=13079880 -HeapAlloc dt=6 heapalloc_value=13088072 -HeapAlloc dt=5 heapalloc_value=13096264 -HeapAlloc dt=5 heapalloc_value=13104456 -HeapAlloc dt=6 heapalloc_value=13112648 -HeapAlloc dt=6 heapalloc_value=13120840 -HeapAlloc dt=5 heapalloc_value=13129032 -HeapAlloc dt=10 heapalloc_value=13137224 -HeapAlloc dt=6 heapalloc_value=13145416 -HeapAlloc dt=5 heapalloc_value=13153608 -HeapAlloc dt=6 heapalloc_value=13161800 -GoBlock dt=12 reason_string=19 stack=21 -ProcStop dt=124 -ProcStart dt=17212 p=2 p_seq=9 -ProcStop dt=13 -ProcStart dt=1068 p=0 p_seq=20 -ProcStop dt=8 -ProcStart dt=16756 p=0 p_seq=21 -GoUnblock dt=11 g=1 g_seq=46 stack=0 -GoStart dt=92 g=1 g_seq=47 -HeapAlloc dt=19 heapalloc_value=14193992 -HeapAlloc dt=10 heapalloc_value=14202184 -HeapAlloc dt=6 heapalloc_value=14210376 -HeapAlloc dt=6 heapalloc_value=14218568 -HeapAlloc dt=6 heapalloc_value=14226760 -HeapAlloc dt=6 heapalloc_value=14234952 -HeapAlloc dt=6 heapalloc_value=14243144 -HeapAlloc dt=6 heapalloc_value=14251336 -HeapAlloc dt=6 heapalloc_value=14259528 -HeapAlloc dt=6 heapalloc_value=14267720 -HeapAlloc dt=5 heapalloc_value=14275912 -HeapAlloc dt=6 heapalloc_value=14284104 -HeapAlloc dt=6 heapalloc_value=14292296 -HeapAlloc dt=6 heapalloc_value=14300488 -HeapAlloc dt=60 heapalloc_value=14308680 -HeapAlloc dt=8 heapalloc_value=14316872 -HeapAlloc dt=6 heapalloc_value=14325064 -HeapAlloc dt=6 heapalloc_value=14333256 -HeapAlloc dt=6 heapalloc_value=14341448 -HeapAlloc dt=5 heapalloc_value=14349640 -HeapAlloc dt=6 heapalloc_value=14357832 -HeapAlloc dt=6 heapalloc_value=14366024 -HeapAlloc dt=6 heapalloc_value=14374216 -HeapAlloc dt=6 heapalloc_value=14382408 -HeapAlloc dt=8 heapalloc_value=14390600 -HeapAlloc dt=6 heapalloc_value=14398792 -HeapAlloc dt=6 heapalloc_value=14406984 -HeapAlloc dt=6 heapalloc_value=14415176 -HeapAlloc dt=6 heapalloc_value=14423368 -HeapAlloc dt=5 heapalloc_value=14431560 -HeapAlloc dt=6 heapalloc_value=14439752 -HeapAlloc dt=7 heapalloc_value=14447944 -HeapAlloc dt=5 heapalloc_value=14456136 -HeapAlloc dt=6 heapalloc_value=14464328 -HeapAlloc dt=6 heapalloc_value=14472520 -HeapAlloc dt=5 heapalloc_value=14480712 -HeapAlloc dt=6 heapalloc_value=14488904 -HeapAlloc dt=6 heapalloc_value=14497096 -HeapAlloc dt=6 heapalloc_value=14505288 -HeapAlloc dt=6 heapalloc_value=14513480 -HeapAlloc dt=6 heapalloc_value=14521672 -HeapAlloc dt=6 heapalloc_value=14529864 -HeapAlloc dt=5 heapalloc_value=14538056 -HeapAlloc dt=6 heapalloc_value=14546248 -HeapAlloc dt=6 heapalloc_value=14554440 -HeapAlloc dt=5 heapalloc_value=14562632 -HeapAlloc dt=6 heapalloc_value=14570824 -HeapAlloc dt=6 heapalloc_value=14579016 -HeapAlloc dt=6 heapalloc_value=14587208 -HeapAlloc dt=6 heapalloc_value=14595400 -HeapAlloc dt=5 heapalloc_value=14603592 -HeapAlloc dt=6 heapalloc_value=14611784 -HeapAlloc dt=45 heapalloc_value=14619976 -HeapAlloc dt=7 heapalloc_value=14628168 -HeapAlloc dt=6 heapalloc_value=14636360 -HeapAlloc dt=7 heapalloc_value=14644552 -HeapAlloc dt=5 heapalloc_value=14652744 -HeapAlloc dt=6 heapalloc_value=14660936 -HeapAlloc dt=6 heapalloc_value=14669128 -HeapAlloc dt=5 heapalloc_value=14677320 -HeapAlloc dt=6 heapalloc_value=14685512 -HeapAlloc dt=6 heapalloc_value=14693704 -HeapAlloc dt=6 heapalloc_value=14701896 -HeapAlloc dt=15 heapalloc_value=14710088 -HeapAlloc dt=6 heapalloc_value=14718280 -HeapAlloc dt=5 heapalloc_value=14726472 -HeapAlloc dt=35 heapalloc_value=14734664 -HeapAlloc dt=7 heapalloc_value=14742856 -HeapAlloc dt=6 heapalloc_value=14751048 -HeapAlloc dt=6 heapalloc_value=14759240 -HeapAlloc dt=6 heapalloc_value=14767432 -HeapAlloc dt=6 heapalloc_value=14775624 -HeapAlloc dt=6 heapalloc_value=14783816 -HeapAlloc dt=6 heapalloc_value=14792008 -HeapAlloc dt=5 heapalloc_value=14800200 -HeapAlloc dt=6 heapalloc_value=14808392 -HeapAlloc dt=5 heapalloc_value=14816584 -HeapAlloc dt=6 heapalloc_value=14824776 -HeapAlloc dt=6 heapalloc_value=14832968 -HeapAlloc dt=6 heapalloc_value=14841160 -HeapAlloc dt=6 heapalloc_value=14849352 -HeapAlloc dt=45 heapalloc_value=14857544 -HeapAlloc dt=6 heapalloc_value=14865736 -HeapAlloc dt=5 heapalloc_value=14873928 -HeapAlloc dt=6 heapalloc_value=14882120 -HeapAlloc dt=6 heapalloc_value=14890312 -HeapAlloc dt=6 heapalloc_value=14898504 -HeapAlloc dt=6 heapalloc_value=14906696 -HeapAlloc dt=6 heapalloc_value=14914888 -HeapAlloc dt=5 heapalloc_value=14923080 -HeapAlloc dt=6 heapalloc_value=14931272 -HeapAlloc dt=6 heapalloc_value=14939464 -HeapAlloc dt=5 heapalloc_value=14947656 -HeapAlloc dt=6 heapalloc_value=14955848 -HeapAlloc dt=6 heapalloc_value=14964040 -HeapAlloc dt=6 heapalloc_value=14972232 -HeapAlloc dt=5 heapalloc_value=14980424 -HeapAlloc dt=6 heapalloc_value=14988616 -HeapAlloc dt=6 heapalloc_value=14996808 -HeapAlloc dt=5 heapalloc_value=15005000 -HeapAlloc dt=6 heapalloc_value=15013192 -HeapAlloc dt=6 heapalloc_value=15021384 -HeapAlloc dt=6 heapalloc_value=15029576 -HeapAlloc dt=6 heapalloc_value=15037768 -HeapAlloc dt=6 heapalloc_value=15045960 -HeapAlloc dt=5 heapalloc_value=15054152 -HeapAlloc dt=6 heapalloc_value=15062344 -HeapAlloc dt=6 heapalloc_value=15070536 -HeapAlloc dt=6 heapalloc_value=15078728 -HeapAlloc dt=5 heapalloc_value=15086920 -HeapAlloc dt=6 heapalloc_value=15095112 -HeapAlloc dt=6 heapalloc_value=15103304 -HeapAlloc dt=5 heapalloc_value=15111496 -HeapAlloc dt=6 heapalloc_value=15119688 -HeapAlloc dt=6 heapalloc_value=15127880 -HeapAlloc dt=5 heapalloc_value=15136072 -HeapAlloc dt=51 heapalloc_value=15471944 -HeapAlloc dt=2533 heapalloc_value=15480136 -HeapAlloc dt=11 heapalloc_value=15488328 -HeapAlloc dt=9 heapalloc_value=15496520 -HeapAlloc dt=7 heapalloc_value=15504712 -HeapAlloc dt=9 heapalloc_value=15512904 -HeapAlloc dt=9 heapalloc_value=15521096 -HeapAlloc dt=7 heapalloc_value=15529288 -HeapAlloc dt=8 heapalloc_value=15537480 -HeapAlloc dt=8 heapalloc_value=15545672 -GoBlock dt=13 reason_string=19 stack=21 -ProcStop dt=116 -ProcStart dt=17265 p=2 p_seq=11 -ProcStop dt=10 -ProcStart dt=1450 p=0 p_seq=24 -ProcStop dt=9 -ProcStart dt=17026 p=0 p_seq=25 -GoUnblock dt=12 g=1 g_seq=50 stack=0 -GoStart dt=148 g=1 g_seq=51 -HeapAlloc dt=20 heapalloc_value=16577864 -HeapAlloc dt=15 heapalloc_value=16586056 -HeapAlloc dt=10 heapalloc_value=16594248 -HeapAlloc dt=11 heapalloc_value=16602440 -HeapAlloc dt=9 heapalloc_value=16610632 -HeapAlloc dt=9 heapalloc_value=16618824 -HeapAlloc dt=10 heapalloc_value=16627016 -HeapAlloc dt=9 heapalloc_value=16635208 -HeapAlloc dt=11 heapalloc_value=16643400 -HeapAlloc dt=11 heapalloc_value=16651592 -HeapAlloc dt=9 heapalloc_value=16659784 -HeapAlloc dt=11 heapalloc_value=16667976 -HeapAlloc dt=9 heapalloc_value=16676168 -HeapAlloc dt=10 heapalloc_value=16684360 -HeapAlloc dt=10 heapalloc_value=16692552 -HeapAlloc dt=10 heapalloc_value=16700744 -HeapAlloc dt=11 heapalloc_value=16708936 -HeapAlloc dt=11 heapalloc_value=16717128 -HeapAlloc dt=9 heapalloc_value=16725320 -HeapAlloc dt=78 heapalloc_value=16733512 -HeapAlloc dt=14 heapalloc_value=16741704 -HeapAlloc dt=10 heapalloc_value=16749896 -HeapAlloc dt=11 heapalloc_value=16758088 -HeapAlloc dt=11 heapalloc_value=16766280 -HeapAlloc dt=10 heapalloc_value=16774472 -HeapAlloc dt=9 heapalloc_value=16782664 -HeapAlloc dt=10 heapalloc_value=16790856 -HeapAlloc dt=9 heapalloc_value=16799048 -HeapAlloc dt=21 heapalloc_value=16807240 -HeapAlloc dt=11 heapalloc_value=16815432 -HeapAlloc dt=9 heapalloc_value=16823624 -HeapAlloc dt=9 heapalloc_value=16831816 -HeapAlloc dt=9 heapalloc_value=16840008 -HeapAlloc dt=10 heapalloc_value=16848200 -HeapAlloc dt=11 heapalloc_value=16856392 -HeapAlloc dt=9 heapalloc_value=16864584 -HeapAlloc dt=6 heapalloc_value=16872776 -HeapAlloc dt=9 heapalloc_value=16880968 -HeapAlloc dt=6 heapalloc_value=16889160 -HeapAlloc dt=6 heapalloc_value=16897352 -HeapAlloc dt=5 heapalloc_value=16905544 -HeapAlloc dt=6 heapalloc_value=16913736 -HeapAlloc dt=6 heapalloc_value=16921928 -HeapAlloc dt=5 heapalloc_value=16930120 -HeapAlloc dt=6 heapalloc_value=16938312 -HeapAlloc dt=5 heapalloc_value=16946504 -HeapAlloc dt=6 heapalloc_value=16954696 -HeapAlloc dt=5 heapalloc_value=16962888 -HeapAlloc dt=5 heapalloc_value=16971080 -HeapAlloc dt=5 heapalloc_value=16979272 -HeapAlloc dt=6 heapalloc_value=16987464 -HeapAlloc dt=5 heapalloc_value=16995656 -HeapAlloc dt=5 heapalloc_value=17003848 -HeapAlloc dt=6 heapalloc_value=17012040 -HeapAlloc dt=5 heapalloc_value=17020232 -HeapAlloc dt=6 heapalloc_value=17028424 -HeapAlloc dt=5 heapalloc_value=17036616 -HeapAlloc dt=53 heapalloc_value=17044808 -HeapAlloc dt=7 heapalloc_value=17053000 -HeapAlloc dt=5 heapalloc_value=17061192 -HeapAlloc dt=6 heapalloc_value=17069384 -HeapAlloc dt=11 heapalloc_value=17077576 -HeapAlloc dt=10 heapalloc_value=17085768 -HeapAlloc dt=5 heapalloc_value=17093960 -HeapAlloc dt=5 heapalloc_value=17102152 -HeapAlloc dt=6 heapalloc_value=17110344 -HeapAlloc dt=5 heapalloc_value=17118536 -HeapAlloc dt=5 heapalloc_value=17126728 -HeapAlloc dt=6 heapalloc_value=17134920 -HeapAlloc dt=5 heapalloc_value=17143112 -HeapAlloc dt=6 heapalloc_value=17151304 -HeapAlloc dt=37 heapalloc_value=17159496 -GCBegin dt=15 gc_seq=5 stack=22 -STWBegin dt=37 kind_string=22 stack=28 -GoUnblock dt=288 g=4 g_seq=9 stack=29 -ProcsChange dt=56 procs_value=8 stack=30 -STWEnd dt=23 -GCMarkAssistBegin dt=90 stack=31 -GCMarkAssistEnd dt=3424 -HeapAlloc dt=523 heapalloc_value=17175048 -HeapAlloc dt=21 heapalloc_value=17183240 -HeapAlloc dt=46 heapalloc_value=17191432 -HeapAlloc dt=96 heapalloc_value=17199624 -HeapAlloc dt=12 heapalloc_value=17207816 -HeapAlloc dt=12 heapalloc_value=17216008 -HeapAlloc dt=13 heapalloc_value=17224200 -HeapAlloc dt=10 heapalloc_value=17232392 -HeapAlloc dt=12 heapalloc_value=17240584 -HeapAlloc dt=13 heapalloc_value=17248776 -HeapAlloc dt=12 heapalloc_value=17256968 -HeapAlloc dt=14 heapalloc_value=17265160 -HeapAlloc dt=12 heapalloc_value=17273352 -HeapAlloc dt=12 heapalloc_value=17281544 -HeapAlloc dt=11 heapalloc_value=17289736 -HeapAlloc dt=13 heapalloc_value=17297928 -HeapAlloc dt=36 heapalloc_value=17306120 -HeapAlloc dt=12 heapalloc_value=17314312 -HeapAlloc dt=10 heapalloc_value=17322504 -HeapAlloc dt=12 heapalloc_value=17330696 -HeapAlloc dt=10 heapalloc_value=17338888 -HeapAlloc dt=11 heapalloc_value=17347080 -HeapAlloc dt=10 heapalloc_value=17355272 -HeapAlloc dt=10 heapalloc_value=17363464 -HeapAlloc dt=10 heapalloc_value=17371656 -HeapAlloc dt=11 heapalloc_value=17379848 -HeapAlloc dt=8 heapalloc_value=17388040 -HeapAlloc dt=13 heapalloc_value=17396232 -HeapAlloc dt=10 heapalloc_value=17404424 -HeapAlloc dt=13 heapalloc_value=17412616 -HeapAlloc dt=13 heapalloc_value=17420808 -HeapAlloc dt=10 heapalloc_value=17429000 -HeapAlloc dt=31 heapalloc_value=17437192 -HeapAlloc dt=6 heapalloc_value=17445384 -HeapAlloc dt=7 heapalloc_value=17453576 -HeapAlloc dt=6 heapalloc_value=17461768 -HeapAlloc dt=7 heapalloc_value=17469960 -HeapAlloc dt=7 heapalloc_value=17478152 -HeapAlloc dt=7 heapalloc_value=17486344 -HeapAlloc dt=7 heapalloc_value=17494536 -HeapAlloc dt=12 heapalloc_value=17502728 -HeapAlloc dt=7 heapalloc_value=17510920 -HeapAlloc dt=12 heapalloc_value=17519112 -HeapAlloc dt=13 heapalloc_value=17527304 -HeapAlloc dt=20 heapalloc_value=17535496 -HeapAlloc dt=15 heapalloc_value=17543688 -HeapAlloc dt=6 heapalloc_value=17551880 -HeapAlloc dt=7 heapalloc_value=17560072 -HeapAlloc dt=72 heapalloc_value=17568264 -HeapAlloc dt=37 heapalloc_value=17576456 -HeapAlloc dt=7 heapalloc_value=17584648 -HeapAlloc dt=7 heapalloc_value=17592840 -HeapAlloc dt=6 heapalloc_value=17601032 -GoBlock dt=13 reason_string=19 stack=21 -GoUnblock dt=157 g=24 g_seq=12 stack=0 -GoStart dt=7 g=24 g_seq=13 -GoLabel dt=1 label_string=2 -STWBegin dt=4128 kind_string=23 stack=37 -GoUnblock dt=64 g=25 g_seq=8 stack=38 -HeapAlloc dt=25 heapalloc_value=16970376 -GoUnblock dt=24 g=3 g_seq=5 stack=39 -GCEnd dt=6 gc_seq=6 -HeapGoal dt=7 heapgoal_value=34360936 -ProcsChange dt=46 procs_value=8 stack=40 -STWEnd dt=49 -GoBlock dt=756 reason_string=15 stack=27 -GoStart dt=10 g=3 g_seq=6 -GoBlock dt=14862 reason_string=14 stack=44 -ProcStop dt=25 -ProcStart dt=132428 p=0 p_seq=32 -GoStart dt=162 g=4 g_seq=12 -GoBlock dt=19 reason_string=15 stack=32 -ProcStop dt=20 -ProcStart dt=8304 p=0 p_seq=33 -GoStart dt=191 g=39 g_seq=1 -GoStop dt=306173 reason_string=16 stack=50 -GoStart dt=17 g=39 g_seq=2 -GoStop dt=315175 reason_string=16 stack=50 -GoStart dt=7 g=39 g_seq=3 -GoDestroy dt=159902 -ProcStop dt=50 -EventBatch gen=1 m=1709040 time=7689670148204 size=3534 -ProcStart dt=256 p=1 p_seq=1 -GoStart dt=186 g=6 g_seq=1 -HeapAlloc dt=320 heapalloc_value=2768896 -HeapAlloc dt=22 heapalloc_value=2777088 -GoBlock dt=229 reason_string=12 stack=15 -GoStart dt=12 g=8 g_seq=1 -HeapAlloc dt=15 heapalloc_value=2785280 -GoSyscallBegin dt=16 p_seq=2 stack=16 -GoSyscallEnd dt=254 -GoBlock dt=293 reason_string=15 stack=17 -GoStart dt=19 g=9 g_seq=1 -GoDestroy dt=156265 -ProcStop dt=44 -ProcStart dt=67218 p=1 p_seq=3 -ProcStop dt=19 -ProcStart dt=88214 p=1 p_seq=4 -ProcStop dt=13 -ProcStart dt=17539 p=0 p_seq=1 -ProcStop dt=14 -ProcStart dt=9071 p=4 p_seq=1 -GoUnblock dt=33 g=22 g_seq=2 stack=0 -GoStart dt=6 g=22 g_seq=3 -GoLabel dt=1 label_string=4 -GoUnblock dt=2321 g=1 g_seq=23 stack=34 -STWBegin dt=1205 kind_string=23 stack=37 -GoUnblock dt=78 g=24 g_seq=6 stack=38 -HeapAlloc dt=26 heapalloc_value=3840752 -GoStatus dt=14 g=3 m=18446744073709551615 gstatus=4 -GoUnblock dt=7 g=3 g_seq=1 stack=39 -GCEnd dt=3 gc_seq=2 -HeapGoal dt=6 heapgoal_value=8101720 -ProcsChange dt=43 procs_value=8 stack=40 -STWEnd dt=31 -GoBlock dt=4030 reason_string=15 stack=27 -GoStart dt=12 g=3 g_seq=2 -GoBlock dt=1406 reason_string=14 stack=44 -ProcStop dt=24 -ProcStart dt=34332 p=4 p_seq=4 -GoStart dt=153 g=4 g_seq=4 -GoBlock dt=20 reason_string=15 stack=32 -ProcStop dt=19 -ProcStart dt=1832 p=2 p_seq=5 -GoUnblock dt=22 g=24 g_seq=8 stack=0 -GoStart dt=102 g=24 g_seq=9 -GoLabel dt=1 label_string=2 -STWBegin dt=11769 kind_string=23 stack=37 -GoUnblock dt=60 g=1 g_seq=36 stack=38 -HeapAlloc dt=23 heapalloc_value=8744264 -GoUnblock dt=17 g=3 g_seq=3 stack=39 -GCEnd dt=6 gc_seq=4 -HeapGoal dt=7 heapgoal_value=17908728 -ProcsChange dt=47 procs_value=8 stack=40 -STWEnd dt=28 -GoBlock dt=572 reason_string=15 stack=27 -GoStart dt=13 g=3 g_seq=4 -GoBlock dt=5707 reason_string=14 stack=44 -ProcStop dt=16 -ProcStart dt=136502 p=1 p_seq=11 -GoStart dt=17 g=4 g_seq=8 -GoBlock dt=12 reason_string=15 stack=32 -ProcStop dt=22 -ProcStart dt=5977 p=6 p_seq=1 -ProcStop dt=34 -ProcStart dt=16775 p=2 p_seq=15 -ProcStop dt=23 -ProcStart dt=3966 p=1 p_seq=14 -ProcStop dt=15 -ProcStart dt=16753 p=1 p_seq=15 -GoUnblock dt=35 g=1 g_seq=57 stack=0 -GoStart dt=139 g=1 g_seq=58 -HeapAlloc dt=71 heapalloc_value=17593992 -HeapAlloc dt=47 heapalloc_value=17602184 -HeapAlloc dt=24 heapalloc_value=17610376 -HeapAlloc dt=97 heapalloc_value=17618568 -HeapAlloc dt=23 heapalloc_value=17626760 -HeapAlloc dt=18 heapalloc_value=17634952 -HeapAlloc dt=15 heapalloc_value=17643144 -HeapAlloc dt=18 heapalloc_value=17651336 -HeapAlloc dt=21 heapalloc_value=17659528 -HeapAlloc dt=28 heapalloc_value=17667720 -HeapAlloc dt=26 heapalloc_value=17675912 -HeapAlloc dt=23 heapalloc_value=17684104 -HeapAlloc dt=12 heapalloc_value=17692296 -HeapAlloc dt=12 heapalloc_value=17700488 -HeapAlloc dt=11 heapalloc_value=17708680 -HeapAlloc dt=15 heapalloc_value=17716872 -HeapAlloc dt=18 heapalloc_value=17725064 -HeapAlloc dt=15 heapalloc_value=17733256 -HeapAlloc dt=165 heapalloc_value=17741448 -HeapAlloc dt=16 heapalloc_value=17749640 -HeapAlloc dt=12 heapalloc_value=17757832 -HeapAlloc dt=15 heapalloc_value=17766024 -HeapAlloc dt=12 heapalloc_value=17774216 -HeapAlloc dt=12 heapalloc_value=17782408 -HeapAlloc dt=15 heapalloc_value=17790600 -HeapAlloc dt=11 heapalloc_value=17798792 -HeapAlloc dt=11 heapalloc_value=17806984 -HeapAlloc dt=12 heapalloc_value=17815176 -HeapAlloc dt=12 heapalloc_value=17823368 -HeapAlloc dt=15 heapalloc_value=17831560 -HeapAlloc dt=11 heapalloc_value=17839752 -HeapAlloc dt=12 heapalloc_value=17847944 -HeapAlloc dt=15 heapalloc_value=17856136 -HeapAlloc dt=11 heapalloc_value=17864328 -HeapAlloc dt=12 heapalloc_value=17872520 -HeapAlloc dt=12 heapalloc_value=17880712 -HeapAlloc dt=14 heapalloc_value=17888904 -HeapAlloc dt=42 heapalloc_value=17897096 -HeapAlloc dt=54 heapalloc_value=17905288 -HeapAlloc dt=49 heapalloc_value=17913480 -HeapAlloc dt=54 heapalloc_value=17921672 -HeapAlloc dt=56 heapalloc_value=17929864 -HeapAlloc dt=45 heapalloc_value=17938056 -HeapAlloc dt=57 heapalloc_value=17946248 -HeapAlloc dt=63 heapalloc_value=17954440 -HeapAlloc dt=57 heapalloc_value=17962632 -HeapAlloc dt=56 heapalloc_value=17970824 -HeapAlloc dt=62 heapalloc_value=17979016 -HeapAlloc dt=109 heapalloc_value=17987208 -HeapAlloc dt=59 heapalloc_value=17995400 -HeapAlloc dt=45 heapalloc_value=18003592 -HeapAlloc dt=61 heapalloc_value=18011784 -HeapAlloc dt=35 heapalloc_value=18019976 -HeapAlloc dt=16 heapalloc_value=18028168 -HeapAlloc dt=15 heapalloc_value=18036360 -HeapAlloc dt=15 heapalloc_value=18044552 -HeapAlloc dt=21 heapalloc_value=18052744 -HeapAlloc dt=16 heapalloc_value=18060936 -HeapAlloc dt=16 heapalloc_value=18069128 -HeapAlloc dt=22 heapalloc_value=18077320 -HeapAlloc dt=43 heapalloc_value=18085512 -HeapAlloc dt=46 heapalloc_value=18093704 -HeapAlloc dt=43 heapalloc_value=18101896 -HeapAlloc dt=42 heapalloc_value=18110088 -HeapAlloc dt=44 heapalloc_value=18118280 -HeapAlloc dt=35 heapalloc_value=18126472 -HeapAlloc dt=39 heapalloc_value=18134664 -HeapAlloc dt=40 heapalloc_value=18142856 -HeapAlloc dt=43 heapalloc_value=18151048 -HeapAlloc dt=44 heapalloc_value=18159240 -HeapAlloc dt=38 heapalloc_value=18167432 -HeapAlloc dt=42 heapalloc_value=18175624 -HeapAlloc dt=40 heapalloc_value=18183816 -HeapAlloc dt=40 heapalloc_value=18192008 -HeapAlloc dt=36 heapalloc_value=18200200 -HeapAlloc dt=55 heapalloc_value=18208392 -HeapAlloc dt=54 heapalloc_value=18216584 -HeapAlloc dt=54 heapalloc_value=18224776 -HeapAlloc dt=41 heapalloc_value=18232968 -HeapAlloc dt=58 heapalloc_value=18241160 -HeapAlloc dt=61 heapalloc_value=18249352 -HeapAlloc dt=55 heapalloc_value=18257544 -HeapAlloc dt=141 heapalloc_value=18265736 -HeapAlloc dt=55 heapalloc_value=18273928 -HeapAlloc dt=54 heapalloc_value=18282120 -HeapAlloc dt=50 heapalloc_value=18290312 -HeapAlloc dt=82 heapalloc_value=18298504 -HeapAlloc dt=64 heapalloc_value=18306696 -HeapAlloc dt=55 heapalloc_value=18314888 -HeapAlloc dt=58 heapalloc_value=18323080 -HeapAlloc dt=54 heapalloc_value=18331272 -HeapAlloc dt=57 heapalloc_value=18339464 -HeapAlloc dt=46 heapalloc_value=18347656 -HeapAlloc dt=41 heapalloc_value=18355848 -HeapAlloc dt=56 heapalloc_value=18364040 -HeapAlloc dt=50 heapalloc_value=18372232 -HeapAlloc dt=54 heapalloc_value=18380424 -HeapAlloc dt=56 heapalloc_value=18388616 -HeapAlloc dt=57 heapalloc_value=18396808 -HeapAlloc dt=55 heapalloc_value=18405000 -HeapAlloc dt=55 heapalloc_value=18413192 -HeapAlloc dt=51 heapalloc_value=18421384 -HeapAlloc dt=52 heapalloc_value=18429576 -HeapAlloc dt=67 heapalloc_value=18437768 -HeapAlloc dt=36 heapalloc_value=18445960 -HeapAlloc dt=28 heapalloc_value=18454152 -HeapAlloc dt=30 heapalloc_value=18462344 -HeapAlloc dt=40 heapalloc_value=18470536 -HeapAlloc dt=29 heapalloc_value=18478728 -HeapAlloc dt=37 heapalloc_value=18486920 -HeapAlloc dt=34 heapalloc_value=18495112 -HeapAlloc dt=73 heapalloc_value=18503304 -HeapAlloc dt=37 heapalloc_value=18511496 -HeapAlloc dt=38 heapalloc_value=18519688 -HeapAlloc dt=29 heapalloc_value=18527880 -HeapAlloc dt=35 heapalloc_value=18536072 -HeapAlloc dt=33 heapalloc_value=18544264 -HeapAlloc dt=40 heapalloc_value=18552456 -HeapAlloc dt=32 heapalloc_value=18560648 -HeapAlloc dt=42 heapalloc_value=18568840 -HeapAlloc dt=34 heapalloc_value=18577032 -HeapAlloc dt=37 heapalloc_value=18585224 -HeapAlloc dt=35 heapalloc_value=18593416 -HeapAlloc dt=39 heapalloc_value=18601608 -HeapAlloc dt=35 heapalloc_value=18609800 -GoBlock dt=51 reason_string=19 stack=21 -ProcStop dt=192 -ProcStart dt=17579 p=0 p_seq=27 -ProcStop dt=18 -ProcStart dt=1930 p=1 p_seq=18 -ProcStop dt=15 -ProcStart dt=16696 p=1 p_seq=19 -GoUnblock dt=22 g=1 g_seq=61 stack=0 -GoStart dt=125 g=1 g_seq=62 -HeapAlloc dt=53 heapalloc_value=19641992 -HeapAlloc dt=19 heapalloc_value=19650184 -HeapAlloc dt=20 heapalloc_value=19658376 -HeapAlloc dt=23 heapalloc_value=19666568 -HeapAlloc dt=16 heapalloc_value=19674760 -HeapAlloc dt=16 heapalloc_value=19682952 -HeapAlloc dt=19 heapalloc_value=19691144 -HeapAlloc dt=15 heapalloc_value=19699336 -HeapAlloc dt=12 heapalloc_value=19707528 -HeapAlloc dt=12 heapalloc_value=19715720 -HeapAlloc dt=13 heapalloc_value=19723912 -HeapAlloc dt=18 heapalloc_value=19732104 -HeapAlloc dt=12 heapalloc_value=19740296 -HeapAlloc dt=12 heapalloc_value=19748488 -HeapAlloc dt=9 heapalloc_value=19756680 -HeapAlloc dt=6 heapalloc_value=19764872 -HeapAlloc dt=5 heapalloc_value=19773064 -HeapAlloc dt=6 heapalloc_value=19781256 -HeapAlloc dt=5 heapalloc_value=19789448 -HeapAlloc dt=10 heapalloc_value=19797640 -HeapAlloc dt=5 heapalloc_value=19805832 -HeapAlloc dt=6 heapalloc_value=19814024 -HeapAlloc dt=9 heapalloc_value=19822216 -HeapAlloc dt=6 heapalloc_value=19830408 -HeapAlloc dt=117 heapalloc_value=19838600 -HeapAlloc dt=17 heapalloc_value=19846792 -HeapAlloc dt=5 heapalloc_value=19854984 -HeapAlloc dt=10 heapalloc_value=19863176 -HeapAlloc dt=6 heapalloc_value=19871368 -HeapAlloc dt=6 heapalloc_value=19879560 -HeapAlloc dt=9 heapalloc_value=19887752 -HeapAlloc dt=6 heapalloc_value=19895944 -HeapAlloc dt=6 heapalloc_value=19904136 -HeapAlloc dt=5 heapalloc_value=19912328 -HeapAlloc dt=6 heapalloc_value=19920520 -HeapAlloc dt=10 heapalloc_value=19928712 -HeapAlloc dt=5 heapalloc_value=19936904 -HeapAlloc dt=6 heapalloc_value=19945096 -HeapAlloc dt=9 heapalloc_value=19953288 -HeapAlloc dt=6 heapalloc_value=19961480 -HeapAlloc dt=35 heapalloc_value=19969672 -HeapAlloc dt=7 heapalloc_value=19977864 -HeapAlloc dt=5 heapalloc_value=19986056 -HeapAlloc dt=468 heapalloc_value=19994248 -HeapAlloc dt=14 heapalloc_value=20002440 -HeapAlloc dt=6 heapalloc_value=20010632 -HeapAlloc dt=10 heapalloc_value=20018824 -HeapAlloc dt=5 heapalloc_value=20027016 -HeapAlloc dt=6 heapalloc_value=20035208 -HeapAlloc dt=11 heapalloc_value=20043400 -HeapAlloc dt=6 heapalloc_value=20051592 -HeapAlloc dt=5 heapalloc_value=20059784 -HeapAlloc dt=6 heapalloc_value=20067976 -HeapAlloc dt=5 heapalloc_value=20076168 -HeapAlloc dt=7 heapalloc_value=20084360 -HeapAlloc dt=6 heapalloc_value=20092552 -HeapAlloc dt=5 heapalloc_value=20100744 -HeapAlloc dt=6 heapalloc_value=20108936 -HeapAlloc dt=6 heapalloc_value=20117128 -HeapAlloc dt=5 heapalloc_value=20125320 -HeapAlloc dt=6 heapalloc_value=20133512 -HeapAlloc dt=6 heapalloc_value=20141704 -HeapAlloc dt=7 heapalloc_value=20149896 -HeapAlloc dt=5 heapalloc_value=20158088 -HeapAlloc dt=6 heapalloc_value=20166280 -HeapAlloc dt=5 heapalloc_value=20174472 -HeapAlloc dt=6 heapalloc_value=20182664 -HeapAlloc dt=6 heapalloc_value=20190856 -HeapAlloc dt=5 heapalloc_value=20199048 -HeapAlloc dt=5 heapalloc_value=20207240 -HeapAlloc dt=6 heapalloc_value=20215432 -HeapAlloc dt=6 heapalloc_value=20223624 -HeapAlloc dt=5 heapalloc_value=20231816 -HeapAlloc dt=6 heapalloc_value=20240008 -HeapAlloc dt=5 heapalloc_value=20248200 -HeapAlloc dt=5 heapalloc_value=20256392 -HeapAlloc dt=6 heapalloc_value=20264584 -HeapAlloc dt=5 heapalloc_value=20272776 -HeapAlloc dt=6 heapalloc_value=20280968 -HeapAlloc dt=5 heapalloc_value=20289160 -HeapAlloc dt=6 heapalloc_value=20297352 -HeapAlloc dt=5 heapalloc_value=20305544 -HeapAlloc dt=6 heapalloc_value=20313736 -HeapAlloc dt=5 heapalloc_value=20321928 -HeapAlloc dt=6 heapalloc_value=20330120 -HeapAlloc dt=5 heapalloc_value=20338312 -HeapAlloc dt=6 heapalloc_value=20346504 -HeapAlloc dt=6 heapalloc_value=20354696 -HeapAlloc dt=62 heapalloc_value=20362888 -HeapAlloc dt=7 heapalloc_value=20371080 -HeapAlloc dt=5 heapalloc_value=20379272 -HeapAlloc dt=6 heapalloc_value=20387464 -HeapAlloc dt=37 heapalloc_value=20395656 -HeapAlloc dt=7 heapalloc_value=20403848 -HeapAlloc dt=6 heapalloc_value=20412040 -HeapAlloc dt=5 heapalloc_value=20420232 -HeapAlloc dt=6 heapalloc_value=20428424 -HeapAlloc dt=5 heapalloc_value=20436616 -HeapAlloc dt=6 heapalloc_value=20444808 -HeapAlloc dt=5 heapalloc_value=20453000 -HeapAlloc dt=6 heapalloc_value=20461192 -HeapAlloc dt=5 heapalloc_value=20469384 -HeapAlloc dt=6 heapalloc_value=20477576 -HeapAlloc dt=5 heapalloc_value=20485768 -HeapAlloc dt=6 heapalloc_value=20493960 -HeapAlloc dt=5 heapalloc_value=20502152 -HeapAlloc dt=6 heapalloc_value=20510344 -HeapAlloc dt=9 heapalloc_value=20518536 -HeapAlloc dt=6 heapalloc_value=20526728 -HeapAlloc dt=5 heapalloc_value=20534920 -HeapAlloc dt=6 heapalloc_value=20543112 -HeapAlloc dt=5 heapalloc_value=20551304 -HeapAlloc dt=6 heapalloc_value=20559496 -HeapAlloc dt=5 heapalloc_value=20567688 -HeapAlloc dt=6 heapalloc_value=20575880 -HeapAlloc dt=5 heapalloc_value=20584072 -HeapAlloc dt=6 heapalloc_value=20592264 -HeapAlloc dt=38 heapalloc_value=20600456 -HeapAlloc dt=7 heapalloc_value=20608648 -HeapAlloc dt=5 heapalloc_value=20616840 -HeapAlloc dt=6 heapalloc_value=20625032 -HeapAlloc dt=5 heapalloc_value=20633224 -HeapAlloc dt=6 heapalloc_value=20641416 -HeapAlloc dt=5 heapalloc_value=20649608 -HeapAlloc dt=6 heapalloc_value=20657800 -GoBlock dt=12 reason_string=19 stack=21 -ProcStop dt=167 -ProcStart dt=17576 p=0 p_seq=29 -ProcStop dt=20 -ProcStart dt=3256 p=1 p_seq=22 -ProcStop dt=17 -ProcStart dt=16071 p=1 p_seq=23 -GoUnblock dt=21 g=1 g_seq=65 stack=0 -GoStart dt=124 g=1 g_seq=66 -HeapAlloc dt=51 heapalloc_value=22230664 -HeapAlloc dt=26 heapalloc_value=22238856 -HeapAlloc dt=16 heapalloc_value=22247048 -HeapAlloc dt=19 heapalloc_value=22255240 -HeapAlloc dt=19 heapalloc_value=22263432 -HeapAlloc dt=16 heapalloc_value=22271624 -HeapAlloc dt=16 heapalloc_value=22279816 -HeapAlloc dt=19 heapalloc_value=22288008 -HeapAlloc dt=18 heapalloc_value=22296200 -HeapAlloc dt=16 heapalloc_value=22304392 -HeapAlloc dt=12 heapalloc_value=22312584 -HeapAlloc dt=13 heapalloc_value=22320776 -HeapAlloc dt=15 heapalloc_value=22328968 -HeapAlloc dt=12 heapalloc_value=22337160 -HeapAlloc dt=6 heapalloc_value=22345352 -HeapAlloc dt=8 heapalloc_value=22353544 -HeapAlloc dt=6 heapalloc_value=22361736 -HeapAlloc dt=5 heapalloc_value=22369928 -HeapAlloc dt=25 heapalloc_value=22378120 -HeapAlloc dt=23 heapalloc_value=22386312 -HeapAlloc dt=9 heapalloc_value=22394504 -HeapAlloc dt=6 heapalloc_value=22402696 -HeapAlloc dt=5 heapalloc_value=22410888 -HeapAlloc dt=10 heapalloc_value=22419080 -HeapAlloc dt=5 heapalloc_value=22427272 -HeapAlloc dt=6 heapalloc_value=22435464 -HeapAlloc dt=5 heapalloc_value=22443656 -HeapAlloc dt=6 heapalloc_value=22451848 -HeapAlloc dt=8 heapalloc_value=22460040 -HeapAlloc dt=135 heapalloc_value=22468232 -HeapAlloc dt=8 heapalloc_value=22476424 -HeapAlloc dt=9 heapalloc_value=22484616 -HeapAlloc dt=6 heapalloc_value=22492808 -HeapAlloc dt=6 heapalloc_value=22501000 -HeapAlloc dt=6 heapalloc_value=22509192 -HeapAlloc dt=5 heapalloc_value=22517384 -HeapAlloc dt=9 heapalloc_value=22525576 -HeapAlloc dt=6 heapalloc_value=22533768 -HeapAlloc dt=6 heapalloc_value=22541960 -HeapAlloc dt=5 heapalloc_value=22550152 -HeapAlloc dt=6 heapalloc_value=22558344 -HeapAlloc dt=5 heapalloc_value=22566536 -HeapAlloc dt=6 heapalloc_value=22574728 -HeapAlloc dt=5 heapalloc_value=22582920 -HeapAlloc dt=9 heapalloc_value=22591112 -HeapAlloc dt=44 heapalloc_value=22599304 -HeapAlloc dt=7 heapalloc_value=22607496 -HeapAlloc dt=38 heapalloc_value=22615688 -HeapAlloc dt=6 heapalloc_value=22623880 -HeapAlloc dt=6 heapalloc_value=22632072 -HeapAlloc dt=6 heapalloc_value=22640264 -HeapAlloc dt=6 heapalloc_value=22648456 -HeapAlloc dt=6 heapalloc_value=22656648 -HeapAlloc dt=5 heapalloc_value=22664840 -HeapAlloc dt=6 heapalloc_value=22673032 -HeapAlloc dt=5 heapalloc_value=22681224 -HeapAlloc dt=6 heapalloc_value=22689416 -HeapAlloc dt=5 heapalloc_value=22697608 -HeapAlloc dt=6 heapalloc_value=22705800 -HeapAlloc dt=6 heapalloc_value=22713992 -HeapAlloc dt=5 heapalloc_value=22722184 -HeapAlloc dt=5 heapalloc_value=22730376 -HeapAlloc dt=6 heapalloc_value=22738568 -HeapAlloc dt=6 heapalloc_value=22746760 -HeapAlloc dt=5 heapalloc_value=22754952 -HeapAlloc dt=6 heapalloc_value=22763144 -HeapAlloc dt=6 heapalloc_value=22771336 -HeapAlloc dt=6 heapalloc_value=22779528 -HeapAlloc dt=5 heapalloc_value=22787720 -HeapAlloc dt=5 heapalloc_value=22795912 -HeapAlloc dt=6 heapalloc_value=22804104 -HeapAlloc dt=75 heapalloc_value=22812296 -HeapAlloc dt=7 heapalloc_value=22820488 -HeapAlloc dt=5 heapalloc_value=22828680 -HeapAlloc dt=6 heapalloc_value=22836872 -HeapAlloc dt=5 heapalloc_value=22845064 -HeapAlloc dt=6 heapalloc_value=22853256 -HeapAlloc dt=6 heapalloc_value=22861448 -HeapAlloc dt=5 heapalloc_value=22869640 -HeapAlloc dt=6 heapalloc_value=22877832 -HeapAlloc dt=5 heapalloc_value=22886024 -HeapAlloc dt=5 heapalloc_value=22894216 -HeapAlloc dt=6 heapalloc_value=22902408 -HeapAlloc dt=7 heapalloc_value=22910600 -HeapAlloc dt=6 heapalloc_value=22918792 -HeapAlloc dt=5 heapalloc_value=22926984 -HeapAlloc dt=6 heapalloc_value=22935176 -HeapAlloc dt=6 heapalloc_value=22943368 -HeapAlloc dt=6 heapalloc_value=22951560 -HeapAlloc dt=5 heapalloc_value=22959752 -HeapAlloc dt=6 heapalloc_value=22967944 -HeapAlloc dt=7 heapalloc_value=22976136 -HeapAlloc dt=5 heapalloc_value=22984328 -HeapAlloc dt=43 heapalloc_value=22992520 -HeapAlloc dt=7 heapalloc_value=23000712 -HeapAlloc dt=5 heapalloc_value=23008904 -HeapAlloc dt=6 heapalloc_value=23017096 -HeapAlloc dt=35 heapalloc_value=23025288 -HeapAlloc dt=7 heapalloc_value=23033480 -HeapAlloc dt=5 heapalloc_value=23041672 -HeapAlloc dt=5 heapalloc_value=23049864 -HeapAlloc dt=6 heapalloc_value=23058056 -HeapAlloc dt=5 heapalloc_value=23066248 -HeapAlloc dt=6 heapalloc_value=23074440 -HeapAlloc dt=5 heapalloc_value=23082632 -HeapAlloc dt=6 heapalloc_value=23090824 -HeapAlloc dt=5 heapalloc_value=23099016 -HeapAlloc dt=6 heapalloc_value=23107208 -HeapAlloc dt=5 heapalloc_value=23115400 -HeapAlloc dt=6 heapalloc_value=23123592 -HeapAlloc dt=5 heapalloc_value=23131784 -HeapAlloc dt=12 heapalloc_value=23139976 -HeapAlloc dt=5 heapalloc_value=23148168 -HeapAlloc dt=6 heapalloc_value=23156360 -HeapAlloc dt=5 heapalloc_value=23164552 -HeapAlloc dt=6 heapalloc_value=23172744 -HeapAlloc dt=5 heapalloc_value=23180936 -HeapAlloc dt=6 heapalloc_value=23189128 -HeapAlloc dt=5 heapalloc_value=23197320 -HeapAlloc dt=7 heapalloc_value=23205512 -HeapAlloc dt=5 heapalloc_value=23213704 -HeapAlloc dt=6 heapalloc_value=23221896 -HeapAlloc dt=38 heapalloc_value=23230088 -HeapAlloc dt=7 heapalloc_value=23238280 -HeapAlloc dt=5 heapalloc_value=23246472 -GoBlock dt=9 reason_string=19 stack=21 -ProcStop dt=164 -ProcStart dt=17494 p=0 p_seq=31 -ProcStop dt=25 -ProcStart dt=1701 p=1 p_seq=26 -ProcStop dt=16 -ProcStart dt=16748 p=2 p_seq=17 -GoUnblock dt=36 g=1 g_seq=71 stack=0 -GoStart dt=149 g=1 g_seq=72 -HeapAlloc dt=67 heapalloc_value=25302664 -HeapAlloc dt=38 heapalloc_value=25310856 -HeapAlloc dt=23 heapalloc_value=25319048 -HeapAlloc dt=17 heapalloc_value=25327240 -HeapAlloc dt=21 heapalloc_value=25335432 -HeapAlloc dt=17 heapalloc_value=25343624 -HeapAlloc dt=17 heapalloc_value=25351816 -HeapAlloc dt=16 heapalloc_value=25360008 -HeapAlloc dt=19 heapalloc_value=25368200 -HeapAlloc dt=16 heapalloc_value=25376392 -HeapAlloc dt=16 heapalloc_value=25384584 -HeapAlloc dt=16 heapalloc_value=25392776 -HeapAlloc dt=17 heapalloc_value=25400968 -HeapAlloc dt=16 heapalloc_value=25409160 -HeapAlloc dt=9 heapalloc_value=25417352 -HeapAlloc dt=9 heapalloc_value=25425544 -HeapAlloc dt=9 heapalloc_value=25433736 -HeapAlloc dt=10 heapalloc_value=25441928 -HeapAlloc dt=9 heapalloc_value=25450120 -HeapAlloc dt=10 heapalloc_value=25458312 -HeapAlloc dt=9 heapalloc_value=25466504 -HeapAlloc dt=6 heapalloc_value=25474696 -HeapAlloc dt=5 heapalloc_value=25482888 -HeapAlloc dt=6 heapalloc_value=25491080 -HeapAlloc dt=9 heapalloc_value=25499272 -HeapAlloc dt=6 heapalloc_value=25507464 -HeapAlloc dt=8 heapalloc_value=25515656 -HeapAlloc dt=7 heapalloc_value=25523848 -HeapAlloc dt=10 heapalloc_value=25532040 -HeapAlloc dt=9 heapalloc_value=25540232 -HeapAlloc dt=102 heapalloc_value=25548424 -HeapAlloc dt=7 heapalloc_value=25556616 -HeapAlloc dt=10 heapalloc_value=25564808 -HeapAlloc dt=5 heapalloc_value=25573000 -HeapAlloc dt=5 heapalloc_value=25581192 -HeapAlloc dt=36 heapalloc_value=25589384 -HeapAlloc dt=8 heapalloc_value=25597576 -HeapAlloc dt=5 heapalloc_value=25605768 -HeapAlloc dt=43 heapalloc_value=25613960 -HeapAlloc dt=7 heapalloc_value=25622152 -HeapAlloc dt=10 heapalloc_value=25630344 -HeapAlloc dt=6 heapalloc_value=25638536 -HeapAlloc dt=6 heapalloc_value=25646728 -HeapAlloc dt=6 heapalloc_value=25654920 -HeapAlloc dt=7 heapalloc_value=25663112 -HeapAlloc dt=5 heapalloc_value=25671304 -HeapAlloc dt=6 heapalloc_value=25679496 -HeapAlloc dt=41 heapalloc_value=25687688 -HeapAlloc dt=13 heapalloc_value=25695880 -HeapAlloc dt=5 heapalloc_value=25704072 -HeapAlloc dt=6 heapalloc_value=25712264 -HeapAlloc dt=13 heapalloc_value=25720456 -HeapAlloc dt=13 heapalloc_value=25728648 -HeapAlloc dt=5 heapalloc_value=25736840 -HeapAlloc dt=6 heapalloc_value=25745032 -HeapAlloc dt=6 heapalloc_value=25753224 -HeapAlloc dt=9 heapalloc_value=25761416 -HeapAlloc dt=6 heapalloc_value=25769608 -HeapAlloc dt=5 heapalloc_value=25777800 -HeapAlloc dt=6 heapalloc_value=25785992 -HeapAlloc dt=5 heapalloc_value=25794184 -HeapAlloc dt=6 heapalloc_value=25802376 -HeapAlloc dt=5 heapalloc_value=25810568 -HeapAlloc dt=6 heapalloc_value=25818760 -HeapAlloc dt=10 heapalloc_value=25826952 -HeapAlloc dt=6 heapalloc_value=25835144 -HeapAlloc dt=6 heapalloc_value=25843336 -HeapAlloc dt=5 heapalloc_value=25851528 -HeapAlloc dt=6 heapalloc_value=25859720 -HeapAlloc dt=5 heapalloc_value=25867912 -HeapAlloc dt=6 heapalloc_value=25876104 -HeapAlloc dt=6 heapalloc_value=25884296 -HeapAlloc dt=7 heapalloc_value=25892488 -HeapAlloc dt=6 heapalloc_value=25900680 -HeapAlloc dt=5 heapalloc_value=25908872 -HeapAlloc dt=6 heapalloc_value=25917064 -HeapAlloc dt=6 heapalloc_value=25925256 -HeapAlloc dt=5 heapalloc_value=25933448 -HeapAlloc dt=6 heapalloc_value=25941640 -HeapAlloc dt=6 heapalloc_value=25949832 -HeapAlloc dt=6 heapalloc_value=25958024 -HeapAlloc dt=5 heapalloc_value=25966216 -HeapAlloc dt=6 heapalloc_value=25974408 -HeapAlloc dt=5 heapalloc_value=25982600 -HeapAlloc dt=6 heapalloc_value=25990792 -HeapAlloc dt=6 heapalloc_value=25998984 -HeapAlloc dt=5 heapalloc_value=26007176 -HeapAlloc dt=6 heapalloc_value=26015368 -HeapAlloc dt=6 heapalloc_value=26023560 -HeapAlloc dt=6 heapalloc_value=26031752 -HeapAlloc dt=5 heapalloc_value=26039944 -HeapAlloc dt=6 heapalloc_value=26048136 -HeapAlloc dt=5 heapalloc_value=26056328 -HeapAlloc dt=6 heapalloc_value=26064520 -HeapAlloc dt=94 heapalloc_value=26072712 -HeapAlloc dt=7 heapalloc_value=26080904 -HeapAlloc dt=5 heapalloc_value=26089096 -HeapAlloc dt=6 heapalloc_value=26097288 -HeapAlloc dt=6 heapalloc_value=26105480 -HeapAlloc dt=5 heapalloc_value=26113672 -HeapAlloc dt=6 heapalloc_value=26121864 -HeapAlloc dt=6 heapalloc_value=26130056 -HeapAlloc dt=5 heapalloc_value=26138248 -HeapAlloc dt=6 heapalloc_value=26146440 -HeapAlloc dt=6 heapalloc_value=26154632 -HeapAlloc dt=5 heapalloc_value=26162824 -HeapAlloc dt=1696 heapalloc_value=26171016 -HeapAlloc dt=7 heapalloc_value=26179208 -HeapAlloc dt=6 heapalloc_value=26187400 -HeapAlloc dt=5 heapalloc_value=26195592 -HeapAlloc dt=6 heapalloc_value=26203784 -HeapAlloc dt=5 heapalloc_value=26211976 -HeapAlloc dt=47 heapalloc_value=26220168 -HeapAlloc dt=8 heapalloc_value=26228360 -HeapAlloc dt=5 heapalloc_value=26236552 -HeapAlloc dt=6 heapalloc_value=26244744 -HeapAlloc dt=6 heapalloc_value=26252936 -HeapAlloc dt=5 heapalloc_value=26261128 -HeapAlloc dt=6 heapalloc_value=26269320 -HeapAlloc dt=5 heapalloc_value=26277512 -HeapAlloc dt=6 heapalloc_value=26285704 -HeapAlloc dt=6 heapalloc_value=26293896 -HeapAlloc dt=5 heapalloc_value=26302088 -HeapAlloc dt=6 heapalloc_value=26310280 -HeapAlloc dt=6 heapalloc_value=26318472 -HeapAlloc dt=30 heapalloc_value=26326360 -HeapAlloc dt=30 heapalloc_value=26334536 -HeapAlloc dt=24 heapalloc_value=26336904 -GoCreate dt=72 new_g=34 new_stack=47 stack=48 -GoCreate dt=183 new_g=35 new_stack=47 stack=48 -GoCreate dt=15 new_g=36 new_stack=47 stack=48 -GoCreate dt=12 new_g=37 new_stack=47 stack=48 -GoCreate dt=14 new_g=38 new_stack=47 stack=48 -HeapAlloc dt=25 heapalloc_value=26344200 -GoCreate dt=9 new_g=39 new_stack=47 stack=48 -GoCreate dt=13 new_g=40 new_stack=47 stack=48 -GoCreate dt=4 new_g=41 new_stack=47 stack=48 -HeapAlloc dt=17 heapalloc_value=26351912 -GoBlock dt=15 reason_string=10 stack=49 -GoStart dt=5 g=41 g_seq=1 -GoStop dt=307427 reason_string=16 stack=51 -GoStart dt=34 g=41 g_seq=2 -GoStop dt=315328 reason_string=16 stack=50 -GoStart dt=10 g=41 g_seq=3 -GoDestroy dt=158464 -ProcStop dt=40 -EventBatch gen=1 m=1709039 time=7689670530705 size=53 -GoUnblock dt=117 g=4 g_seq=3 stack=0 -GoUnblock dt=157408 g=4 g_seq=7 stack=0 -GoUnblock dt=157553 g=4 g_seq=11 stack=0 -ProcSteal dt=947714 p=7 p_seq=9 m=1709048 -ProcSteal dt=646055 p=7 p_seq=13 m=1709046 -ProcSteal dt=5677 p=5 p_seq=11 m=1709046 -ProcSteal dt=1312 p=6 p_seq=9 m=1709048 -EventBatch gen=1 m=1709038 time=7689670147327 size=336 -ProcStatus dt=56 p=0 pstatus=1 -GoStatus dt=4 g=1 m=1709038 gstatus=2 -ProcsChange dt=184 procs_value=8 stack=1 -STWBegin dt=81 kind_string=21 stack=2 -HeapGoal dt=5 heapgoal_value=4194304 -ProcStatus dt=2 p=1 pstatus=2 -ProcStatus dt=1 p=2 pstatus=2 -ProcStatus dt=1 p=3 pstatus=2 -ProcStatus dt=1 p=4 pstatus=2 -ProcStatus dt=1 p=5 pstatus=2 -ProcStatus dt=1 p=6 pstatus=2 -ProcStatus dt=1 p=7 pstatus=2 -ProcsChange dt=51 procs_value=8 stack=3 -STWEnd dt=74 -GoCreate dt=216 new_g=6 new_stack=4 stack=5 -HeapAlloc dt=174 heapalloc_value=2752512 -GoCreate dt=140 new_g=7 new_stack=6 stack=7 -HeapAlloc dt=16 heapalloc_value=2760704 -GoCreate dt=11 new_g=8 new_stack=8 stack=9 -GoCreate dt=197 new_g=9 new_stack=10 stack=11 -GoCreate dt=18 new_g=10 new_stack=12 stack=13 -GoBlock dt=159 reason_string=10 stack=14 -GoStart dt=10 g=10 g_seq=1 -GoStop dt=224159 reason_string=16 stack=19 -GoStart dt=105 g=10 g_seq=2 -GoUnblock dt=88262 g=1 g_seq=1 stack=20 -GoDestroy dt=111 -GoStart dt=10 g=1 g_seq=2 -GoBlock dt=18 reason_string=19 stack=21 -ProcStop dt=177 -ProcStart dt=22598 p=0 p_seq=2 -ProcStop dt=20 -ProcStart dt=30 p=2 p_seq=2 -ProcStop dt=1158 -ProcStart dt=1116 p=0 p_seq=4 -GoUnblock dt=19 g=25 g_seq=2 stack=0 -GoStart dt=130 g=25 g_seq=3 -GoLabel dt=1 label_string=2 -GoBlock dt=1809 reason_string=15 stack=27 -ProcStop dt=35 -ProcStart dt=45680 p=3 p_seq=4 -HeapAlloc dt=46 heapalloc_value=7659248 -HeapAlloc dt=48 heapalloc_value=7663408 -HeapAlloc dt=6065 heapalloc_value=7876144 -GoStart dt=2865 g=4 g_seq=6 -GoBlock dt=31 reason_string=15 stack=32 -ProcStop dt=49 -ProcStart dt=1490 p=3 p_seq=5 -ProcStop dt=29 -ProcStart dt=2071 p=1 p_seq=10 -ProcStop dt=21 -ProcStart dt=143297 p=2 p_seq=13 -GoUnblock dt=21 g=22 g_seq=6 stack=0 -GoStart dt=177 g=22 g_seq=7 -GoLabel dt=2 label_string=2 -GoBlock dt=2058 reason_string=15 stack=27 -ProcStop dt=2352 -ProcStart dt=162401 p=5 p_seq=2 -HeapAlloc dt=51 heapalloc_value=26353960 -HeapAlloc dt=42 heapalloc_value=26360360 -HeapAlloc dt=6510 heapalloc_value=26367784 -GoStart dt=1039 g=40 g_seq=1 -GoStop dt=297000 reason_string=16 stack=50 -GoStart dt=15 g=40 g_seq=2 -GoStop dt=315522 reason_string=16 stack=50 -GoStart dt=7 g=40 g_seq=3 -GoDestroy dt=168735 -ProcStop dt=43 -ProcStart dt=799345 p=6 p_seq=6 -ProcStop dt=33 -ProcStart dt=1506 p=6 p_seq=10 -ProcStop dt=26 -ProcStart dt=18634 p=7 p_seq=33 -ProcStop dt=34 -EventBatch gen=1 m=18446744073709551615 time=7689672466616 size=28 -GoStatus dt=61 g=2 m=18446744073709551615 gstatus=4 -GoStatus dt=3 g=5 m=18446744073709551615 gstatus=4 -EventBatch gen=1 m=18446744073709551615 time=7689672467258 size=4540 -Stacks -Stack id=86 nframes=7 - pc=4754167 func=24 file=25 line=736 - pc=4814861 func=26 file=27 line=181 - pc=4814837 func=28 file=29 line=736 - pc=4814480 func=30 file=29 line=160 - pc=4996132 func=31 file=32 line=55 - pc=5032836 func=33 file=34 line=179 - pc=5078635 func=35 file=36 line=73 -Stack id=77 nframes=16 - pc=4756520 func=37 file=25 line=1442 - pc=4751813 func=38 file=27 line=298 - pc=4996815 func=39 file=40 line=59 - pc=5049499 func=41 file=42 line=124 - pc=5048282 func=43 file=42 line=70 - pc=5021687 func=44 file=45 line=154 - pc=5057739 func=46 file=47 line=85 - pc=5057380 func=48 file=47 line=75 - pc=5057381 func=49 file=47 line=71 - pc=4965884 func=50 file=51 line=651 - pc=4964173 func=52 file=51 line=616 - pc=4961811 func=53 file=51 line=517 - pc=4960409 func=54 file=51 line=508 - pc=4958646 func=55 file=51 line=434 - pc=4958647 func=56 file=51 line=401 - pc=5078500 func=35 file=36 line=68 -Stack id=13 nframes=1 - pc=5077820 func=35 file=36 line=28 -Stack id=65 nframes=2 - pc=4224086 func=57 file=58 line=145 - pc=5080123 func=59 file=36 line=94 -Stack id=21 nframes=3 - pc=4640852 func=60 file=61 line=195 - pc=5081128 func=62 file=36 line=125 - pc=5077843 func=35 file=36 line=32 -Stack id=11 nframes=1 - pc=5077754 func=35 file=36 line=27 -Stack id=10 nframes=1 - pc=5080288 func=63 file=36 line=97 -Stack id=44 nframes=2 - pc=4354430 func=64 file=65 line=408 - pc=4354396 func=66 file=67 line=318 -Stack id=51 nframes=3 - pc=4658586 func=68 file=69 line=53 - pc=5080816 func=70 file=36 line=110 - pc=5079149 func=71 file=36 line=40 -Stack id=36 nframes=7 - pc=4310007 func=72 file=73 line=806 - pc=4326610 func=74 file=75 line=562 - pc=4258131 func=76 file=77 line=1353 - pc=4255947 func=78 file=77 line=1025 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=57 nframes=5 - pc=4753924 func=81 file=25 line=432 - pc=4744496 func=82 file=83 line=118 - pc=4823012 func=84 file=85 line=218 - pc=4824373 func=86 file=87 line=21 - pc=5079543 func=59 file=36 line=82 -Stack id=16 nframes=7 - pc=4754618 func=88 file=25 line=964 - pc=4816103 func=89 file=27 line=209 - pc=4816095 func=28 file=29 line=736 - pc=4815648 func=90 file=29 line=380 - pc=4821008 func=91 file=92 line=46 - pc=4821000 func=93 file=94 line=189 - pc=5077114 func=95 file=96 line=134 -Stack id=63 nframes=1 - pc=5080224 func=97 file=36 line=89 -Stack id=2 nframes=3 - pc=4567556 func=98 file=99 line=239 - pc=5076805 func=100 file=96 line=125 - pc=5077595 func=35 file=36 line=20 -Stack id=80 nframes=15 - pc=4998478 func=101 file=29 line=683 - pc=4998507 func=39 file=40 line=141 - pc=5049499 func=41 file=42 line=124 - pc=5048282 func=43 file=42 line=70 - pc=5021687 func=44 file=45 line=154 - pc=5057739 func=46 file=47 line=85 - pc=5057380 func=48 file=47 line=75 - pc=5057381 func=49 file=47 line=71 - pc=4965884 func=50 file=51 line=651 - pc=4964173 func=52 file=51 line=616 - pc=4961811 func=53 file=51 line=517 - pc=4960409 func=54 file=51 line=508 - pc=4958646 func=55 file=51 line=434 - pc=4958647 func=56 file=51 line=401 - pc=5078500 func=35 file=36 line=68 -Stack id=47 nframes=1 - pc=5079072 func=71 file=36 line=38 -Stack id=55 nframes=2 - pc=4227441 func=102 file=58 line=442 - pc=5078106 func=35 file=36 line=48 -Stack id=5 nframes=4 - pc=4576789 func=103 file=104 line=44 - pc=4567832 func=98 file=99 line=258 - pc=5076805 func=100 file=96 line=125 - pc=5077595 func=35 file=36 line=20 -Stack id=46 nframes=3 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=8 nframes=1 - pc=5077056 func=95 file=96 line=128 -Stack id=24 nframes=6 - pc=4315620 func=105 file=73 line=1249 - pc=4308860 func=106 file=73 line=662 - pc=4257811 func=78 file=77 line=1308 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=37 nframes=1 - pc=4316644 func=107 file=73 line=1469 -Stack id=79 nframes=5 - pc=4817209 func=108 file=29 line=611 - pc=5000296 func=109 file=40 line=172 - pc=5058941 func=110 file=47 line=159 - pc=5055951 func=111 file=112 line=327 - pc=5078747 func=113 file=36 line=59 -Stack id=17 nframes=1 - pc=5077124 func=95 file=96 line=130 -Stack id=41 nframes=2 - pc=4310763 func=72 file=73 line=816 - pc=4316644 func=107 file=73 line=1469 -Stack id=33 nframes=7 - pc=4328420 func=114 file=75 line=747 - pc=4326674 func=74 file=75 line=587 - pc=4258131 func=76 file=77 line=1353 - pc=4255947 func=78 file=77 line=1025 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=29 nframes=6 - pc=4644903 func=115 file=116 line=474 - pc=4309092 func=106 file=73 line=683 - pc=4257811 func=78 file=77 line=1308 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=73 nframes=10 - pc=4756296 func=117 file=25 line=1432 - pc=4751685 func=118 file=27 line=290 - pc=5051812 func=119 file=42 line=167 - pc=5048051 func=43 file=42 line=57 - pc=5021687 func=44 file=45 line=154 - pc=5059172 func=120 file=47 line=189 - pc=4967876 func=121 file=47 line=179 - pc=4967838 func=122 file=51 line=734 - pc=4968614 func=123 file=51 line=808 - pc=5078215 func=35 file=36 line=53 -Stack id=92 nframes=2 - pc=4640852 func=60 file=61 line=195 - pc=5078782 func=113 file=36 line=63 -Stack id=32 nframes=2 - pc=4344589 func=124 file=125 line=425 - pc=4346072 func=126 file=125 line=658 -Stack id=45 nframes=1 - pc=5077843 func=35 file=36 line=32 -Stack id=62 nframes=3 - pc=4754167 func=24 file=25 line=736 - pc=5079848 func=26 file=27 line=181 - pc=5079785 func=59 file=36 line=90 -Stack id=15 nframes=3 - pc=4227441 func=102 file=58 line=442 - pc=4574090 func=127 file=99 line=937 - pc=4576964 func=128 file=104 line=56 -Stack id=28 nframes=4 - pc=4257811 func=78 file=77 line=1308 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=64 nframes=7 - pc=4754618 func=88 file=25 line=964 - pc=4816103 func=89 file=27 line=209 - pc=4816095 func=28 file=29 line=736 - pc=4815648 func=90 file=29 line=380 - pc=4821008 func=91 file=92 line=46 - pc=4821000 func=93 file=94 line=189 - pc=5080260 func=97 file=36 line=89 -Stack id=91 nframes=8 - pc=4757394 func=129 file=25 line=1488 - pc=4819063 func=130 file=27 line=462 - pc=4819041 func=131 file=132 line=17 - pc=5060022 func=133 file=134 line=21 - pc=5055784 func=135 file=112 line=257 - pc=5058972 func=110 file=47 line=163 - pc=5055951 func=111 file=112 line=327 - pc=5078747 func=113 file=36 line=59 -Stack id=95 nframes=8 - pc=4753732 func=136 file=25 line=335 - pc=4813424 func=137 file=138 line=24 - pc=4813394 func=139 file=29 line=81 - pc=4811154 func=140 file=141 line=213 - pc=4813572 func=142 file=29 line=104 - pc=4996049 func=143 file=32 line=37 - pc=5033653 func=144 file=34 line=203 - pc=5078651 func=35 file=36 line=74 -Stack id=22 nframes=4 - pc=4257811 func=78 file=77 line=1308 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=56 nframes=5 - pc=4753924 func=81 file=25 line=432 - pc=4744422 func=82 file=83 line=106 - pc=4823012 func=84 file=85 line=218 - pc=4824373 func=86 file=87 line=21 - pc=5079543 func=59 file=36 line=82 -Stack id=60 nframes=5 - pc=4753924 func=81 file=25 line=432 - pc=4744422 func=82 file=83 line=106 - pc=4813961 func=145 file=29 line=129 - pc=5079772 func=146 file=85 line=90 - pc=5079785 func=59 file=36 line=90 -Stack id=38 nframes=2 - pc=4310679 func=72 file=73 line=914 - pc=4316644 func=107 file=73 line=1469 -Stack id=52 nframes=3 - pc=4708004 func=147 file=148 line=81 - pc=5079238 func=149 file=148 line=87 - pc=5079164 func=71 file=36 line=41 -Stack id=20 nframes=3 - pc=4708004 func=147 file=148 line=81 - pc=5080678 func=149 file=148 line=87 - pc=5080600 func=150 file=36 line=105 -Stack id=67 nframes=19 - pc=4752943 func=151 file=25 line=98 - pc=4822218 func=152 file=153 line=280 - pc=4822195 func=154 file=155 line=15 - pc=4823409 func=156 file=85 line=272 - pc=4821405 func=157 file=94 line=374 - pc=5042404 func=158 file=94 line=354 - pc=5042391 func=159 file=160 line=76 - pc=5047095 func=161 file=162 line=35 - pc=5068462 func=163 file=34 line=373 - pc=4703265 func=164 file=165 line=74 - pc=5034315 func=166 file=165 line=65 - pc=5034286 func=167 file=34 line=373 - pc=5047998 func=43 file=42 line=57 - pc=5021687 func=44 file=45 line=154 - pc=5059172 func=120 file=47 line=189 - pc=4967876 func=121 file=47 line=179 - pc=4967838 func=122 file=51 line=734 - pc=4968614 func=123 file=51 line=808 - pc=5078215 func=35 file=36 line=53 -Stack id=84 nframes=15 - pc=4757394 func=129 file=25 line=1488 - pc=4819063 func=130 file=27 line=462 - pc=4819041 func=131 file=132 line=17 - pc=5059867 func=133 file=134 line=18 - pc=5055784 func=135 file=112 line=257 - pc=5058352 func=46 file=47 line=121 - pc=5057380 func=48 file=47 line=75 - pc=5057381 func=49 file=47 line=71 - pc=4965884 func=50 file=51 line=651 - pc=4964173 func=52 file=51 line=616 - pc=4961811 func=53 file=51 line=517 - pc=4960409 func=54 file=51 line=508 - pc=4958646 func=55 file=51 line=434 - pc=4958647 func=56 file=51 line=401 - pc=5078500 func=35 file=36 line=68 -Stack id=74 nframes=9 - pc=4755428 func=168 file=25 line=1213 - pc=5051952 func=119 file=42 line=170 - pc=5048051 func=43 file=42 line=57 - pc=5021687 func=44 file=45 line=154 - pc=5059172 func=120 file=47 line=189 - pc=4967876 func=121 file=47 line=179 - pc=4967838 func=122 file=51 line=734 - pc=4968614 func=123 file=51 line=808 - pc=5078215 func=35 file=36 line=53 -Stack id=50 nframes=1 - pc=5079149 func=71 file=36 line=40 -Stack id=14 nframes=2 - pc=4708263 func=169 file=148 line=116 - pc=5077833 func=35 file=36 line=29 -Stack id=27 nframes=2 - pc=4437613 func=170 file=65 line=402 - pc=4316040 func=107 file=73 line=1333 -Stack id=30 nframes=5 - pc=4309402 func=106 file=73 line=745 - pc=4257811 func=78 file=77 line=1308 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=75 nframes=1 - pc=5078720 func=113 file=36 line=58 -Stack id=88 nframes=8 - pc=4757394 func=129 file=25 line=1488 - pc=4819063 func=130 file=27 line=462 - pc=4819041 func=131 file=132 line=17 - pc=5059594 func=171 file=172 line=15 - pc=5055722 func=135 file=112 line=251 - pc=5058972 func=110 file=47 line=163 - pc=5055951 func=111 file=112 line=327 - pc=5078747 func=113 file=36 line=59 -Stack id=70 nframes=21 - pc=4754167 func=24 file=25 line=736 - pc=4814861 func=26 file=27 line=181 - pc=4814837 func=28 file=29 line=736 - pc=4814480 func=30 file=29 line=160 - pc=4820817 func=173 file=92 line=29 - pc=4820809 func=174 file=94 line=118 - pc=4742703 func=175 file=176 line=335 - pc=5041967 func=177 file=176 line=354 - pc=5041927 func=178 file=160 line=55 - pc=5047143 func=161 file=162 line=40 - pc=5068462 func=163 file=34 line=373 - pc=4703265 func=164 file=165 line=74 - pc=5034315 func=166 file=165 line=65 - pc=5034286 func=167 file=34 line=373 - pc=5047998 func=43 file=42 line=57 - pc=5021687 func=44 file=45 line=154 - pc=5059172 func=120 file=47 line=189 - pc=4967876 func=121 file=47 line=179 - pc=4967838 func=122 file=51 line=734 - pc=4968614 func=123 file=51 line=808 - pc=5078215 func=35 file=36 line=53 -Stack id=25 nframes=7 - pc=4227441 func=102 file=58 line=442 - pc=4315507 func=105 file=73 line=1259 - pc=4308860 func=106 file=73 line=662 - pc=4257811 func=78 file=77 line=1308 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=58 nframes=5 - pc=4753924 func=81 file=25 line=432 - pc=4744422 func=82 file=83 line=106 - pc=4823012 func=84 file=85 line=218 - pc=4824408 func=86 file=87 line=21 - pc=5079543 func=59 file=36 line=82 -Stack id=69 nframes=19 - pc=4753924 func=81 file=25 line=432 - pc=4744496 func=82 file=83 line=118 - pc=4823012 func=84 file=85 line=218 - pc=4823631 func=156 file=85 line=301 - pc=4821405 func=157 file=94 line=374 - pc=5042404 func=158 file=94 line=354 - pc=5042391 func=159 file=160 line=76 - pc=5047095 func=161 file=162 line=35 - pc=5068462 func=163 file=34 line=373 - pc=4703265 func=164 file=165 line=74 - pc=5034315 func=166 file=165 line=65 - pc=5034286 func=167 file=34 line=373 - pc=5047998 func=43 file=42 line=57 - pc=5021687 func=44 file=45 line=154 - pc=5059172 func=120 file=47 line=189 - pc=4967876 func=121 file=47 line=179 - pc=4967838 func=122 file=51 line=734 - pc=4968614 func=123 file=51 line=808 - pc=5078215 func=35 file=36 line=53 -Stack id=83 nframes=15 - pc=4757394 func=129 file=25 line=1488 - pc=4819063 func=130 file=27 line=462 - pc=4819041 func=131 file=132 line=17 - pc=5054762 func=179 file=180 line=88 - pc=5055769 func=135 file=112 line=256 - pc=5058352 func=46 file=47 line=121 - pc=5057380 func=48 file=47 line=75 - pc=5057381 func=49 file=47 line=71 - pc=4965884 func=50 file=51 line=651 - pc=4964173 func=52 file=51 line=616 - pc=4961811 func=53 file=51 line=517 - pc=4960409 func=54 file=51 line=508 - pc=4958646 func=55 file=51 line=434 - pc=4958647 func=56 file=51 line=401 - pc=5078500 func=35 file=36 line=68 -Stack id=43 nframes=9 - pc=4368154 func=181 file=182 line=958 - pc=4293585 func=183 file=184 line=254 - pc=4293175 func=185 file=184 line=170 - pc=4290674 func=186 file=187 line=182 - pc=4255364 func=188 file=77 line=948 - pc=4256932 func=78 file=77 line=1149 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=78 nframes=8 - pc=4756062 func=189 file=25 line=1421 - pc=4750293 func=190 file=153 line=684 - pc=4818215 func=191 file=192 line=17 - pc=4816989 func=108 file=29 line=602 - pc=5000296 func=109 file=40 line=172 - pc=5058941 func=110 file=47 line=159 - pc=5055951 func=111 file=112 line=327 - pc=5078747 func=113 file=36 line=59 -Stack id=71 nframes=20 - pc=4753732 func=136 file=25 line=335 - pc=4813424 func=137 file=138 line=24 - pc=4813394 func=139 file=29 line=81 - pc=4811154 func=140 file=141 line=213 - pc=4813572 func=142 file=29 line=104 - pc=4823895 func=193 file=85 line=315 - pc=5047564 func=194 file=92 line=23 - pc=5047547 func=195 file=160 line=23 - pc=5047406 func=161 file=162 line=53 - pc=5068462 func=163 file=34 line=373 - pc=4703265 func=164 file=165 line=74 - pc=5034315 func=166 file=165 line=65 - pc=5034286 func=167 file=34 line=373 - pc=5047998 func=43 file=42 line=57 - pc=5021687 func=44 file=45 line=154 - pc=5059172 func=120 file=47 line=189 - pc=4967876 func=121 file=47 line=179 - pc=4967838 func=122 file=51 line=734 - pc=4968614 func=123 file=51 line=808 - pc=5078215 func=35 file=36 line=53 -Stack id=3 nframes=4 - pc=4446827 func=196 file=65 line=1369 - pc=4567827 func=98 file=99 line=256 - pc=5076805 func=100 file=96 line=125 - pc=5077595 func=35 file=36 line=20 -Stack id=35 nframes=2 - pc=4310007 func=72 file=73 line=806 - pc=4316644 func=107 file=73 line=1469 -Stack id=6 nframes=1 - pc=4573664 func=197 file=99 line=877 -Stack id=19 nframes=1 - pc=5080585 func=150 file=36 line=104 -Stack id=54 nframes=1 - pc=5078085 func=35 file=36 line=47 -Stack id=82 nframes=15 - pc=4757394 func=129 file=25 line=1488 - pc=4819063 func=130 file=27 line=462 - pc=4819041 func=131 file=132 line=17 - pc=5059594 func=171 file=172 line=15 - pc=5055722 func=135 file=112 line=251 - pc=5058352 func=46 file=47 line=121 - pc=5057380 func=48 file=47 line=75 - pc=5057381 func=49 file=47 line=71 - pc=4965884 func=50 file=51 line=651 - pc=4964173 func=52 file=51 line=616 - pc=4961811 func=53 file=51 line=517 - pc=4960409 func=54 file=51 line=508 - pc=4958646 func=55 file=51 line=434 - pc=4958647 func=56 file=51 line=401 - pc=5078500 func=35 file=36 line=68 -Stack id=90 nframes=8 - pc=4757394 func=129 file=25 line=1488 - pc=4819063 func=130 file=27 line=462 - pc=4819041 func=131 file=132 line=17 - pc=5059867 func=133 file=134 line=18 - pc=5055784 func=135 file=112 line=257 - pc=5058972 func=110 file=47 line=163 - pc=5055951 func=111 file=112 line=327 - pc=5078747 func=113 file=36 line=59 -Stack id=61 nframes=5 - pc=4753924 func=81 file=25 line=432 - pc=4744496 func=82 file=83 line=118 - pc=4813961 func=145 file=29 line=129 - pc=5079772 func=146 file=85 line=90 - pc=5079785 func=59 file=36 line=90 -Stack id=23 nframes=1 - pc=4315808 func=107 file=73 line=1298 -Stack id=12 nframes=1 - pc=5080512 func=150 file=36 line=102 -Stack id=68 nframes=19 - pc=4753924 func=81 file=25 line=432 - pc=4744422 func=82 file=83 line=106 - pc=4823012 func=84 file=85 line=218 - pc=4823631 func=156 file=85 line=301 - pc=4821405 func=157 file=94 line=374 - pc=5042404 func=158 file=94 line=354 - pc=5042391 func=159 file=160 line=76 - pc=5047095 func=161 file=162 line=35 - pc=5068462 func=163 file=34 line=373 - pc=4703265 func=164 file=165 line=74 - pc=5034315 func=166 file=165 line=65 - pc=5034286 func=167 file=34 line=373 - pc=5047998 func=43 file=42 line=57 - pc=5021687 func=44 file=45 line=154 - pc=5059172 func=120 file=47 line=189 - pc=4967876 func=121 file=47 line=179 - pc=4967838 func=122 file=51 line=734 - pc=4968614 func=123 file=51 line=808 - pc=5078215 func=35 file=36 line=53 -Stack id=4 nframes=1 - pc=4576896 func=128 file=104 line=44 -Stack id=66 nframes=6 - pc=5021687 func=44 file=45 line=154 - pc=5059172 func=120 file=47 line=189 - pc=4967876 func=121 file=47 line=179 - pc=4967838 func=122 file=51 line=734 - pc=4968614 func=123 file=51 line=808 - pc=5078215 func=35 file=36 line=53 -Stack id=81 nframes=16 - pc=4757147 func=198 file=25 line=1478 - pc=4752076 func=199 file=27 line=313 - pc=4998549 func=39 file=40 line=149 - pc=5049499 func=41 file=42 line=124 - pc=5048282 func=43 file=42 line=70 - pc=5021687 func=44 file=45 line=154 - pc=5057739 func=46 file=47 line=85 - pc=5057380 func=48 file=47 line=75 - pc=5057381 func=49 file=47 line=71 - pc=4965884 func=50 file=51 line=651 - pc=4964173 func=52 file=51 line=616 - pc=4961811 func=53 file=51 line=517 - pc=4960409 func=54 file=51 line=508 - pc=4958646 func=55 file=51 line=434 - pc=4958647 func=56 file=51 line=401 - pc=5078500 func=35 file=36 line=68 -Stack id=87 nframes=4 - pc=4814791 func=30 file=29 line=164 - pc=4996132 func=31 file=32 line=55 - pc=5032836 func=33 file=34 line=179 - pc=5078635 func=35 file=36 line=73 -Stack id=85 nframes=15 - pc=4757394 func=129 file=25 line=1488 - pc=4819063 func=130 file=27 line=462 - pc=4819041 func=131 file=132 line=17 - pc=5060022 func=133 file=134 line=21 - pc=5055784 func=135 file=112 line=257 - pc=5058352 func=46 file=47 line=121 - pc=5057380 func=48 file=47 line=75 - pc=5057381 func=49 file=47 line=71 - pc=4965884 func=50 file=51 line=651 - pc=4964173 func=52 file=51 line=616 - pc=4961811 func=53 file=51 line=517 - pc=4960409 func=54 file=51 line=508 - pc=4958646 func=55 file=51 line=434 - pc=4958647 func=56 file=51 line=401 - pc=5078500 func=35 file=36 line=68 -Stack id=39 nframes=4 - pc=4644903 func=115 file=116 line=474 - pc=4311677 func=200 file=73 line=964 - pc=4310756 func=72 file=73 line=926 - pc=4316644 func=107 file=73 line=1469 -Stack id=31 nframes=7 - pc=4585153 func=201 file=202 line=383 - pc=4326396 func=74 file=75 line=534 - pc=4258131 func=76 file=77 line=1353 - pc=4255947 func=78 file=77 line=1025 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=89 nframes=8 - pc=4757394 func=129 file=25 line=1488 - pc=4819063 func=130 file=27 line=462 - pc=4819041 func=131 file=132 line=17 - pc=5054762 func=179 file=180 line=88 - pc=5055769 func=135 file=112 line=256 - pc=5058972 func=110 file=47 line=163 - pc=5055951 func=111 file=112 line=327 - pc=5078747 func=113 file=36 line=59 -Stack id=53 nframes=1 - pc=5079488 func=59 file=36 line=81 -Stack id=18 nframes=3 - pc=4227441 func=102 file=58 line=442 - pc=4574090 func=127 file=99 line=937 - pc=4573703 func=197 file=99 line=880 -Stack id=48 nframes=1 - pc=5077881 func=35 file=36 line=38 -Stack id=94 nframes=8 - pc=4753732 func=136 file=25 line=335 - pc=4813424 func=137 file=138 line=24 - pc=4813394 func=139 file=29 line=81 - pc=4811154 func=140 file=141 line=213 - pc=4813572 func=142 file=29 line=104 - pc=4996049 func=143 file=32 line=37 - pc=5033653 func=144 file=34 line=203 - pc=5078837 func=113 file=36 line=66 -Stack id=42 nframes=9 - pc=4584693 func=203 file=202 line=357 - pc=4355940 func=204 file=67 line=522 - pc=4292956 func=185 file=184 line=147 - pc=4290674 func=186 file=187 line=182 - pc=4255364 func=188 file=77 line=948 - pc=4256932 func=78 file=77 line=1149 - pc=4528840 func=79 file=80 line=107 - pc=5081148 func=62 file=36 line=127 - pc=5077843 func=35 file=36 line=32 -Stack id=93 nframes=7 - pc=4754618 func=88 file=25 line=964 - pc=4816103 func=89 file=27 line=209 - pc=4816095 func=28 file=29 line=736 - pc=4815648 func=90 file=29 line=380 - pc=4996388 func=205 file=32 line=96 - pc=5033284 func=206 file=34 line=191 - pc=5078821 func=113 file=36 line=65 -Stack id=34 nframes=2 - pc=4644903 func=115 file=116 line=474 - pc=4316309 func=107 file=73 line=1393 -Stack id=49 nframes=2 - pc=4708263 func=169 file=148 line=116 - pc=5078001 func=35 file=36 line=43 -Stack id=7 nframes=4 - pc=4573636 func=207 file=99 line=877 - pc=4567844 func=98 file=99 line=259 - pc=5076805 func=100 file=96 line=125 - pc=5077595 func=35 file=36 line=20 -Stack id=76 nframes=1 - pc=5078444 func=35 file=36 line=58 -Stack id=1 nframes=4 - pc=4583115 func=208 file=202 line=260 - pc=4567535 func=98 file=99 line=238 - pc=5076805 func=100 file=96 line=125 - pc=5077595 func=35 file=36 line=20 -Stack id=26 nframes=2 - pc=4224086 func=57 file=58 line=145 - pc=4316011 func=107 file=73 line=1312 -Stack id=40 nframes=3 - pc=4312646 func=200 file=73 line=1086 - pc=4310756 func=72 file=73 line=926 - pc=4316644 func=107 file=73 line=1469 -Stack id=72 nframes=11 - pc=4757394 func=129 file=25 line=1488 - pc=5054386 func=130 file=27 line=462 - pc=5054396 func=209 file=210 line=28 - pc=5051349 func=119 file=42 line=152 - pc=5048051 func=43 file=42 line=57 - pc=5021687 func=44 file=45 line=154 - pc=5059172 func=120 file=47 line=189 - pc=4967876 func=121 file=47 line=179 - pc=4967838 func=122 file=51 line=734 - pc=4968614 func=123 file=51 line=808 - pc=5078215 func=35 file=36 line=53 -Stack id=59 nframes=5 - pc=4753924 func=81 file=25 line=432 - pc=4744496 func=82 file=83 line=118 - pc=4823012 func=84 file=85 line=218 - pc=4824408 func=86 file=87 line=21 - pc=5079543 func=59 file=36 line=82 -Stack id=9 nframes=2 - pc=5076879 func=100 file=96 line=128 - pc=5077595 func=35 file=36 line=20 -EventBatch gen=1 m=18446744073709551615 time=7689670146021 size=6980 -Strings -String id=1 - data="Not worker" -String id=2 - data="GC (dedicated)" -String id=3 - data="GC (fractional)" -String id=4 - data="GC (idle)" -String id=5 - data="unspecified" -String id=6 - data="forever" -String id=7 - data="network" -String id=8 - data="select" -String id=9 - data="sync.(*Cond).Wait" -String id=10 - data="sync" -String id=11 - data="chan send" -String id=12 - data="chan receive" -String id=13 - data="GC mark assist wait for work" -String id=14 - data="GC background sweeper wait" -String id=15 - data="system goroutine wait" -String id=16 - data="preempted" -String id=17 - data="wait for debug call" -String id=18 - data="wait until GC ends" -String id=19 - data="sleep" -String id=20 - data="runtime.Gosched" -String id=21 - data="start trace" -String id=22 - data="GC sweep termination" -String id=23 - data="GC mark termination" -String id=24 - data="syscall.read" -String id=25 - data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/zsyscall_linux_amd64.go" -String id=26 - data="syscall.Read" -String id=27 - data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/syscall_unix.go" -String id=28 - data="internal/poll.ignoringEINTRIO" -String id=29 - data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/fd_unix.go" -String id=30 - data="internal/poll.(*FD).Read" -String id=31 - data="net.(*netFD).Read" -String id=32 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/fd_posix.go" -String id=33 - data="net.(*conn).Read" -String id=34 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/net.go" -String id=35 - data="main.main" -String id=36 - data="/usr/local/google/home/mknyszek/work/go-1/src/cmd/trace/v2/testdata/testprog/main.go" -String id=37 - data="syscall.connect" -String id=38 - data="syscall.Connect" -String id=39 - data="net.(*netFD).connect" -String id=40 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/fd_unix.go" -String id=41 - data="net.(*netFD).dial" -String id=42 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/sock_posix.go" -String id=43 - data="net.socket" -String id=44 - data="net.internetSocket" -String id=45 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/ipsock_posix.go" -String id=46 - data="net.(*sysDialer).doDialTCPProto" -String id=47 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsock_posix.go" -String id=48 - data="net.(*sysDialer).doDialTCP" -String id=49 - data="net.(*sysDialer).dialTCP" -String id=50 - data="net.(*sysDialer).dialSingle" -String id=51 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/dial.go" -String id=52 - data="net.(*sysDialer).dialSerial" -String id=53 - data="net.(*sysDialer).dialParallel" -String id=54 - data="net.(*Dialer).DialContext" -String id=55 - data="net.(*Dialer).Dial" -String id=56 - data="net.Dial" -String id=57 - data="runtime.chansend1" -String id=58 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/chan.go" -String id=59 - data="main.blockingSyscall" -String id=60 - data="time.Sleep" -String id=61 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/time.go" -String id=62 - data="main.allocHog" -String id=63 - data="main.cpu10" -String id=64 - data="runtime.goparkunlock" -String id=65 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/proc.go" -String id=66 - data="runtime.bgsweep" -String id=67 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgcsweep.go" -String id=68 - data="runtime.asyncPreempt" -String id=69 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/preempt_amd64.s" -String id=70 - data="main.cpuHog" -String id=71 - data="main.main.func1" -String id=72 - data="runtime.gcMarkDone" -String id=73 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgc.go" -String id=74 - data="runtime.gcAssistAlloc" -String id=75 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgcmark.go" -String id=76 - data="runtime.deductAssistCredit" -String id=77 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/malloc.go" -String id=78 - data="runtime.mallocgc" -String id=79 - data="runtime.makeslice" -String id=80 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/slice.go" -String id=81 - data="syscall.fcntl" -String id=82 - data="syscall.SetNonblock" -String id=83 - data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/exec_unix.go" -String id=84 - data="os.newFile" -String id=85 - data="/usr/local/google/home/mknyszek/work/go-1/src/os/file_unix.go" -String id=86 - data="os.Pipe" -String id=87 - data="/usr/local/google/home/mknyszek/work/go-1/src/os/pipe2_unix.go" -String id=88 - data="syscall.write" -String id=89 - data="syscall.Write" -String id=90 - data="internal/poll.(*FD).Write" -String id=91 - data="os.(*File).write" -String id=92 - data="/usr/local/google/home/mknyszek/work/go-1/src/os/file_posix.go" -String id=93 - data="os.(*File).Write" -String id=94 - data="/usr/local/google/home/mknyszek/work/go-1/src/os/file.go" -String id=95 - data="runtime/trace.Start.func1" -String id=96 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace/trace.go" -String id=97 - data="main.blockingSyscall.func1" -String id=98 - data="runtime.StartTrace" -String id=99 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace2.go" -String id=100 - data="runtime/trace.Start" -String id=101 - data="internal/poll.(*FD).WaitWrite" -String id=102 - data="runtime.chanrecv1" -String id=103 - data="runtime.traceStartReadCPU" -String id=104 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace2cpu.go" -String id=105 - data="runtime.gcBgMarkStartWorkers" -String id=106 - data="runtime.gcStart" -String id=107 - data="runtime.gcBgMarkWorker" -String id=108 - data="internal/poll.(*FD).Accept" -String id=109 - data="net.(*netFD).accept" -String id=110 - data="net.(*TCPListener).accept" -String id=111 - data="net.(*TCPListener).Accept" -String id=112 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsock.go" -String id=113 - data="main.main.func2" -String id=114 - data="runtime.gcParkAssist" -String id=115 - data="runtime.systemstack_switch" -String id=116 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/asm_amd64.s" -String id=117 - data="syscall.bind" -String id=118 - data="syscall.Bind" -String id=119 - data="net.(*netFD).listenStream" -String id=120 - data="net.(*sysListener).listenTCPProto" -String id=121 - data="net.(*sysListener).listenTCP" -String id=122 - data="net.(*ListenConfig).Listen" -String id=123 - data="net.Listen" -String id=124 - data="runtime.(*scavengerState).park" -String id=125 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgcscavenge.go" -String id=126 - data="runtime.bgscavenge" -String id=127 - data="runtime.(*wakeableSleep).sleep" -String id=128 - data="runtime.traceStartReadCPU.func1" -String id=129 - data="syscall.setsockopt" -String id=130 - data="syscall.SetsockoptInt" -String id=131 - data="internal/poll.(*FD).SetsockoptInt" -String id=132 - data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/sockopt.go" -String id=133 - data="net.setKeepAlivePeriod" -String id=134 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsockopt_unix.go" -String id=135 - data="net.newTCPConn" -String id=136 - data="syscall.Close" -String id=137 - data="internal/poll.(*SysFile).destroy" -String id=138 - data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/fd_unixjs.go" -String id=139 - data="internal/poll.(*FD).destroy" -String id=140 - data="internal/poll.(*FD).decref" -String id=141 - data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/fd_mutex.go" -String id=142 - data="internal/poll.(*FD).Close" -String id=143 - data="net.(*netFD).Close" -String id=144 - data="net.(*conn).Close" -String id=145 - data="internal/poll.(*FD).SetBlocking" -String id=146 - data="os.(*File).Fd" -String id=147 - data="sync.(*WaitGroup).Add" -String id=148 - data="/usr/local/google/home/mknyszek/work/go-1/src/sync/waitgroup.go" -String id=149 - data="sync.(*WaitGroup).Done" -String id=150 - data="main.cpu20" -String id=151 - data="syscall.openat" -String id=152 - data="syscall.Open" -String id=153 - data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/syscall_linux.go" -String id=154 - data="os.open" -String id=155 - data="/usr/local/google/home/mknyszek/work/go-1/src/os/file_open_unix.go" -String id=156 - data="os.openFileNolog" -String id=157 - data="os.OpenFile" -String id=158 - data="os.Open" -String id=159 - data="net.open" -String id=160 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/parse.go" -String id=161 - data="net.maxListenerBacklog" -String id=162 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/sock_linux.go" -String id=163 - data="net.listenerBacklog.func1" -String id=164 - data="sync.(*Once).doSlow" -String id=165 - data="/usr/local/google/home/mknyszek/work/go-1/src/sync/once.go" -String id=166 - data="sync.(*Once).Do" -String id=167 - data="net.listenerBacklog" -String id=168 - data="syscall.Listen" -String id=169 - data="sync.(*WaitGroup).Wait" -String id=170 - data="runtime.gopark" -String id=171 - data="net.setNoDelay" -String id=172 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsockopt_posix.go" -String id=173 - data="os.(*File).read" -String id=174 - data="os.(*File).Read" -String id=175 - data="io.ReadAtLeast" -String id=176 - data="/usr/local/google/home/mknyszek/work/go-1/src/io/io.go" -String id=177 - data="io.ReadFull" -String id=178 - data="net.(*file).readLine" -String id=179 - data="net.setKeepAlive" -String id=180 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/sockopt_posix.go" -String id=181 - data="runtime.(*mheap).alloc" -String id=182 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mheap.go" -String id=183 - data="runtime.(*mcentral).grow" -String id=184 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mcentral.go" -String id=185 - data="runtime.(*mcentral).cacheSpan" -String id=186 - data="runtime.(*mcache).refill" -String id=187 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mcache.go" -String id=188 - data="runtime.(*mcache).nextFree" -String id=189 - data="syscall.accept4" -String id=190 - data="syscall.Accept4" -String id=191 - data="internal/poll.accept" -String id=192 - data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/sock_cloexec.go" -String id=193 - data="os.(*file).close" -String id=194 - data="os.(*File).Close" -String id=195 - data="net.(*file).close" -String id=196 - data="runtime.startTheWorld" -String id=197 - data="runtime.(*traceAdvancerState).start.func1" -String id=198 - data="syscall.getsockopt" -String id=199 - data="syscall.GetsockoptInt" -String id=200 - data="runtime.gcMarkTermination" -String id=201 - data="runtime.traceLocker.GCMarkAssistStart" -String id=202 - data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace2runtime.go" -String id=203 - data="runtime.traceLocker.GCSweepSpan" -String id=204 - data="runtime.(*sweepLocked).sweep" -String id=205 - data="net.(*netFD).Write" -String id=206 - data="net.(*conn).Write" -String id=207 - data="runtime.(*traceAdvancerState).start" -String id=208 - data="runtime.traceLocker.Gomaxprocs" -String id=209 - data="net.setDefaultListenerSockopts" -String id=210 - data="/usr/local/google/home/mknyszek/work/go-1/src/net/sockopt_linux.go" diff --git a/src/cmd/trace/v2/testdata/mktests.go b/src/cmd/trace/v2/testdata/mktests.go deleted file mode 100644 index b6efa83ece..0000000000 --- a/src/cmd/trace/v2/testdata/mktests.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build ignore - -package main - -import ( - "bytes" - "fmt" - "internal/trace/v2/raw" - "internal/trace/v2/version" - "io" - "log" - "os" - "os/exec" -) - -func main() { - // Create command. - var trace, stderr bytes.Buffer - cmd := exec.Command("go", "run", "./testprog/main.go") - cmd.Stdout = &trace - cmd.Stderr = &stderr - - // Run trace program; the trace will appear in stdout. - fmt.Fprintln(os.Stderr, "running trace program...") - if err := cmd.Run(); err != nil { - log.Fatalf("running trace program: %v:\n%s", err, stderr.String()) - } - - // Create file. - f, err := os.Create(fmt.Sprintf("./go1%d.test", version.Current)) - if err != nil { - log.Fatalf("creating output file: %v", err) - } - defer f.Close() - - // Write out the trace. - r, err := raw.NewReader(&trace) - if err != nil { - log.Fatalf("reading trace: %v", err) - } - w, err := raw.NewTextWriter(f, version.Current) - for { - ev, err := r.ReadEvent() - if err == io.EOF { - break - } - if err != nil { - log.Fatalf("reading trace: %v", err) - } - if err := w.WriteEvent(ev); err != nil { - log.Fatalf("writing trace: %v", err) - } - } -} diff --git a/src/cmd/trace/v2/testdata/testprog/main.go b/src/cmd/trace/v2/testdata/testprog/main.go deleted file mode 100644 index fcf4dc156c..0000000000 --- a/src/cmd/trace/v2/testdata/testprog/main.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "log" - "net" - "os" - "runtime" - "runtime/trace" - "sync" - "syscall" - "time" -) - -func main() { - if err := trace.Start(os.Stdout); err != nil { - log.Fatal(err) - } - - // checkExecutionTimes relies on this. - var wg sync.WaitGroup - wg.Add(2) - go cpu10(&wg) - go cpu20(&wg) - wg.Wait() - - // checkHeapMetrics relies on this. - allocHog(25 * time.Millisecond) - - // checkProcStartStop relies on this. - var wg2 sync.WaitGroup - for i := 0; i < runtime.GOMAXPROCS(0); i++ { - wg2.Add(1) - go func() { - defer wg2.Done() - cpuHog(50 * time.Millisecond) - }() - } - wg2.Wait() - - // checkSyscalls relies on this. - done := make(chan error) - go blockingSyscall(50*time.Millisecond, done) - if err := <-done; err != nil { - log.Fatal(err) - } - - // checkNetworkUnblock relies on this. - ln, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - log.Fatalf("listen failed: %v", err) - } - defer ln.Close() - go func() { - c, err := ln.Accept() - if err != nil { - return - } - time.Sleep(time.Millisecond) - var buf [1]byte - c.Write(buf[:]) - c.Close() - }() - c, err := net.Dial("tcp", ln.Addr().String()) - if err != nil { - log.Fatalf("dial failed: %v", err) - } - var tmp [1]byte - c.Read(tmp[:]) - c.Close() - - trace.Stop() -} - -// blockingSyscall blocks the current goroutine for duration d in a syscall and -// sends a message to done when it is done or if the syscall failed. -func blockingSyscall(d time.Duration, done chan<- error) { - r, w, err := os.Pipe() - if err != nil { - done <- err - return - } - start := time.Now() - msg := []byte("hello") - time.AfterFunc(d, func() { w.Write(msg) }) - _, err = syscall.Read(int(r.Fd()), make([]byte, len(msg))) - if err == nil && time.Since(start) < d { - err = fmt.Errorf("syscall returned too early: want=%s got=%s", d, time.Since(start)) - } - done <- err -} - -func cpu10(wg *sync.WaitGroup) { - defer wg.Done() - cpuHog(10 * time.Millisecond) -} - -func cpu20(wg *sync.WaitGroup) { - defer wg.Done() - cpuHog(20 * time.Millisecond) -} - -func cpuHog(dt time.Duration) { - start := time.Now() - for i := 0; ; i++ { - if i%1000 == 0 && time.Since(start) > dt { - return - } - } -} - -func allocHog(dt time.Duration) { - start := time.Now() - var s [][]byte - for i := 0; ; i++ { - if i%1000 == 0 { - if time.Since(start) > dt { - return - } - // Take a break... this will generate a ton of events otherwise. - time.Sleep(50 * time.Microsecond) - } - s = append(s, make([]byte, 1024)) - } -} diff --git a/src/cmd/trace/v2/threadgen.go b/src/cmd/trace/v2/threadgen.go deleted file mode 100644 index e1cae2b2cf..0000000000 --- a/src/cmd/trace/v2/threadgen.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - "fmt" - "internal/trace/traceviewer" - "internal/trace/traceviewer/format" - tracev2 "internal/trace/v2" -) - -var _ generator = &threadGenerator{} - -type threadGenerator struct { - globalRangeGenerator - globalMetricGenerator - stackSampleGenerator[tracev2.ThreadID] - logEventGenerator[tracev2.ThreadID] - - gStates map[tracev2.GoID]*gState[tracev2.ThreadID] - threads map[tracev2.ThreadID]struct{} -} - -func newThreadGenerator() *threadGenerator { - tg := new(threadGenerator) - rg := func(ev *tracev2.Event) tracev2.ThreadID { - return ev.Thread() - } - tg.stackSampleGenerator.getResource = rg - tg.logEventGenerator.getResource = rg - tg.gStates = make(map[tracev2.GoID]*gState[tracev2.ThreadID]) - tg.threads = make(map[tracev2.ThreadID]struct{}) - return tg -} - -func (g *threadGenerator) Sync() { - g.globalRangeGenerator.Sync() -} - -func (g *threadGenerator) GoroutineLabel(ctx *traceContext, ev *tracev2.Event) { - l := ev.Label() - g.gStates[l.Resource.Goroutine()].setLabel(l.Label) -} - -func (g *threadGenerator) GoroutineRange(ctx *traceContext, ev *tracev2.Event) { - r := ev.Range() - switch ev.Kind() { - case tracev2.EventRangeBegin: - g.gStates[r.Scope.Goroutine()].rangeBegin(ev.Time(), r.Name, ev.Stack()) - case tracev2.EventRangeActive: - g.gStates[r.Scope.Goroutine()].rangeActive(r.Name) - case tracev2.EventRangeEnd: - gs := g.gStates[r.Scope.Goroutine()] - gs.rangeEnd(ev.Time(), r.Name, ev.Stack(), ctx) - } -} - -func (g *threadGenerator) GoroutineTransition(ctx *traceContext, ev *tracev2.Event) { - if ev.Thread() != tracev2.NoThread { - if _, ok := g.threads[ev.Thread()]; !ok { - g.threads[ev.Thread()] = struct{}{} - } - } - - st := ev.StateTransition() - goID := st.Resource.Goroutine() - - // If we haven't seen this goroutine before, create a new - // gState for it. - gs, ok := g.gStates[goID] - if !ok { - gs = newGState[tracev2.ThreadID](goID) - g.gStates[goID] = gs - } - // If we haven't already named this goroutine, try to name it. - gs.augmentName(st.Stack) - - // Handle the goroutine state transition. - from, to := st.Goroutine() - if from == to { - // Filter out no-op events. - return - } - if from.Executing() && !to.Executing() { - if to == tracev2.GoWaiting { - // Goroutine started blocking. - gs.block(ev.Time(), ev.Stack(), st.Reason, ctx) - } else { - gs.stop(ev.Time(), ev.Stack(), ctx) - } - } - if !from.Executing() && to.Executing() { - start := ev.Time() - if from == tracev2.GoUndetermined { - // Back-date the event to the start of the trace. - start = ctx.startTime - } - gs.start(start, ev.Thread(), ctx) - } - - if from == tracev2.GoWaiting { - // Goroutine was unblocked. - gs.unblock(ev.Time(), ev.Stack(), ev.Thread(), ctx) - } - if from == tracev2.GoNotExist && to == tracev2.GoRunnable { - // Goroutine was created. - gs.created(ev.Time(), ev.Thread(), ev.Stack()) - } - if from == tracev2.GoSyscall { - // Exiting syscall. - gs.syscallEnd(ev.Time(), to != tracev2.GoRunning, ctx) - } - - // Handle syscalls. - if to == tracev2.GoSyscall { - start := ev.Time() - if from == tracev2.GoUndetermined { - // Back-date the event to the start of the trace. - start = ctx.startTime - } - // Write down that we've entered a syscall. Note: we might have no P here - // if we're in a cgo callback or this is a transition from GoUndetermined - // (i.e. the G has been blocked in a syscall). - gs.syscallBegin(start, ev.Thread(), ev.Stack()) - } - - // Note down the goroutine transition. - _, inMarkAssist := gs.activeRanges["GC mark assist"] - ctx.GoroutineTransition(ctx.elapsed(ev.Time()), viewerGState(from, inMarkAssist), viewerGState(to, inMarkAssist)) -} - -func (g *threadGenerator) ProcTransition(ctx *traceContext, ev *tracev2.Event) { - if ev.Thread() != tracev2.NoThread { - if _, ok := g.threads[ev.Thread()]; !ok { - g.threads[ev.Thread()] = struct{}{} - } - } - - type procArg struct { - Proc uint64 `json:"proc,omitempty"` - } - st := ev.StateTransition() - viewerEv := traceviewer.InstantEvent{ - Resource: uint64(ev.Thread()), - Stack: ctx.Stack(viewerFrames(ev.Stack())), - Arg: procArg{Proc: uint64(st.Resource.Proc())}, - } - - from, to := st.Proc() - if from == to { - // Filter out no-op events. - return - } - if to.Executing() { - start := ev.Time() - if from == tracev2.ProcUndetermined { - start = ctx.startTime - } - viewerEv.Name = "proc start" - viewerEv.Arg = format.ThreadIDArg{ThreadID: uint64(ev.Thread())} - viewerEv.Ts = ctx.elapsed(start) - // TODO(mknyszek): We don't have a state machine for threads, so approximate - // running threads with running Ps. - ctx.IncThreadStateCount(ctx.elapsed(start), traceviewer.ThreadStateRunning, 1) - } - if from.Executing() { - start := ev.Time() - viewerEv.Name = "proc stop" - viewerEv.Ts = ctx.elapsed(start) - // TODO(mknyszek): We don't have a state machine for threads, so approximate - // running threads with running Ps. - ctx.IncThreadStateCount(ctx.elapsed(start), traceviewer.ThreadStateRunning, -1) - } - // TODO(mknyszek): Consider modeling procs differently and have them be - // transition to and from NotExist when GOMAXPROCS changes. We can emit - // events for this to clearly delineate GOMAXPROCS changes. - - if viewerEv.Name != "" { - ctx.Instant(viewerEv) - } -} - -func (g *threadGenerator) ProcRange(ctx *traceContext, ev *tracev2.Event) { - // TODO(mknyszek): Extend procRangeGenerator to support rendering proc ranges on threads. -} - -func (g *threadGenerator) Finish(ctx *traceContext) { - ctx.SetResourceType("OS THREADS") - - // Finish off global ranges. - g.globalRangeGenerator.Finish(ctx) - - // Finish off all the goroutine slices. - for _, gs := range g.gStates { - gs.finish(ctx) - } - - // Name all the threads to the emitter. - for id := range g.threads { - ctx.Resource(uint64(id), fmt.Sprintf("Thread %d", id)) - } -} diff --git a/src/cmd/trace/v2/viewer.go b/src/cmd/trace/v2/viewer.go deleted file mode 100644 index de67fc4e0e..0000000000 --- a/src/cmd/trace/v2/viewer.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package trace - -import ( - "fmt" - "internal/trace" - "internal/trace/traceviewer" - tracev2 "internal/trace/v2" - "time" -) - -// viewerFrames returns the frames of the stack of ev. The given frame slice is -// used to store the frames to reduce allocations. -func viewerFrames(stk tracev2.Stack) []*trace.Frame { - var frames []*trace.Frame - stk.Frames(func(f tracev2.StackFrame) bool { - frames = append(frames, &trace.Frame{ - PC: f.PC, - Fn: f.Func, - File: f.File, - Line: int(f.Line), - }) - return true - }) - return frames -} - -func viewerGState(state tracev2.GoState, inMarkAssist bool) traceviewer.GState { - switch state { - case tracev2.GoUndetermined: - return traceviewer.GDead - case tracev2.GoNotExist: - return traceviewer.GDead - case tracev2.GoRunnable: - return traceviewer.GRunnable - case tracev2.GoRunning: - return traceviewer.GRunning - case tracev2.GoWaiting: - if inMarkAssist { - return traceviewer.GWaitingGC - } - return traceviewer.GWaiting - case tracev2.GoSyscall: - // N.B. A goroutine in a syscall is considered "executing" (state.Executing() == true). - return traceviewer.GRunning - default: - panic(fmt.Sprintf("unknown GoState: %s", state.String())) - } -} - -func viewerTime(t time.Duration) float64 { - return float64(t) / float64(time.Microsecond) -} diff --git a/src/cmd/trace/viewer.go b/src/cmd/trace/viewer.go new file mode 100644 index 0000000000..6d3029ac86 --- /dev/null +++ b/src/cmd/trace/viewer.go @@ -0,0 +1,56 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "internal/trace" + "internal/trace/traceviewer" + tracev2 "internal/trace/v2" + "time" +) + +// viewerFrames returns the frames of the stack of ev. The given frame slice is +// used to store the frames to reduce allocations. +func viewerFrames(stk tracev2.Stack) []*trace.Frame { + var frames []*trace.Frame + stk.Frames(func(f tracev2.StackFrame) bool { + frames = append(frames, &trace.Frame{ + PC: f.PC, + Fn: f.Func, + File: f.File, + Line: int(f.Line), + }) + return true + }) + return frames +} + +func viewerGState(state tracev2.GoState, inMarkAssist bool) traceviewer.GState { + switch state { + case tracev2.GoUndetermined: + return traceviewer.GDead + case tracev2.GoNotExist: + return traceviewer.GDead + case tracev2.GoRunnable: + return traceviewer.GRunnable + case tracev2.GoRunning: + return traceviewer.GRunning + case tracev2.GoWaiting: + if inMarkAssist { + return traceviewer.GWaitingGC + } + return traceviewer.GWaiting + case tracev2.GoSyscall: + // N.B. A goroutine in a syscall is considered "executing" (state.Executing() == true). + return traceviewer.GRunning + default: + panic(fmt.Sprintf("unknown GoState: %s", state.String())) + } +} + +func viewerTime(t time.Duration) float64 { + return float64(t) / float64(time.Microsecond) +} -- cgit v1.3-6-g1900
WhenElapsedGoroutineEvents
{{$el.WhenString}}{{$el.Duration}} - Task {{$el.ID}} - (goroutine view) - ({{if .Complete}}complete{{else}}incomplete{{end}}) -
{{.WhenString}}{{elapsed .Elapsed}}{{.Goroutine}}{{.What}}