From 748952f494f359acf945b7984929024c248bedab Mon Sep 17 00:00:00 2001 From: Michael Anthony Knyszek Date: Tue, 14 Nov 2023 17:03:24 +0000 Subject: [PATCH] cmd/trace: add almost full support for v2 traces in the trace viewer MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This change refactors the cmd/trace package and adds most of the support for v2 traces. The following features of note are missing in this CL and will be implemented in follow-up CLs: - The focustask filter for the trace viewer - The taskid filter for the trace viewer - The goid filter for the trace viewer - Pprof profiles - The MMU graph - The goroutine analysis pages - The task analysis pages - The region analysis pages This CL makes one notable change to the trace CLI: it makes the -d flag accept an integer to set the debug mode. For old traces -d != 0 works just like -d. For new traces -d=1 means the high-level events and -d=2 means the low-level events. Thanks to Felix Geisendörfer (felix.geisendoerfer@datadoghq.com) for doing a lot of work on this CL; I picked this up from him and got a massive headstart as a result. For #60773. For #63960. Change-Id: I3626e22473227c5980134a85f1bb6a845f567b1b Reviewed-on: https://go-review.googlesource.com/c/go/+/542218 Reviewed-by: Michael Pratt Auto-Submit: Michael Knyszek TryBot-Bypass: Michael Knyszek --- src/cmd/go/internal/trace/trace.go | 12 +- src/cmd/trace/main.go | 238 +- src/cmd/trace/mmu.go | 3 +- src/cmd/trace/trace.go | 776 +-- src/cmd/trace/trace_test.go | 21 +- src/cmd/trace/trace_unix_test.go | 9 +- src/cmd/trace/v2/gen.go | 249 + src/cmd/trace/v2/gstate.go | 362 ++ src/cmd/trace/v2/jsontrace.go | 67 + src/cmd/trace/v2/jsontrace_test.go | 291 ++ src/cmd/trace/v2/main.go | 136 + src/cmd/trace/v2/procgen.go | 209 + src/cmd/trace/v2/testdata/generate.go | 6 + src/cmd/trace/v2/testdata/go122.test | 4366 +++++++++++++++++ src/cmd/trace/v2/testdata/mktests.go | 60 + src/cmd/trace/v2/testdata/testprog/main.go | 129 + src/cmd/trace/v2/viewer.go | 56 + src/go/build/deps_test.go | 11 + src/internal/trace/parser.go | 15 +- src/internal/trace/traceviewer/emitter.go | 666 +++ .../trace/traceviewer/format}/format.go | 43 +- src/internal/trace/traceviewer/http.go | 375 ++ .../trace/traceviewer}/static/README.md | 0 .../static/trace_viewer_full.html | 0 .../traceviewer}/static/webcomponents.min.js | 0 src/internal/trace/v2/version/version.go | 3 +- 26 files changed, 7196 insertions(+), 907 deletions(-) create mode 100644 src/cmd/trace/v2/gen.go create mode 100644 src/cmd/trace/v2/gstate.go create mode 100644 src/cmd/trace/v2/jsontrace.go create mode 100644 src/cmd/trace/v2/jsontrace_test.go create mode 100644 src/cmd/trace/v2/main.go create mode 100644 src/cmd/trace/v2/procgen.go create mode 100644 src/cmd/trace/v2/testdata/generate.go create mode 100644 src/cmd/trace/v2/testdata/go122.test create mode 100644 src/cmd/trace/v2/testdata/mktests.go create mode 100644 src/cmd/trace/v2/testdata/testprog/main.go create mode 100644 src/cmd/trace/v2/viewer.go create mode 100644 src/internal/trace/traceviewer/emitter.go rename src/{cmd/internal/traceviewer => internal/trace/traceviewer/format}/format.go (60%) create mode 100644 src/internal/trace/traceviewer/http.go rename src/{cmd/trace => internal/trace/traceviewer}/static/README.md (100%) rename src/{cmd/trace => internal/trace/traceviewer}/static/trace_viewer_full.html (100%) rename src/{cmd/trace => internal/trace/traceviewer}/static/webcomponents.min.js (100%) diff --git a/src/cmd/go/internal/trace/trace.go b/src/cmd/go/internal/trace/trace.go index 17d3ee9e7f..f96aa40002 100644 --- a/src/cmd/go/internal/trace/trace.go +++ b/src/cmd/go/internal/trace/trace.go @@ -5,10 +5,10 @@ package trace import ( - "cmd/internal/traceviewer" "context" "encoding/json" "errors" + "internal/trace/traceviewer/format" "os" "strings" "sync/atomic" @@ -47,7 +47,7 @@ func StartSpan(ctx context.Context, name string) (context.Context, *Span) { return ctx, nil } childSpan := &Span{t: tc.t, name: name, tid: tc.tid, start: time.Now()} - tc.t.writeEvent(&traceviewer.Event{ + tc.t.writeEvent(&format.Event{ Name: childSpan.name, Time: float64(childSpan.start.UnixNano()) / float64(time.Microsecond), TID: childSpan.tid, @@ -77,7 +77,7 @@ func Flow(ctx context.Context, from *Span, to *Span) { } id := tc.t.getNextFlowID() - tc.t.writeEvent(&traceviewer.Event{ + tc.t.writeEvent(&format.Event{ Name: from.name + " -> " + to.name, Category: "flow", ID: id, @@ -85,7 +85,7 @@ func Flow(ctx context.Context, from *Span, to *Span) { Phase: phaseFlowStart, TID: from.tid, }) - tc.t.writeEvent(&traceviewer.Event{ + tc.t.writeEvent(&format.Event{ Name: from.name + " -> " + to.name, Category: "flow", // TODO(matloob): Add Category to Flow? ID: id, @@ -110,7 +110,7 @@ func (s *Span) Done() { return } s.end = time.Now() - s.t.writeEvent(&traceviewer.Event{ + s.t.writeEvent(&format.Event{ Name: s.name, Time: float64(s.end.UnixNano()) / float64(time.Microsecond), TID: s.tid, @@ -125,7 +125,7 @@ type tracer struct { nextFlowID atomic.Uint64 } -func (t *tracer) writeEvent(ev *traceviewer.Event) error { +func (t *tracer) writeEvent(ev *format.Event) error { f := <-t.file defer func() { t.file <- f }() var err error diff --git a/src/cmd/trace/main.go b/src/cmd/trace/main.go index 9e9e7f3e49..b269050499 100644 --- a/src/cmd/trace/main.go +++ b/src/cmd/trace/main.go @@ -7,10 +7,11 @@ package main import ( "bufio" "cmd/internal/browser" + cmdv2 "cmd/trace/v2" "flag" "fmt" - "html/template" "internal/trace" + "internal/trace/traceviewer" "io" "log" "net" @@ -46,7 +47,7 @@ Supported profile types are: Flags: -http=addr: HTTP service address (e.g., ':6060') -pprof=type: print a pprof-like profile instead - -d: print debug info such as parsed events + -d=int: print debug info such as parsed events (1 for high-level, 2 for low-level) Note that while the various profiles available when launching 'go tool trace' work on every browser, the trace viewer itself @@ -57,7 +58,7 @@ and is only actively tested on that browser. var ( httpFlag = flag.String("http", "localhost:0", "HTTP service address (e.g., ':6060')") pprofFlag = flag.String("pprof", "", "print a pprof-like profile instead") - debugFlag = flag.Bool("d", false, "print debug information such as parsed events list") + debugFlag = flag.Int("d", 0, "print debug information (1 for basic debug info, 2 for lower-level info)") // The binary file name, left here for serveSVGProfile. programBinary string @@ -83,6 +84,13 @@ func main() { flag.Usage() } + if isTraceV2(traceFile) { + if err := cmdv2.Main(traceFile, *httpFlag, *pprofFlag, *debugFlag); err != nil { + dief("%s\n", err) + } + return + } + var pprofFunc func(io.Writer, *http.Request) error switch *pprofFlag { case "net": @@ -115,7 +123,7 @@ func main() { dief("%v\n", err) } - if *debugFlag { + if *debugFlag != 0 { trace.Print(res.Events) os.Exit(0) } @@ -132,12 +140,27 @@ func main() { browser.Open(addr) // Start http server. - http.HandleFunc("/", httpMain) + http.Handle("/", traceviewer.MainHandler(ranges)) err = http.Serve(ln, nil) dief("failed to start http server: %v\n", err) } -var ranges []Range +// isTraceV2 returns true if filename holds a v2 trace. +func isTraceV2(filename string) bool { + file, err := os.Open(filename) + if err != nil { + return false + } + defer file.Close() + + ver, _, err := trace.ReadVersion(file) + if err != nil { + return false + } + return ver >= 1022 +} + +var ranges []traceviewer.Range var loader struct { once sync.Once @@ -175,209 +198,6 @@ func parseTrace() (trace.ParseResult, error) { return loader.res, loader.err } -// httpMain serves the starting page. -func httpMain(w http.ResponseWriter, r *http.Request) { - if err := templMain.Execute(w, ranges); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } -} - -var templMain = template.Must(template.New("").Parse(` - - - -

cmd/trace: the Go trace event viewer

-

- This web server provides various visualizations of an event log gathered during - the execution of a Go program that uses the runtime/trace package. -

- -

Event timelines for running goroutines

-{{if $}} -

- Large traces are split into multiple sections of equal data size - (not duration) to avoid overwhelming the visualizer. -

- -{{else}} - -{{end}} -

- This view displays a timeline for each of the GOMAXPROCS logical - processors, showing which goroutine (if any) was running on that - logical processor at each moment. - - Each goroutine has an identifying number (e.g. G123), main function, - and color. - - A colored bar represents an uninterrupted span of execution. - - Execution of a goroutine may migrate from one logical processor to another, - causing a single colored bar to be horizontally continuous but - vertically displaced. -

-

- Clicking on a span reveals information about it, such as its - duration, its causal predecessors and successors, and the stack trace - at the final moment when it yielded the logical processor, for example - because it made a system call or tried to acquire a mutex. - - Directly underneath each bar, a smaller bar or more commonly a fine - vertical line indicates an event occurring during its execution. - Some of these are related to garbage collection; most indicate that - a goroutine yielded its logical processor but then immediately resumed execution - on the same logical processor. Clicking on the event displays the stack trace - at the moment it occurred. -

-

- The causal relationships between spans of goroutine execution - can be displayed by clicking the Flow Events button at the top. -

-

- At the top ("STATS"), there are three additional timelines that - display statistical information. - - "Goroutines" is a time series of the count of existing goroutines; - clicking on it displays their breakdown by state at that moment: - running, runnable, or waiting. - - "Heap" is a time series of the amount of heap memory allocated (in orange) - and (in green) the allocation limit at which the next GC cycle will begin. - - "Threads" shows the number of kernel threads in existence: there is - always one kernel thread per logical processor, and additional threads - are created for calls to non-Go code such as a system call or a - function written in C. -

-

- Above the event trace for the first logical processor are - traces for various runtime-internal events. - - The "GC" bar shows when the garbage collector is running, and in which stage. - Garbage collection may temporarily affect all the logical processors - and the other metrics. - - The "Network", "Timers", and "Syscalls" traces indicate events in - the runtime that cause goroutines to wake up. -

-

- The visualization allows you to navigate events at scales ranging from several - seconds to a handful of nanoseconds. - - Consult the documentation for the Chromium Trace Event Profiling Tool - for help navigating the view. -

- - -

- This view displays information about each set of goroutines that - shares the same main function. - - Clicking on a main function shows links to the four types of - blocking profile (see below) applied to that subset of goroutines. - - It also shows a table of specific goroutine instances, with various - execution statistics and a link to the event timeline for each one. - - The timeline displays only the selected goroutine and any others it - interacts with via block/unblock events. (The timeline is - goroutine-oriented rather than logical processor-oriented.) -

- -

Profiles

-

- Each link below displays a global profile in zoomable graph form as - produced by pprof's "web" command. - - In addition there is a link to download the profile for offline - analysis with pprof. - - All four profiles represent causes of delay that prevent a goroutine - from running on a logical processor: because it was waiting for the network, - for a synchronization operation on a mutex or channel, for a system call, - or for a logical processor to become available. -

- - -

User-defined tasks and regions

-

- The trace API allows a target program to annotate a region of code - within a goroutine, such as a key function, so that its performance - can be analyzed. - - Log events may be - associated with a region to record progress and relevant values. - - The API also allows annotation of higher-level - tasks, - which may involve work across many goroutines. -

-

- The links below display, for each region and task, a histogram of its execution times. - - Each histogram bucket contains a sample trace that records the - sequence of events such as goroutine creations, log events, and - subregion start/end times. - - For each task, you can click through to a logical-processor or - goroutine-oriented view showing the tasks and regions on the - timeline. - - Such information may help uncover which steps in a region are - unexpectedly slow, or reveal relationships between the data values - logged in a request and its running time. -

- - -

Garbage collection metrics

- -

- This chart indicates the maximum GC pause time (the largest x value - for which y is zero), and more generally, the fraction of time that - the processors are available to application goroutines ("mutators"), - for any time window of a specified size, in the worst case. -

- - -`)) - func dief(msg string, args ...any) { fmt.Fprintf(os.Stderr, msg, args...) os.Exit(1) diff --git a/src/cmd/trace/mmu.go b/src/cmd/trace/mmu.go index b71dcd6411..43017c857e 100644 --- a/src/cmd/trace/mmu.go +++ b/src/cmd/trace/mmu.go @@ -29,6 +29,7 @@ import ( "encoding/json" "fmt" "internal/trace" + "internal/trace/traceviewer" "log" "math" "net/http" @@ -393,7 +394,7 @@ type linkedUtilWindow struct { func newLinkedUtilWindow(ui trace.UtilWindow, window time.Duration) linkedUtilWindow { // Find the range containing this window. - var r Range + var r traceviewer.Range for _, r = range ranges { if r.EndTime > ui.Time { break diff --git a/src/cmd/trace/trace.go b/src/cmd/trace/trace.go index 618df42033..865bc612a9 100644 --- a/src/cmd/trace/trace.go +++ b/src/cmd/trace/trace.go @@ -5,29 +5,24 @@ package main import ( - "cmd/internal/traceviewer" - "embed" - "encoding/json" "fmt" "internal/trace" - "io" + "internal/trace/traceviewer" "log" "math" "net/http" "runtime/debug" "sort" "strconv" - "strings" "time" -) -//go:embed static/trace_viewer_full.html static/webcomponents.min.js -var staticContent embed.FS + "internal/trace/traceviewer/format" +) func init() { http.HandleFunc("/trace", httpTrace) http.HandleFunc("/jsontrace", httpJsonTrace) - http.Handle("/static/", http.FileServer(http.FS(staticContent))) + http.Handle("/static/", traceviewer.StaticHandler()) } // httpTrace serves either whole trace (goid==0) or trace for goid goroutine. @@ -37,142 +32,8 @@ func httpTrace(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } - if err := r.ParseForm(); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - html := strings.ReplaceAll(templTrace, "{{PARAMS}}", r.Form.Encode()) - w.Write([]byte(html)) - -} - -// https://chromium.googlesource.com/catapult/+/9508452e18f130c98499cb4c4f1e1efaedee8962/tracing/docs/embedding-trace-viewer.md -// This is almost verbatim copy of https://chromium-review.googlesource.com/c/catapult/+/2062938/2/tracing/bin/index.html -var templTrace = ` - - - - - - - - - - - - - -` // httpJsonTrace serves json trace, requested from within templTrace HTML. func httpJsonTrace(w http.ResponseWriter, r *http.Request) { @@ -203,7 +64,7 @@ func httpJsonTrace(w http.ResponseWriter, r *http.Request) { log.Printf("failed to find goroutine %d", goid) return } - params.mode = modeGoroutineOriented + params.mode = traceviewer.ModeGoroutineOriented params.startTime = g.StartTime if g.EndTime != 0 { params.endTime = g.EndTime @@ -225,7 +86,7 @@ func httpJsonTrace(w http.ResponseWriter, r *http.Request) { return } goid := task.events[0].G - params.mode = modeGoroutineOriented | modeTaskOriented + params.mode = traceviewer.ModeGoroutineOriented | traceviewer.ModeTaskOriented params.startTime = task.firstTimestamp() - 1 params.endTime = task.lastTimestamp() + 1 params.maing = goid @@ -250,7 +111,7 @@ func httpJsonTrace(w http.ResponseWriter, r *http.Request) { log.Printf("failed to find task with id %d", taskid) return } - params.mode = modeTaskOriented + params.mode = traceviewer.ModeTaskOriented params.startTime = task.firstTimestamp() - 1 params.endTime = task.lastTimestamp() + 1 params.tasks = task.descendants() @@ -272,247 +133,31 @@ func httpJsonTrace(w http.ResponseWriter, r *http.Request) { } } - c := viewerDataTraceConsumer(w, start, end) + c := traceviewer.ViewerDataTraceConsumer(w, start, end) if err := generateTrace(params, c); err != nil { log.Printf("failed to generate trace: %v", err) return } } -type Range struct { - Name string - Start int - End int - StartTime int64 - EndTime int64 -} - -func (r Range) URL() string { - return fmt.Sprintf("/trace?start=%d&end=%d", r.Start, r.End) -} - // 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) []Range { +func splitTrace(res trace.ParseResult) []traceviewer.Range { params := &traceParams{ parsed: res, endTime: math.MaxInt64, } - s, c := splittingTraceConsumer(100 << 20) // 100M + s, c := traceviewer.SplittingTraceConsumer(100 << 20) // 100M if err := generateTrace(params, c); err != nil { dief("%v\n", err) } return s.Ranges } -type splitter struct { - Ranges []Range -} - -// walkStackFrames calls fn for id and all of its parent frames from allFrames. -func walkStackFrames(allFrames map[string]traceviewer.Frame, id int, fn func(id int)) { - for id != 0 { - f, ok := allFrames[strconv.Itoa(id)] - if !ok { - break - } - fn(id) - id = f.Parent - } -} - -func stackFrameEncodedSize(id uint, f traceviewer.Frame) int { - // We want to know the marginal size of traceviewer.Data.Frames for - // each event. Running full JSON encoding of the map for each event is - // far too slow. - // - // Since the format is fixed, we can easily compute the size without - // encoding. - // - // A single entry looks like one of the following: - // - // "1":{"name":"main.main:30"}, - // "10":{"name":"pkg.NewSession:173","parent":9}, - // - // The parent is omitted if 0. The trailing comma is omitted from the - // last entry, but we don't need that much precision. - const ( - baseSize = len(`"`) + len(`":{"name":"`) + len(`"},`) - - // Don't count the trailing quote on the name, as that is - // counted in baseSize. - parentBaseSize = len(`,"parent":`) - ) - - size := baseSize - - size += len(f.Name) - - // Bytes for id (always positive). - for id > 0 { - size += 1 - id /= 10 - } - - if f.Parent > 0 { - size += parentBaseSize - // Bytes for parent (always positive). - for f.Parent > 0 { - size += 1 - f.Parent /= 10 - } - } - - return size -} - -func splittingTraceConsumer(max int) (*splitter, traceConsumer) { - type eventSz struct { - Time float64 - Sz int - Frames []int - } - - var ( - // data.Frames contains only the frames for required events. - data = traceviewer.Data{Frames: make(map[string]traceviewer.Frame)} - - allFrames = make(map[string]traceviewer.Frame) - - sizes []eventSz - cw countingWriter - ) - - s := new(splitter) - - return s, traceConsumer{ - consumeTimeUnit: func(unit string) { - data.TimeUnit = unit - }, - consumeViewerEvent: func(v *traceviewer.Event, required bool) { - if required { - // Store required events inside data so flush - // can include them in the required part of the - // trace. - data.Events = append(data.Events, v) - walkStackFrames(allFrames, v.Stack, func(id int) { - s := strconv.Itoa(id) - data.Frames[s] = allFrames[s] - }) - walkStackFrames(allFrames, v.EndStack, func(id int) { - s := strconv.Itoa(id) - data.Frames[s] = allFrames[s] - }) - return - } - enc := json.NewEncoder(&cw) - enc.Encode(v) - size := eventSz{Time: v.Time, Sz: cw.size + 1} // +1 for ",". - // Add referenced stack frames. Their size is computed - // in flush, where we can dedup across events. - walkStackFrames(allFrames, v.Stack, func(id int) { - size.Frames = append(size.Frames, id) - }) - walkStackFrames(allFrames, v.EndStack, func(id int) { - size.Frames = append(size.Frames, id) // This may add duplicates. We'll dedup later. - }) - sizes = append(sizes, size) - cw.size = 0 - }, - consumeViewerFrame: func(k string, v traceviewer.Frame) { - allFrames[k] = v - }, - flush: func() { - // Calculate size of the mandatory part of the trace. - // This includes thread names and stack frames for - // required events. - cw.size = 0 - enc := json.NewEncoder(&cw) - enc.Encode(data) - requiredSize := cw.size - - // Then calculate size of each individual event and - // their stack frames, grouping them into ranges. We - // only include stack frames relevant to the events in - // the range to reduce overhead. - - var ( - start = 0 - - eventsSize = 0 - - frames = make(map[string]traceviewer.Frame) - framesSize = 0 - ) - for i, ev := range sizes { - eventsSize += ev.Sz - - // Add required stack frames. Note that they - // may already be in the map. - for _, id := range ev.Frames { - s := strconv.Itoa(id) - _, ok := frames[s] - if ok { - continue - } - f := allFrames[s] - frames[s] = f - framesSize += stackFrameEncodedSize(uint(id), f) - } - - total := requiredSize + framesSize + eventsSize - if total < max { - continue - } - - // Reached max size, commit this range and - // start a new range. - startTime := time.Duration(sizes[start].Time * 1000) - endTime := time.Duration(ev.Time * 1000) - ranges = append(ranges, Range{ - Name: fmt.Sprintf("%v-%v", startTime, endTime), - Start: start, - End: i + 1, - StartTime: int64(startTime), - EndTime: int64(endTime), - }) - start = i + 1 - frames = make(map[string]traceviewer.Frame) - framesSize = 0 - eventsSize = 0 - } - if len(ranges) <= 1 { - s.Ranges = nil - return - } - - if end := len(sizes) - 1; start < end { - ranges = append(ranges, Range{ - Name: fmt.Sprintf("%v-%v", time.Duration(sizes[start].Time*1000), time.Duration(sizes[end].Time*1000)), - Start: start, - End: end, - StartTime: int64(sizes[start].Time * 1000), - EndTime: int64(sizes[end].Time * 1000), - }) - } - s.Ranges = ranges - }, - } -} - -type countingWriter struct { - size int -} - -func (cw *countingWriter) Write(data []byte) (int, error) { - cw.size += len(data) - return len(data), nil -} - type traceParams struct { parsed trace.ParseResult - mode traceviewMode + mode traceviewer.Mode startTime int64 endTime int64 maing uint64 // for goroutine-oriented view, place this goroutine on the top row @@ -520,59 +165,18 @@ type traceParams struct { tasks []*taskDesc // Tasks to be displayed. tasks[0] is the top-most task } -type traceviewMode uint - -const ( - modeGoroutineOriented traceviewMode = 1 << iota - modeTaskOriented -) - type traceContext struct { *traceParams - consumer traceConsumer - frameTree frameNode - frameSeq int - arrowSeq uint64 - gcount uint64 - - heapStats, prevHeapStats heapStats - threadStats, prevThreadStats threadStats - gstates, prevGstates [gStateCount]int64 - + consumer traceviewer.TraceConsumer + emitter *traceviewer.Emitter + arrowSeq uint64 + gcount uint64 regionID int // last emitted region id. incremented in each emitRegion call. } -type heapStats struct { - heapAlloc uint64 - nextGC uint64 -} - -type threadStats struct { - insyscallRuntime int64 // system goroutine in syscall - insyscall int64 // user goroutine in syscall - prunning int64 // thread running P -} - -type frameNode struct { - id int - children map[uint64]frameNode -} - -type gState int - -const ( - gDead gState = iota - gRunnable - gRunning - gWaiting - gWaitingGC - - gStateCount -) - type gInfo struct { - state gState // current state - name string // name chosen for this goroutine at first EvGoStart + 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. @@ -596,19 +200,6 @@ type SortIndexArg struct { Index int `json:"sort_index"` } -type traceConsumer struct { - consumeTimeUnit func(unit string) - consumeViewerEvent func(v *traceviewer.Event, required bool) - consumeViewerFrame func(key string, f traceviewer.Frame) - flush func() -} - -const ( - procsSection = 0 // where Goroutines or per-P timelines are presented. - statsSection = 1 // where counters are presented. - tasksSection = 2 // where Task hierarchy & timeline is presented. -) - // generateTrace generates json trace for trace-viewer: // https://github.com/google/trace-viewer // Trace format is described at: @@ -616,14 +207,23 @@ const ( // 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 traceConsumer) error { - defer consumer.flush() +func generateTrace(params *traceParams, consumer traceviewer.TraceConsumer) error { + emitter := traceviewer.NewEmitter( + consumer, + params.mode, + 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} - ctx.frameTree.children = make(map[uint64]frameNode) + ctx := &traceContext{traceParams: params, emitter: emitter} ctx.consumer = consumer - ctx.consumer.consumeTimeUnit("ns") maxProc := 0 ginfos := make(map[uint64]*gInfo) stacks := params.parsed.Stacks @@ -640,17 +240,17 @@ func generateTrace(params *traceParams, consumer traceConsumer) error { // 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 gState) { + setGState := func(ev *trace.Event, g uint64, oldState, newState traceviewer.GState) { info := getGInfo(g) - if oldState == gWaiting && info.state == gWaitingGC { - // For checking, gWaiting counts as any gWaiting*. + 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) } - ctx.gstates[info.state]-- - ctx.gstates[newState]++ + + emitter.GoroutineTransition(time.Duration(ev.Ts), info.state, newState) info.state = newState } @@ -658,13 +258,13 @@ func generateTrace(params *traceParams, consumer traceConsumer) error { // Handle state transitions before we filter out events. switch ev.Type { case trace.EvGoStart, trace.EvGoStartLabel: - setGState(ev, ev.G, gRunnable, gRunning) + setGState(ev, ev.G, traceviewer.GRunnable, traceviewer.GRunning) info := getGInfo(ev.G) info.start = ev case trace.EvProcStart: - ctx.threadStats.prunning++ + emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateRunning, 1) case trace.EvProcStop: - ctx.threadStats.prunning-- + emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateRunning, -1) case trace.EvGoCreate: newG := ev.Args[0] info := getGInfo(newG) @@ -682,58 +282,59 @@ func generateTrace(params *traceParams, consumer traceConsumer) error { info.isSystemG = trace.IsSystemGoroutine(fname) ctx.gcount++ - setGState(ev, newG, gDead, gRunnable) + setGState(ev, newG, traceviewer.GDead, traceviewer.GRunnable) case trace.EvGoEnd: ctx.gcount-- - setGState(ev, ev.G, gRunning, gDead) + setGState(ev, ev.G, traceviewer.GRunning, traceviewer.GDead) case trace.EvGoUnblock: - setGState(ev, ev.Args[0], gWaiting, gRunnable) + setGState(ev, ev.Args[0], traceviewer.GWaiting, traceviewer.GRunnable) case trace.EvGoSysExit: - setGState(ev, ev.G, gWaiting, gRunnable) + setGState(ev, ev.G, traceviewer.GWaiting, traceviewer.GRunnable) if getGInfo(ev.G).isSystemG { - ctx.threadStats.insyscallRuntime-- + emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscallRuntime, -1) } else { - ctx.threadStats.insyscall-- + emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscall, -1) } case trace.EvGoSysBlock: - setGState(ev, ev.G, gRunning, gWaiting) + setGState(ev, ev.G, traceviewer.GRunning, traceviewer.GWaiting) if getGInfo(ev.G).isSystemG { - ctx.threadStats.insyscallRuntime++ + emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscallRuntime, 1) } else { - ctx.threadStats.insyscall++ + emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscall, 1) } case trace.EvGoSched, trace.EvGoPreempt: - setGState(ev, ev.G, gRunning, gRunnable) + 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, gRunning, gWaiting) + setGState(ev, ev.G, traceviewer.GRunning, traceviewer.GWaiting) case trace.EvGoBlockGC: - setGState(ev, ev.G, gRunning, gWaitingGC) + 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, gRunnable, gWaiting) + setGState(ev, ev.G, traceviewer.GRunnable, traceviewer.GWaiting) case trace.EvGoInSyscall: // Cancel out the effect of EvGoCreate at the beginning. - setGState(ev, ev.G, gRunnable, gWaiting) + setGState(ev, ev.G, traceviewer.GRunnable, traceviewer.GWaiting) if getGInfo(ev.G).isSystemG { - ctx.threadStats.insyscallRuntime++ + emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscallRuntime, 1) } else { - ctx.threadStats.insyscall++ + emitter.IncThreadStateCount(time.Duration(ev.Ts), traceviewer.ThreadStateInSyscall, 1) } case trace.EvHeapAlloc: - ctx.heapStats.heapAlloc = ev.Args[0] + emitter.HeapAlloc(time.Duration(ev.Ts), ev.Args[0]) case trace.EvHeapGoal: - ctx.heapStats.nextGC = ev.Args[0] + emitter.HeapGoal(time.Duration(ev.Ts), ev.Args[0]) } if setGStateErr != nil { return setGStateErr } - if ctx.gstates[gRunnable] < 0 || ctx.gstates[gRunning] < 0 || ctx.threadStats.insyscall < 0 || ctx.threadStats.insyscallRuntime < 0 { - return fmt.Errorf("invalid state after processing %v: runnable=%d running=%d insyscall=%d insyscallRuntime=%d", ev, ctx.gstates[gRunnable], ctx.gstates[gRunning], ctx.threadStats.insyscall, ctx.threadStats.insyscallRuntime) + + if err := emitter.Err(); err != nil { + return fmt.Errorf("invalid state after processing %v: %s", ev, err) } // Ignore events that are from uninteresting goroutines @@ -752,12 +353,12 @@ func generateTrace(params *traceParams, consumer traceConsumer) error { // Emit trace objects. switch ev.Type { case trace.EvProcStart: - if ctx.mode&modeGoroutineOriented != 0 { + if ctx.mode&traceviewer.ModeGoroutineOriented != 0 { continue } ctx.emitInstant(ev, "proc start", "") case trace.EvProcStop: - if ctx.mode&modeGoroutineOriented != 0 { + if ctx.mode&traceviewer.ModeGoroutineOriented != 0 { continue } ctx.emitInstant(ev, "proc stop", "") @@ -765,7 +366,7 @@ func generateTrace(params *traceParams, consumer traceConsumer) error { ctx.emitSlice(ev, "GC") case trace.EvGCDone: case trace.EvSTWStart: - if ctx.mode&modeGoroutineOriented != 0 { + if ctx.mode&traceviewer.ModeGoroutineOriented != 0 { continue } ctx.emitSlice(ev, fmt.Sprintf("STW (%s)", ev.SArgs[0])) @@ -832,46 +433,10 @@ func generateTrace(params *traceParams, consumer traceConsumer) error { ctx.emitInstant(ev, "CPU profile sample", "") } } - // Emit any counter updates. - ctx.emitThreadCounters(ev) - ctx.emitHeapCounters(ev) - ctx.emitGoroutineCounters(ev) - } - - ctx.emitSectionFooter(statsSection, "STATS", 0) - - if ctx.mode&modeTaskOriented != 0 { - ctx.emitSectionFooter(tasksSection, "TASKS", 1) - } - - if ctx.mode&modeGoroutineOriented != 0 { - ctx.emitSectionFooter(procsSection, "G", 2) - } else { - ctx.emitSectionFooter(procsSection, "PROCS", 2) - } - - ctx.emitFooter(&traceviewer.Event{Name: "thread_name", Phase: "M", PID: procsSection, TID: trace.GCP, Arg: &NameArg{"GC"}}) - ctx.emitFooter(&traceviewer.Event{Name: "thread_sort_index", Phase: "M", PID: procsSection, TID: trace.GCP, Arg: &SortIndexArg{-6}}) - - ctx.emitFooter(&traceviewer.Event{Name: "thread_name", Phase: "M", PID: procsSection, TID: trace.NetpollP, Arg: &NameArg{"Network"}}) - ctx.emitFooter(&traceviewer.Event{Name: "thread_sort_index", Phase: "M", PID: procsSection, TID: trace.NetpollP, Arg: &SortIndexArg{-5}}) - - ctx.emitFooter(&traceviewer.Event{Name: "thread_name", Phase: "M", PID: procsSection, TID: trace.TimerP, Arg: &NameArg{"Timers"}}) - ctx.emitFooter(&traceviewer.Event{Name: "thread_sort_index", Phase: "M", PID: procsSection, TID: trace.TimerP, Arg: &SortIndexArg{-4}}) - - ctx.emitFooter(&traceviewer.Event{Name: "thread_name", Phase: "M", PID: procsSection, TID: trace.SyscallP, Arg: &NameArg{"Syscalls"}}) - ctx.emitFooter(&traceviewer.Event{Name: "thread_sort_index", Phase: "M", PID: procsSection, TID: trace.SyscallP, Arg: &SortIndexArg{-3}}) - - // Display rows for Ps if we are in the default trace view mode (not goroutine-oriented presentation) - if ctx.mode&modeGoroutineOriented == 0 { - for i := 0; i <= maxProc; i++ { - ctx.emitFooter(&traceviewer.Event{Name: "thread_name", Phase: "M", PID: procsSection, TID: uint64(i), Arg: &NameArg{fmt.Sprintf("Proc %v", i)}}) - ctx.emitFooter(&traceviewer.Event{Name: "thread_sort_index", Phase: "M", PID: procsSection, TID: uint64(i), Arg: &SortIndexArg{i}}) - } } // Display task and its regions if we are in task-oriented presentation mode. - if ctx.mode&modeTaskOriented != 0 { + if ctx.mode&traceviewer.ModeTaskOriented != 0 { // sort tasks based on the task start time. sortedTask := make([]*taskDesc, len(ctx.tasks)) copy(sortedTask, ctx.tasks) @@ -888,7 +453,7 @@ func generateTrace(params *traceParams, consumer traceConsumer) error { // 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&modeGoroutineOriented != 0 { + if ctx.mode&traceviewer.ModeGoroutineOriented != 0 { for _, s := range task.regions { ctx.emitRegion(s) } @@ -897,34 +462,34 @@ func generateTrace(params *traceParams, consumer traceConsumer) error { } // Display goroutine rows if we are either in goroutine-oriented mode. - if ctx.mode&modeGoroutineOriented != 0 { + if ctx.mode&traceviewer.ModeGoroutineOriented != 0 { for k, v := range ginfos { if !ctx.gs[k] { continue } - ctx.emitFooter(&traceviewer.Event{Name: "thread_name", Phase: "M", PID: procsSection, TID: k, Arg: &NameArg{v.name}}) + emitter.Resource(k, v.name) } - // Row for the main goroutine (maing) - ctx.emitFooter(&traceviewer.Event{Name: "thread_sort_index", Phase: "M", PID: procsSection, TID: ctx.maing, Arg: &SortIndexArg{-2}}) + emitter.Focus(ctx.maing) + // Row for GC or global state (specified with G=0) - ctx.emitFooter(&traceviewer.Event{Name: "thread_sort_index", Phase: "M", PID: procsSection, TID: 0, Arg: &SortIndexArg{-1}}) + 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 *traceviewer.Event) { - ctx.consumer.consumeViewerEvent(e, false) +func (ctx *traceContext) emit(e *format.Event) { + ctx.consumer.ConsumeViewerEvent(e, false) } -func (ctx *traceContext) emitFooter(e *traceviewer.Event) { - ctx.consumer.consumeViewerEvent(e, true) -} -func (ctx *traceContext) emitSectionFooter(sectionID uint64, name string, priority int) { - ctx.emitFooter(&traceviewer.Event{Name: "process_name", Phase: "M", PID: sectionID, Arg: &NameArg{name}}) - ctx.emitFooter(&traceviewer.Event{Name: "process_sort_index", Phase: "M", PID: sectionID, Arg: &SortIndexArg{priority}}) +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 @@ -942,7 +507,7 @@ func tsWithinRange(ts, s, e int64) bool { } func (ctx *traceContext) proc(ev *trace.Event) uint64 { - if ctx.mode&modeGoroutineOriented != 0 && ev.P < trace.FakeP { + if ctx.mode&traceviewer.ModeGoroutineOriented != 0 && ev.P < trace.FakeP { return ev.G } else { return uint64(ev.P) @@ -953,7 +518,7 @@ func (ctx *traceContext) emitSlice(ev *trace.Event, name string) { ctx.emit(ctx.makeSlice(ev, name)) } -func (ctx *traceContext) makeSlice(ev *trace.Event, name string) *traceviewer.Event { +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. @@ -961,18 +526,18 @@ func (ctx *traceContext) makeSlice(ev *trace.Event, name string) *traceviewer.Ev if ev.Link.Ts-ev.Ts <= 0 { durationUsec = 0.0001 // 0.1 nanoseconds } - sl := &traceviewer.Event{ + sl := &format.Event{ Name: name, Phase: "X", Time: ctx.time(ev), Dur: durationUsec, TID: ctx.proc(ev), - Stack: ctx.stack(ev.Stk), - EndStack: ctx.stack(ev.Link.Stk), + 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&modeTaskOriented != 0 && 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 { @@ -1000,25 +565,25 @@ func (ctx *traceContext) emitTask(task *taskDesc, sortIndex int) { taskName := task.name durationUsec := float64(task.lastTimestamp()-task.firstTimestamp()) / 1e3 - ctx.emitFooter(&traceviewer.Event{Name: "thread_name", Phase: "M", PID: tasksSection, TID: taskRow, Arg: &NameArg{fmt.Sprintf("T%d %s", task.id, taskName)}}) - ctx.emit(&traceviewer.Event{Name: "thread_sort_index", Phase: "M", PID: tasksSection, TID: taskRow, Arg: &SortIndexArg{sortIndex}}) + ctx.emitFooter(&format.Event{Name: "thread_name", Phase: "M", PID: format.TasksSection, TID: taskRow, Arg: &NameArg{fmt.Sprintf("T%d %s", task.id, taskName)}}) + ctx.emit(&format.Event{Name: "thread_sort_index", Phase: "M", PID: format.TasksSection, TID: taskRow, Arg: &SortIndexArg{sortIndex}}) ts := float64(task.firstTimestamp()) / 1e3 - sl := &traceviewer.Event{ + sl := &format.Event{ Name: taskName, Phase: "X", Time: ts, Dur: durationUsec, - PID: tasksSection, + PID: format.TasksSection, TID: taskRow, Cname: pickTaskColor(task.id), } targ := TaskArg{ID: task.id} if task.create != nil { - sl.Stack = ctx.stack(task.create.Stk) + sl.Stack = ctx.emitter.Stack(task.create.Stk) targ.StartG = task.create.G } if task.end != nil { - sl.EndStack = ctx.stack(task.end.Stk) + sl.EndStack = ctx.emitter.Stack(task.end.Stk) targ.EndG = task.end.G } sl.Arg = targ @@ -1026,8 +591,8 @@ func (ctx *traceContext) emitTask(task *taskDesc, sortIndex int) { if task.create != nil && task.create.Type == trace.EvUserTaskCreate && task.create.Args[1] != 0 { ctx.arrowSeq++ - ctx.emit(&traceviewer.Event{Name: "newTask", Phase: "s", TID: task.create.Args[1], ID: ctx.arrowSeq, Time: ts, PID: tasksSection}) - ctx.emit(&traceviewer.Event{Name: "newTask", Phase: "t", TID: taskRow, ID: ctx.arrowSeq, Time: ts, PID: tasksSection}) + 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}) } } @@ -1048,7 +613,7 @@ func (ctx *traceContext) emitRegion(s regionDesc) { scopeID := fmt.Sprintf("%x", id) name := s.Name - sl0 := &traceviewer.Event{ + sl0 := &format.Event{ Category: "Region", Name: name, Phase: "b", @@ -1059,11 +624,11 @@ func (ctx *traceContext) emitRegion(s regionDesc) { Cname: pickTaskColor(s.TaskID), } if s.Start != nil { - sl0.Stack = ctx.stack(s.Start.Stk) + sl0.Stack = ctx.emitter.Stack(s.Start.Stk) } ctx.emit(sl0) - sl1 := &traceviewer.Event{ + sl1 := &format.Event{ Category: "Region", Name: name, Phase: "e", @@ -1075,70 +640,18 @@ func (ctx *traceContext) emitRegion(s regionDesc) { Arg: RegionArg{TaskID: s.TaskID}, } if s.End != nil { - sl1.Stack = ctx.stack(s.End.Stk) + sl1.Stack = ctx.emitter.Stack(s.End.Stk) } ctx.emit(sl1) } -type heapCountersArg struct { - Allocated uint64 - NextGC uint64 -} - -func (ctx *traceContext) emitHeapCounters(ev *trace.Event) { - if ctx.prevHeapStats == ctx.heapStats { - return - } - diff := uint64(0) - if ctx.heapStats.nextGC > ctx.heapStats.heapAlloc { - diff = ctx.heapStats.nextGC - ctx.heapStats.heapAlloc - } - if tsWithinRange(ev.Ts, ctx.startTime, ctx.endTime) { - ctx.emit(&traceviewer.Event{Name: "Heap", Phase: "C", Time: ctx.time(ev), PID: 1, Arg: &heapCountersArg{ctx.heapStats.heapAlloc, diff}}) - } - ctx.prevHeapStats = ctx.heapStats -} - -type goroutineCountersArg struct { - Running uint64 - Runnable uint64 - GCWaiting uint64 -} - -func (ctx *traceContext) emitGoroutineCounters(ev *trace.Event) { - if ctx.prevGstates == ctx.gstates { - return - } - if tsWithinRange(ev.Ts, ctx.startTime, ctx.endTime) { - ctx.emit(&traceviewer.Event{Name: "Goroutines", Phase: "C", Time: ctx.time(ev), PID: 1, Arg: &goroutineCountersArg{uint64(ctx.gstates[gRunning]), uint64(ctx.gstates[gRunnable]), uint64(ctx.gstates[gWaitingGC])}}) - } - ctx.prevGstates = ctx.gstates -} - -type threadCountersArg struct { - Running int64 - InSyscall int64 -} - -func (ctx *traceContext) emitThreadCounters(ev *trace.Event) { - if ctx.prevThreadStats == ctx.threadStats { - return - } - if tsWithinRange(ev.Ts, ctx.startTime, ctx.endTime) { - ctx.emit(&traceviewer.Event{Name: "Threads", Phase: "C", Time: ctx.time(ev), PID: 1, Arg: &threadCountersArg{ - Running: ctx.threadStats.prunning, - InSyscall: ctx.threadStats.insyscall}}) - } - ctx.prevThreadStats = ctx.threadStats -} - func (ctx *traceContext) emitInstant(ev *trace.Event, name, category string) { if !tsWithinRange(ev.Ts, ctx.startTime, ctx.endTime) { return } cname := "" - if ctx.mode&modeTaskOriented != 0 { + if ctx.mode&traceviewer.ModeTaskOriented != 0 { taskID, isUserAnnotation := isUserAnnotationEvent(ev) show := false @@ -1163,14 +676,14 @@ func (ctx *traceContext) emitInstant(ev *trace.Event, name, category string) { } arg = &Arg{ev.Args[0]} } - ctx.emit(&traceviewer.Event{ + ctx.emit(&format.Event{ Name: name, Category: category, Phase: "I", Scope: "t", Time: ctx.time(ev), TID: ctx.proc(ev), - Stack: ctx.stack(ev.Stk), + Stack: ctx.emitter.Stack(ev.Stk), Cname: cname, Arg: arg}) } @@ -1181,7 +694,7 @@ func (ctx *traceContext) emitArrow(ev *trace.Event, name string) { // For example, a goroutine was unblocked but was not scheduled before trace stop. return } - if ctx.mode&modeGoroutineOriented != 0 && (!ctx.gs[ev.Link.G] || ev.Link.Ts < ctx.startTime || ev.Link.Ts > ctx.endTime) { + if ctx.mode&traceviewer.ModeGoroutineOriented != 0 && (!ctx.gs[ev.Link.G] || ev.Link.Ts < ctx.startTime || ev.Link.Ts > ctx.endTime) { return } @@ -1192,7 +705,7 @@ func (ctx *traceContext) emitArrow(ev *trace.Event, name string) { } color := "" - if ctx.mode&modeTaskOriented != 0 { + if ctx.mode&traceviewer.ModeTaskOriented != 0 { overlapping := false // skip non-overlapping arrows. for _, task := range ctx.tasks { @@ -1207,32 +720,8 @@ func (ctx *traceContext) emitArrow(ev *trace.Event, name string) { } ctx.arrowSeq++ - ctx.emit(&traceviewer.Event{Name: name, Phase: "s", TID: ctx.proc(ev), ID: ctx.arrowSeq, Time: ctx.time(ev), Stack: ctx.stack(ev.Stk), Cname: color}) - ctx.emit(&traceviewer.Event{Name: name, Phase: "t", TID: ctx.proc(ev.Link), ID: ctx.arrowSeq, Time: ctx.time(ev.Link), Cname: color}) -} - -func (ctx *traceContext) stack(stk []*trace.Frame) int { - return ctx.buildBranch(ctx.frameTree, stk) -} - -// buildBranch builds one branch in the prefix tree rooted at ctx.frameTree. -func (ctx *traceContext) buildBranch(parent frameNode, stk []*trace.Frame) int { - if len(stk) == 0 { - return parent.id - } - last := len(stk) - 1 - frame := stk[last] - stk = stk[:last] - - node, ok := parent.children[frame.PC] - if !ok { - ctx.frameSeq++ - node.id = ctx.frameSeq - node.children = make(map[uint64]frameNode) - parent.children[frame.PC] = node - ctx.consumer.consumeViewerFrame(strconv.Itoa(node.id), traceviewer.Frame{Name: fmt.Sprintf("%v:%v", frame.Fn, frame.Line), Parent: parent.id}) - } - return ctx.buildBranch(node, stk) + 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. @@ -1253,61 +742,6 @@ func lastTimestamp() int64 { return 0 } -type jsonWriter struct { - w io.Writer - enc *json.Encoder -} - -func viewerDataTraceConsumer(w io.Writer, start, end int64) traceConsumer { - allFrames := make(map[string]traceviewer.Frame) - requiredFrames := make(map[string]traceviewer.Frame) - enc := json.NewEncoder(w) - written := 0 - index := int64(-1) - - io.WriteString(w, "{") - return traceConsumer{ - consumeTimeUnit: func(unit string) { - io.WriteString(w, `"displayTimeUnit":`) - enc.Encode(unit) - io.WriteString(w, ",") - }, - consumeViewerEvent: func(v *traceviewer.Event, required bool) { - index++ - if !required && (index < start || index > end) { - // not in the range. Skip! - return - } - walkStackFrames(allFrames, v.Stack, func(id int) { - s := strconv.Itoa(id) - requiredFrames[s] = allFrames[s] - }) - walkStackFrames(allFrames, v.EndStack, func(id int) { - s := strconv.Itoa(id) - requiredFrames[s] = allFrames[s] - }) - if written == 0 { - io.WriteString(w, `"traceEvents": [`) - } - if written > 0 { - io.WriteString(w, ",") - } - enc.Encode(v) - // TODO: get rid of the extra \n inserted by enc.Encode. - // Same should be applied to splittingTraceConsumer. - written++ - }, - consumeViewerFrame: func(k string, v traceviewer.Frame) { - allFrames[k] = v - }, - flush: func() { - io.WriteString(w, `], "stackFrames":`) - enc.Encode(requiredFrames) - io.WriteString(w, `}`) - }, - } -} - // 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. diff --git a/src/cmd/trace/trace_test.go b/src/cmd/trace/trace_test.go index 87fd3a3515..d315fad471 100644 --- a/src/cmd/trace/trace_test.go +++ b/src/cmd/trace/trace_test.go @@ -7,9 +7,10 @@ package main import ( - "cmd/internal/traceviewer" "context" "internal/trace" + "internal/trace/traceviewer" + "internal/trace/traceviewer/format" "io" rtrace "runtime/trace" "strings" @@ -78,10 +79,10 @@ func TestGoroutineCount(t *testing.T) { // Use the default viewerDataTraceConsumer but replace // consumeViewerEvent to intercept the ViewerEvents for testing. - c := viewerDataTraceConsumer(io.Discard, 0, 1<<63-1) - c.consumeViewerEvent = func(ev *traceviewer.Event, _ bool) { + c := traceviewer.ViewerDataTraceConsumer(io.Discard, 0, 1<<63-1) + c.ConsumeViewerEvent = func(ev *format.Event, _ bool) { if ev.Name == "Goroutines" { - cnt := ev.Arg.(*goroutineCountersArg) + 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) } @@ -131,7 +132,7 @@ func TestGoroutineFilter(t *testing.T) { gs: map[uint64]bool{10: true}, } - c := viewerDataTraceConsumer(io.Discard, 0, 1<<63-1) + c := traceviewer.ViewerDataTraceConsumer(io.Discard, 0, 1<<63-1) if err := generateTrace(params, c); err != nil { t.Fatalf("generateTrace failed: %v", err) } @@ -163,10 +164,10 @@ func TestPreemptedMarkAssist(t *testing.T) { endTime: int64(1<<63 - 1), } - c := viewerDataTraceConsumer(io.Discard, 0, 1<<63-1) + c := traceviewer.ViewerDataTraceConsumer(io.Discard, 0, 1<<63-1) marks := 0 - c.consumeViewerEvent = func(ev *traceviewer.Event, _ bool) { + c.ConsumeViewerEvent = func(ev *format.Event, _ bool) { if strings.Contains(ev.Name, "MARK ASSIST") { marks++ } @@ -208,16 +209,16 @@ func TestFoo(t *testing.T) { params := &traceParams{ parsed: res, - mode: modeTaskOriented, + mode: traceviewer.ModeTaskOriented, startTime: task.firstTimestamp() - 1, endTime: task.lastTimestamp() + 1, tasks: []*taskDesc{task}, } - c := viewerDataTraceConsumer(io.Discard, 0, 1<<63-1) + c := traceviewer.ViewerDataTraceConsumer(io.Discard, 0, 1<<63-1) var logBeforeTaskEnd, logAfterTaskEnd bool - c.consumeViewerEvent = func(ev *traceviewer.Event, _ bool) { + c.ConsumeViewerEvent = func(ev *format.Event, _ bool) { if ev.Name == "log before task ends" { logBeforeTaskEnd = true } diff --git a/src/cmd/trace/trace_unix_test.go b/src/cmd/trace/trace_unix_test.go index 87ad86fce8..e634635427 100644 --- a/src/cmd/trace/trace_unix_test.go +++ b/src/cmd/trace/trace_unix_test.go @@ -8,9 +8,10 @@ package main import ( "bytes" - "cmd/internal/traceviewer" "internal/goexperiment" traceparser "internal/trace" + "internal/trace/traceviewer" + "internal/trace/traceviewer/format" "io" "runtime" "runtime/trace" @@ -87,10 +88,10 @@ func TestGoroutineInSyscall(t *testing.T) { // Check only one thread for the pipe read goroutine is // considered in-syscall. - c := viewerDataTraceConsumer(io.Discard, 0, 1<<63-1) - c.consumeViewerEvent = func(ev *traceviewer.Event, _ bool) { + c := traceviewer.ViewerDataTraceConsumer(io.Discard, 0, 1<<63-1) + c.ConsumeViewerEvent = func(ev *format.Event, _ bool) { if ev.Name == "Threads" { - arg := ev.Arg.(*threadCountersArg) + arg := ev.Arg.(*format.ThreadCountersArg) if arg.InSyscall > 1 { t.Errorf("%d threads in syscall at time %v; want less than 1 thread in syscall", arg.InSyscall, ev.Time) } diff --git a/src/cmd/trace/v2/gen.go b/src/cmd/trace/v2/gen.go new file mode 100644 index 0000000000..cf8960390c --- /dev/null +++ b/src/cmd/trace/v2/gen.go @@ -0,0 +1,249 @@ +// 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 ( + "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) + + // Finish indicates the end of the trace and finalizes generation. + Finish(ctx *traceContext, endTime tracev2.Time) +} + +// runGenerator produces a trace into ctx by running the generator over the parsed trace. +func runGenerator(ctx *traceContext, g generator, parsed *parsedTrace) { + 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) + } + } + } + g.Finish(ctx, parsed.events[len(parsed.events)-1].Time()) +} + +// 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, endTime tracev2.Time) { + for name, ar := range g.ranges { + if !strings.Contains(name, "GC") { + continue + } + ctx.Slice(traceviewer.SliceEvent{ + Name: name, + Ts: ctx.elapsed(ar.time), + Dur: 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, endTime tracev2.Time) { + for r, ar := range g.ranges { + ctx.Slice(traceviewer.SliceEvent{ + Name: r.Name, + Ts: ctx.elapsed(ar.time), + Dur: 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 +} diff --git a/src/cmd/trace/v2/gstate.go b/src/cmd/trace/v2/gstate.go new file mode 100644 index 0000000000..c0c100c6d7 --- /dev/null +++ b/src/cmd/trace/v2/gstate.go @@ -0,0 +1,362 @@ +// 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 } + +// 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 gorotuine 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) { + // Unblocking goroutine. + name := "unblock" + viewerResource := uint64(resource) + if strings.Contains(gs.startBlockReason, "network") { + // Emit an unblock instant event for the "Network" lane. + ctx.Instant(traceviewer.InstantEvent{ + Name: name, + Ts: ctx.elapsed(ts), + Resource: trace.NetpollP, + Stack: ctx.Stack(viewerFrames(stack)), + }) + gs.startBlockReason = "" + viewerResource = trace.NetpollP + } + 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(ts tracev2.Time, ctx *traceContext) { + if gs.executing != R(noResource) { + gs.syscallEnd(ts, false, ctx) + gs.stop(ts, 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 new file mode 100644 index 0000000000..5b98850c20 --- /dev/null +++ b/src/cmd/trace/v2/jsontrace.go @@ -0,0 +1,67 @@ +// 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 ( + "log" + "math" + "net/http" + "strconv" + "time" + + "internal/trace/traceviewer" + tracev2 "internal/trace/v2" +) + +func JSONTraceHandler(parsed *parsedTrace) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // 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, 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 +} + +// 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) +} + +func generateTrace(parsed *parsedTrace, c traceviewer.TraceConsumer) error { + ctx := &traceContext{ + Emitter: traceviewer.NewEmitter(c, 0, time.Duration(0), time.Duration(math.MaxInt64)), + startTime: parsed.events[0].Time(), + } + defer ctx.Flush() + + runGenerator(ctx, newProcGenerator(), parsed) + return nil +} diff --git a/src/cmd/trace/v2/jsontrace_test.go b/src/cmd/trace/v2/jsontrace_test.go new file mode 100644 index 0000000000..7e0b794159 --- /dev/null +++ b/src/cmd/trace/v2/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 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" && e.Phase == "I" && e.Scope == "t" { + count++ + netBlockEv = e + } + } + if netBlockEv == nil { + t.Error("failed to find a network unblock") + } + if count == 0 || count > 2 { + t.Errorf("found too many network block events: want 1 or 2, found %d", count) + } + // 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) + 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 new file mode 100644 index 0000000000..93c9d89c20 --- /dev/null +++ b/src/cmd/trace/v2/main.go @@ -0,0 +1,136 @@ +// 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" + tracev2 "internal/trace/v2" + "io" + "log" + "net" + "net/http" + "os" + + "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() + + // 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("Parsing trace...") + parsed, err := parseTrace(tracef) + 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() + + log.Print("Splitting trace...") + ranges, err := splitTrace(parsed) + if err != nil { + return err + } + + log.Printf("Opening browser. Trace viewer is listening on %s", addr) + browser.Open(addr) + + mux := http.NewServeMux() + mux.Handle("/", traceviewer.MainHandler(ranges)) + mux.Handle("/trace", traceviewer.TraceHandler()) + mux.Handle("/jsontrace", JSONTraceHandler(parsed)) + mux.Handle("/static/", traceviewer.StaticHandler()) + + err = http.Serve(ln, mux) + return fmt.Errorf("failed to start http server: %w", err) +} + +type parsedTrace struct { + events []tracev2.Event +} + +func parseTrace(trace io.Reader) (*parsedTrace, error) { + r, err := tracev2.NewReader(trace) + if err != nil { + return nil, fmt.Errorf("failed to create trace reader: %w", err) + } + var t parsedTrace + for { + ev, err := r.ReadEvent() + if err == io.EOF { + break + } else if err != nil { + return nil, fmt.Errorf("failed to read event: %w", err) + } + t.events = append(t.events, ev) + } + return &t, nil +} + +// 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, 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()) + } +} diff --git a/src/cmd/trace/v2/procgen.go b/src/cmd/trace/v2/procgen.go new file mode 100644 index 0000000000..a49f9ec632 --- /dev/null +++ b/src/cmd/trace/v2/procgen.go @@ -0,0 +1,209 @@ +// 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] + + gStates map[tracev2.GoID]*gState[tracev2.ProcID] + inSyscall map[tracev2.ProcID]*gState[tracev2.ProcID] + maxProc tracev2.ProcID +} + +func newProcGenerator() *procGenerator { + pg := new(procGenerator) + pg.stackSampleGenerator.getResource = func(ev *tracev2.Event) tracev2.ProcID { + return ev.Proc() + } + 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, endTime tracev2.Time) { + 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, endTime) + g.globalRangeGenerator.Finish(ctx, endTime) + + // Finish off all the goroutine slices. + for _, gs := range g.gStates { + gs.finish(endTime, 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/testdata/generate.go b/src/cmd/trace/v2/testdata/generate.go new file mode 100644 index 0000000000..c0658b2329 --- /dev/null +++ b/src/cmd/trace/v2/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/v2/testdata/go122.test b/src/cmd/trace/v2/testdata/go122.test new file mode 100644 index 0000000000..36a035d0a2 --- /dev/null +++ b/src/cmd/trace/v2/testdata/go122.test @@ -0,0 +1,4366 @@ +Trace Go1.22 +EventBatch gen=1 m=18446744073709551615 time=420903766321 size=5 +Frequency freq=15625000 +EventBatch gen=1 m=2852347 time=420902165664 size=321 +ProcStart dt=1006 p=6 p_seq=1 +GoStart dt=38 g=14 g_seq=1 +GoStop dt=299059 reason_string=16 stack=52 +GoStart dt=17 g=14 g_seq=2 +GoStop dt=316380 reason_string=16 stack=52 +GoStart dt=10 g=14 g_seq=3 +GoUnblock dt=165829 g=1 g_seq=59 stack=53 +GoDestroy dt=195 +GoStart dt=19 g=1 g_seq=60 +HeapAlloc dt=44 heapalloc_value=23256928 +HeapAlloc dt=19 heapalloc_value=23265088 +GoCreate dt=32 new_g=66 new_stack=54 stack=55 +GoBlock dt=12 reason_string=12 stack=56 +GoStart dt=5 g=66 g_seq=1 +HeapAlloc dt=199 heapalloc_value=23273224 +HeapAlloc dt=13 heapalloc_value=23281032 +GoSyscallBegin dt=19 p_seq=2 stack=57 +GoSyscallEnd dt=30 +GoSyscallBegin dt=10 p_seq=3 stack=58 +GoSyscallEnd dt=17 +GoSyscallBegin dt=295 p_seq=4 stack=59 +GoSyscallEnd dt=16 +GoSyscallBegin dt=6 p_seq=5 stack=60 +GoSyscallEnd dt=14 +HeapAlloc dt=216 heapalloc_value=23289000 +HeapAlloc dt=15 heapalloc_value=23296376 +HeapAlloc dt=19 heapalloc_value=23304328 +GoSyscallBegin dt=16 p_seq=6 stack=61 +GoSyscallEnd dt=15 +GoSyscallBegin dt=7 p_seq=7 stack=62 +GoSyscallEnd dt=14 +GoSyscallBegin dt=12 p_seq=8 stack=63 +ProcStart dt=787812 p=7 p_seq=8 +GoSyscallEndBlocked dt=6 +GoStart dt=1 g=66 g_seq=2 +GoUnblock dt=40 g=1 g_seq=61 stack=66 +GoDestroy dt=191 +GoStart dt=23 g=1 g_seq=62 +GoStop dt=27 reason_string=16 stack=67 +GoStart dt=12 g=1 g_seq=63 +HeapAlloc dt=433 heapalloc_value=23321416 +HeapAlloc dt=23 heapalloc_value=23329608 +HeapAlloc dt=27 heapalloc_value=23337800 +HeapAlloc dt=113 heapalloc_value=23344536 +HeapAlloc dt=447 heapalloc_value=23352728 +HeapAlloc dt=38 heapalloc_value=23360856 +GoSyscallBegin dt=19 p_seq=9 stack=68 +GoSyscallEnd dt=927 +HeapAlloc dt=22 heapalloc_value=23368952 +GoSyscallBegin dt=16 p_seq=10 stack=69 +GoSyscallEnd dt=30 +GoSyscallBegin dt=10 p_seq=11 stack=70 +GoSyscallEnd dt=20 +HeapAlloc dt=287 heapalloc_value=23434488 +GoSyscallBegin dt=45 p_seq=12 stack=71 +GoSyscallEnd dt=234 +GoSyscallBegin dt=11 p_seq=13 stack=71 +GoSyscallEnd dt=109 +GoSyscallBegin dt=77 p_seq=14 stack=72 +GoSyscallEnd dt=54 +GoSyscallBegin dt=22 p_seq=15 stack=73 +GoSyscallEnd dt=41 +GoSyscallBegin dt=24 p_seq=16 stack=74 +GoSyscallEnd dt=173 +GoSyscallBegin dt=11 p_seq=17 stack=75 +GoSyscallEnd dt=68 +HeapAlloc dt=134 heapalloc_value=23442648 +HeapAlloc dt=18 heapalloc_value=23450744 +GoCreate dt=23 new_g=82 new_stack=76 stack=77 +HeapAlloc dt=256 heapalloc_value=23458456 +GoSyscallBegin dt=293 p_seq=18 stack=78 +GoSyscallEnd dt=1156 +GoBlock dt=522 reason_string=7 stack=80 +ProcStop dt=25 +EventBatch gen=1 m=2852346 time=420902051246 size=68 +ProcStart dt=304 p=5 p_seq=1 +ProcStop dt=237 +ProcStart dt=1645 p=5 p_seq=2 +ProcStop dt=30 +ProcStart dt=2505 p=1 p_seq=31 +GoStart dt=199 g=34 g_seq=5 +GoBlock dt=29 reason_string=15 stack=26 +ProcStop dt=25 +ProcStart dt=103771 p=1 p_seq=32 +GoStart dt=185 g=10 g_seq=1 +GoStop dt=304886 reason_string=16 stack=52 +GoStart dt=20 g=10 g_seq=2 +GoStop dt=316414 reason_string=16 stack=52 +GoStart dt=20 g=10 g_seq=3 +GoDestroy dt=159939 +ProcStop dt=47 +EventBatch gen=1 m=2852345 time=420901844115 size=3554 +ProcStart dt=108 p=4 p_seq=1 +ProcStop dt=283 +ProcStart dt=3670 p=0 p_seq=27 +GoStart dt=473 g=1 g_seq=19 +GCMarkAssistEnd dt=34 +HeapAlloc dt=33 heapalloc_value=4117744 +HeapAlloc dt=544 heapalloc_value=4124912 +GCSweepBegin dt=49 stack=38 +GCSweepEnd dt=1131 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=64 heapalloc_value=4133104 +GCSweepBegin dt=44 stack=38 +GCSweepEnd dt=192 swept_value=139264 reclaimed_value=0 +HeapAlloc dt=12 heapalloc_value=4141296 +HeapAlloc dt=29 heapalloc_value=4149488 +HeapAlloc dt=19 heapalloc_value=4157680 +HeapAlloc dt=24 heapalloc_value=4165872 +HeapAlloc dt=23 heapalloc_value=4174064 +GCSweepBegin dt=34 stack=39 +GCSweepEnd dt=33 swept_value=67108864 reclaimed_value=0 +HeapAlloc dt=8 heapalloc_value=4182256 +HeapAlloc dt=117 heapalloc_value=4190448 +HeapAlloc dt=27 heapalloc_value=4198640 +HeapAlloc dt=19 heapalloc_value=4206832 +HeapAlloc dt=23 heapalloc_value=4215024 +HeapAlloc dt=20 heapalloc_value=4223216 +HeapAlloc dt=18 heapalloc_value=4231408 +HeapAlloc dt=70 heapalloc_value=4239600 +HeapAlloc dt=19 heapalloc_value=4247792 +HeapAlloc dt=16 heapalloc_value=4255984 +HeapAlloc dt=16 heapalloc_value=4264176 +HeapAlloc dt=15 heapalloc_value=4272368 +HeapAlloc dt=18 heapalloc_value=4280560 +HeapAlloc dt=15 heapalloc_value=4288752 +HeapAlloc dt=15 heapalloc_value=4296944 +HeapAlloc dt=17 heapalloc_value=4305136 +HeapAlloc dt=18 heapalloc_value=4313328 +HeapAlloc dt=17 heapalloc_value=4321520 +HeapAlloc dt=14 heapalloc_value=4329712 +HeapAlloc dt=15 heapalloc_value=4337904 +HeapAlloc dt=16 heapalloc_value=4346096 +HeapAlloc dt=15 heapalloc_value=4354288 +HeapAlloc dt=17 heapalloc_value=4362480 +HeapAlloc dt=38 heapalloc_value=4370672 +HeapAlloc dt=22 heapalloc_value=4378864 +HeapAlloc dt=23 heapalloc_value=4387056 +HeapAlloc dt=22 heapalloc_value=4395248 +HeapAlloc dt=27 heapalloc_value=4403440 +HeapAlloc dt=27 heapalloc_value=4411632 +HeapAlloc dt=29 heapalloc_value=4419824 +HeapAlloc dt=25 heapalloc_value=4428016 +HeapAlloc dt=25 heapalloc_value=4436208 +HeapAlloc dt=21 heapalloc_value=4444400 +GoBlock dt=45 reason_string=19 stack=21 +ProcStop dt=283 +ProcStart dt=17671 p=1 p_seq=16 +ProcStop dt=21 +ProcStart dt=2566 p=0 p_seq=30 +ProcStop dt=12 +ProcStart dt=16741 p=0 p_seq=31 +GoUnblock dt=27 g=1 g_seq=22 stack=0 +GoStart dt=174 g=1 g_seq=23 +HeapAlloc dt=39 heapalloc_value=5574896 +HeapAlloc dt=20 heapalloc_value=5583088 +HeapAlloc dt=13 heapalloc_value=5591280 +HeapAlloc dt=12 heapalloc_value=5599472 +HeapAlloc dt=12 heapalloc_value=5607664 +HeapAlloc dt=12 heapalloc_value=5615856 +HeapAlloc dt=13 heapalloc_value=5624048 +HeapAlloc dt=41 heapalloc_value=5632240 +HeapAlloc dt=12 heapalloc_value=5640432 +HeapAlloc dt=13 heapalloc_value=5648624 +HeapAlloc dt=11 heapalloc_value=5656816 +HeapAlloc dt=12 heapalloc_value=5665008 +HeapAlloc dt=8 heapalloc_value=5673200 +HeapAlloc dt=39 heapalloc_value=5804272 +HeapAlloc dt=2903 heapalloc_value=5812464 +HeapAlloc dt=14 heapalloc_value=5820656 +HeapAlloc dt=77 heapalloc_value=5828848 +HeapAlloc dt=10 heapalloc_value=5837040 +HeapAlloc dt=8 heapalloc_value=5845232 +HeapAlloc dt=48 heapalloc_value=5853424 +HeapAlloc dt=9 heapalloc_value=5861616 +HeapAlloc dt=8 heapalloc_value=5869808 +HeapAlloc dt=8 heapalloc_value=5878000 +HeapAlloc dt=9 heapalloc_value=5886192 +HeapAlloc dt=8 heapalloc_value=5894384 +HeapAlloc dt=8 heapalloc_value=5902576 +HeapAlloc dt=8 heapalloc_value=5910768 +HeapAlloc dt=8 heapalloc_value=5918960 +HeapAlloc dt=8 heapalloc_value=5927152 +HeapAlloc dt=8 heapalloc_value=5935344 +HeapAlloc dt=8 heapalloc_value=5943536 +HeapAlloc dt=17 heapalloc_value=5951728 +HeapAlloc dt=8 heapalloc_value=5959920 +HeapAlloc dt=6 heapalloc_value=5968112 +HeapAlloc dt=6 heapalloc_value=5976304 +HeapAlloc dt=6 heapalloc_value=5984496 +HeapAlloc dt=7 heapalloc_value=5992688 +HeapAlloc dt=6 heapalloc_value=6000880 +HeapAlloc dt=6 heapalloc_value=6009072 +HeapAlloc dt=7 heapalloc_value=6017264 +HeapAlloc dt=6 heapalloc_value=6025456 +HeapAlloc dt=6 heapalloc_value=6033648 +HeapAlloc dt=6 heapalloc_value=6041840 +HeapAlloc dt=6 heapalloc_value=6050032 +HeapAlloc dt=7 heapalloc_value=6058224 +HeapAlloc dt=44 heapalloc_value=6066416 +HeapAlloc dt=8 heapalloc_value=6074608 +HeapAlloc dt=71 heapalloc_value=6082800 +HeapAlloc dt=8 heapalloc_value=6090992 +HeapAlloc dt=6 heapalloc_value=6099184 +HeapAlloc dt=7 heapalloc_value=6107376 +HeapAlloc dt=6 heapalloc_value=6115568 +HeapAlloc dt=6 heapalloc_value=6123760 +HeapAlloc dt=7 heapalloc_value=6131952 +HeapAlloc dt=6 heapalloc_value=6140144 +HeapAlloc dt=6 heapalloc_value=6148336 +HeapAlloc dt=6 heapalloc_value=6156528 +HeapAlloc dt=7 heapalloc_value=6164720 +HeapAlloc dt=6 heapalloc_value=6172912 +HeapAlloc dt=6 heapalloc_value=6181104 +HeapAlloc dt=6 heapalloc_value=6189296 +HeapAlloc dt=6 heapalloc_value=6197488 +HeapAlloc dt=7 heapalloc_value=6205680 +HeapAlloc dt=6 heapalloc_value=6213872 +HeapAlloc dt=6 heapalloc_value=6222064 +HeapAlloc dt=6 heapalloc_value=6230256 +HeapAlloc dt=6 heapalloc_value=6238448 +HeapAlloc dt=7 heapalloc_value=6246640 +HeapAlloc dt=6 heapalloc_value=6254832 +HeapAlloc dt=6 heapalloc_value=6263024 +HeapAlloc dt=6 heapalloc_value=6271216 +HeapAlloc dt=6 heapalloc_value=6279408 +HeapAlloc dt=6 heapalloc_value=6287600 +HeapAlloc dt=7 heapalloc_value=6295792 +HeapAlloc dt=6 heapalloc_value=6303984 +HeapAlloc dt=7 heapalloc_value=6312176 +HeapAlloc dt=6 heapalloc_value=6320368 +HeapAlloc dt=6 heapalloc_value=6328560 +HeapAlloc dt=6 heapalloc_value=6336752 +HeapAlloc dt=70 heapalloc_value=6344944 +HeapAlloc dt=139 heapalloc_value=6353136 +HeapAlloc dt=8 heapalloc_value=6361328 +HeapAlloc dt=7 heapalloc_value=6369520 +HeapAlloc dt=6 heapalloc_value=6377712 +HeapAlloc dt=6 heapalloc_value=6385904 +HeapAlloc dt=6 heapalloc_value=6394096 +HeapAlloc dt=6 heapalloc_value=6402288 +HeapAlloc dt=7 heapalloc_value=6410480 +HeapAlloc dt=6 heapalloc_value=6418672 +HeapAlloc dt=6 heapalloc_value=6426864 +HeapAlloc dt=6 heapalloc_value=6435056 +HeapAlloc dt=6 heapalloc_value=6443248 +HeapAlloc dt=6 heapalloc_value=6451440 +HeapAlloc dt=7 heapalloc_value=6459632 +HeapAlloc dt=6 heapalloc_value=6467824 +HeapAlloc dt=6 heapalloc_value=6476016 +HeapAlloc dt=6 heapalloc_value=6484208 +HeapAlloc dt=42 heapalloc_value=6492400 +HeapAlloc dt=8 heapalloc_value=6500592 +HeapAlloc dt=6 heapalloc_value=6508784 +HeapAlloc dt=6 heapalloc_value=6516976 +HeapAlloc dt=7 heapalloc_value=6525168 +HeapAlloc dt=6 heapalloc_value=6533360 +HeapAlloc dt=6 heapalloc_value=6541552 +HeapAlloc dt=6 heapalloc_value=6549744 +HeapAlloc dt=6 heapalloc_value=6557936 +HeapAlloc dt=7 heapalloc_value=6566128 +HeapAlloc dt=6 heapalloc_value=6574320 +HeapAlloc dt=6 heapalloc_value=6582512 +HeapAlloc dt=7 heapalloc_value=6590704 +HeapAlloc dt=6 heapalloc_value=6598896 +HeapAlloc dt=66 heapalloc_value=6607088 +HeapAlloc dt=8 heapalloc_value=6615280 +HeapAlloc dt=6 heapalloc_value=6623472 +HeapAlloc dt=6 heapalloc_value=6631664 +HeapAlloc dt=7 heapalloc_value=6639856 +HeapAlloc dt=6 heapalloc_value=6648048 +HeapAlloc dt=6 heapalloc_value=6656240 +HeapAlloc dt=7 heapalloc_value=6664432 +HeapAlloc dt=6 heapalloc_value=6672624 +HeapAlloc dt=6 heapalloc_value=6680816 +HeapAlloc dt=6 heapalloc_value=6689008 +HeapAlloc dt=6 heapalloc_value=6697200 +HeapAlloc dt=7 heapalloc_value=6705392 +HeapAlloc dt=6 heapalloc_value=6713584 +HeapAlloc dt=6 heapalloc_value=6721776 +GoBlock dt=13 reason_string=19 stack=21 +ProcStop dt=220 +ProcStart dt=17605 p=1 p_seq=18 +ProcStop dt=18 +ProcStart dt=8830 p=4 p_seq=2 +ProcStop dt=26 +ProcStart dt=16773 p=0 p_seq=36 +ProcStop dt=12 +ProcStart dt=1445 p=1 p_seq=20 +ProcStop dt=12 +ProcStart dt=16751 p=1 p_seq=21 +GoUnblock dt=16 g=1 g_seq=33 stack=0 +GoStart dt=189 g=1 g_seq=34 +HeapAlloc dt=54 heapalloc_value=9892080 +HeapAlloc dt=21 heapalloc_value=9900272 +HeapAlloc dt=64 heapalloc_value=9908464 +HeapAlloc dt=13 heapalloc_value=9916656 +HeapAlloc dt=13 heapalloc_value=9924848 +HeapAlloc dt=12 heapalloc_value=9933040 +HeapAlloc dt=11 heapalloc_value=9941232 +HeapAlloc dt=13 heapalloc_value=9949424 +HeapAlloc dt=12 heapalloc_value=9957616 +HeapAlloc dt=48 heapalloc_value=9965808 +HeapAlloc dt=338 heapalloc_value=9974000 +HeapAlloc dt=16 heapalloc_value=9982192 +HeapAlloc dt=10 heapalloc_value=9990384 +HeapAlloc dt=8 heapalloc_value=9998576 +HeapAlloc dt=8 heapalloc_value=10006768 +HeapAlloc dt=10 heapalloc_value=10014960 +HeapAlloc dt=8 heapalloc_value=10023152 +HeapAlloc dt=7 heapalloc_value=10031344 +HeapAlloc dt=9 heapalloc_value=10039536 +HeapAlloc dt=6 heapalloc_value=10047728 +HeapAlloc dt=52 heapalloc_value=10055920 +HeapAlloc dt=8 heapalloc_value=10064112 +HeapAlloc dt=7 heapalloc_value=10072304 +HeapAlloc dt=7 heapalloc_value=10080496 +HeapAlloc dt=7 heapalloc_value=10088688 +HeapAlloc dt=7 heapalloc_value=10096880 +HeapAlloc dt=90 heapalloc_value=10105072 +HeapAlloc dt=8 heapalloc_value=10113264 +HeapAlloc dt=8 heapalloc_value=10121456 +HeapAlloc dt=7 heapalloc_value=10129648 +HeapAlloc dt=7 heapalloc_value=10137840 +HeapAlloc dt=7 heapalloc_value=10146032 +HeapAlloc dt=6 heapalloc_value=10154224 +HeapAlloc dt=7 heapalloc_value=10162416 +HeapAlloc dt=7 heapalloc_value=10170608 +HeapAlloc dt=7 heapalloc_value=10178800 +HeapAlloc dt=6 heapalloc_value=10186992 +HeapAlloc dt=7 heapalloc_value=10195184 +HeapAlloc dt=7 heapalloc_value=10203376 +HeapAlloc dt=7 heapalloc_value=10211568 +HeapAlloc dt=6 heapalloc_value=10219760 +HeapAlloc dt=8 heapalloc_value=10227952 +HeapAlloc dt=97 heapalloc_value=10236144 +HeapAlloc dt=9 heapalloc_value=10244336 +HeapAlloc dt=6 heapalloc_value=10252528 +HeapAlloc dt=7 heapalloc_value=10260720 +HeapAlloc dt=7 heapalloc_value=10268912 +HeapAlloc dt=6 heapalloc_value=10277104 +HeapAlloc dt=7 heapalloc_value=10285296 +HeapAlloc dt=7 heapalloc_value=10293488 +HeapAlloc dt=73 heapalloc_value=10301680 +HeapAlloc dt=8 heapalloc_value=10309872 +HeapAlloc dt=6 heapalloc_value=10318064 +HeapAlloc dt=7 heapalloc_value=10326256 +HeapAlloc dt=7 heapalloc_value=10334448 +HeapAlloc dt=6 heapalloc_value=10342640 +HeapAlloc dt=7 heapalloc_value=10350832 +HeapAlloc dt=7 heapalloc_value=10359024 +HeapAlloc dt=7 heapalloc_value=10367216 +HeapAlloc dt=6 heapalloc_value=10375408 +HeapAlloc dt=7 heapalloc_value=10383600 +HeapAlloc dt=7 heapalloc_value=10391792 +HeapAlloc dt=7 heapalloc_value=10399984 +HeapAlloc dt=6 heapalloc_value=10408176 +HeapAlloc dt=7 heapalloc_value=10416368 +HeapAlloc dt=7 heapalloc_value=10424560 +HeapAlloc dt=6 heapalloc_value=10432752 +HeapAlloc dt=7 heapalloc_value=10440944 +HeapAlloc dt=7 heapalloc_value=10449136 +HeapAlloc dt=6 heapalloc_value=10457328 +HeapAlloc dt=7 heapalloc_value=10465520 +HeapAlloc dt=96 heapalloc_value=10473712 +HeapAlloc dt=8 heapalloc_value=10481904 +HeapAlloc dt=6 heapalloc_value=10490096 +HeapAlloc dt=68 heapalloc_value=10498288 +HeapAlloc dt=8 heapalloc_value=10506480 +HeapAlloc dt=7 heapalloc_value=10514672 +HeapAlloc dt=7 heapalloc_value=10522864 +HeapAlloc dt=6 heapalloc_value=10531056 +HeapAlloc dt=7 heapalloc_value=10539248 +HeapAlloc dt=7 heapalloc_value=10547440 +HeapAlloc dt=7 heapalloc_value=10555632 +HeapAlloc dt=6 heapalloc_value=10563824 +HeapAlloc dt=7 heapalloc_value=10572016 +HeapAlloc dt=7 heapalloc_value=10580208 +HeapAlloc dt=6 heapalloc_value=10588400 +HeapAlloc dt=7 heapalloc_value=10596592 +HeapAlloc dt=7 heapalloc_value=10604784 +HeapAlloc dt=7 heapalloc_value=10612976 +HeapAlloc dt=7 heapalloc_value=10621168 +HeapAlloc dt=6 heapalloc_value=10629360 +HeapAlloc dt=7 heapalloc_value=10637552 +HeapAlloc dt=7 heapalloc_value=10645744 +HeapAlloc dt=6 heapalloc_value=10653936 +HeapAlloc dt=7 heapalloc_value=10662128 +HeapAlloc dt=7 heapalloc_value=10670320 +HeapAlloc dt=6 heapalloc_value=10678512 +HeapAlloc dt=7 heapalloc_value=10686704 +HeapAlloc dt=7 heapalloc_value=10694896 +HeapAlloc dt=7 heapalloc_value=10703088 +HeapAlloc dt=7 heapalloc_value=10711280 +HeapAlloc dt=6 heapalloc_value=10719472 +HeapAlloc dt=7 heapalloc_value=10727664 +HeapAlloc dt=7 heapalloc_value=10735856 +HeapAlloc dt=7 heapalloc_value=10744048 +HeapAlloc dt=6 heapalloc_value=10752240 +HeapAlloc dt=78 heapalloc_value=10760432 +HeapAlloc dt=8 heapalloc_value=10768624 +HeapAlloc dt=6 heapalloc_value=10776816 +HeapAlloc dt=7 heapalloc_value=10785008 +HeapAlloc dt=7 heapalloc_value=10793200 +HeapAlloc dt=7 heapalloc_value=10801392 +HeapAlloc dt=6 heapalloc_value=10809584 +HeapAlloc dt=7 heapalloc_value=10817776 +HeapAlloc dt=65 heapalloc_value=10825968 +HeapAlloc dt=9 heapalloc_value=10834160 +HeapAlloc dt=6 heapalloc_value=10842352 +HeapAlloc dt=7 heapalloc_value=10850544 +HeapAlloc dt=6 heapalloc_value=10858736 +HeapAlloc dt=7 heapalloc_value=10866928 +HeapAlloc dt=7 heapalloc_value=10875120 +HeapAlloc dt=7 heapalloc_value=10883312 +HeapAlloc dt=6 heapalloc_value=10891504 +HeapAlloc dt=44 heapalloc_value=10899696 +HeapAlloc dt=7 heapalloc_value=10907888 +GoBlock dt=13 reason_string=19 stack=21 +ProcStop dt=198 +ProcStart dt=17586 p=0 p_seq=38 +ProcStop dt=21 +ProcStart dt=5052 p=1 p_seq=24 +ProcStop dt=13 +ProcStart dt=16760 p=1 p_seq=26 +GoUnblock dt=19 g=1 g_seq=39 stack=0 +GoStart dt=169 g=1 g_seq=40 +HeapAlloc dt=52 heapalloc_value=13250800 +HeapAlloc dt=19 heapalloc_value=13258992 +HeapAlloc dt=9 heapalloc_value=13267184 +HeapAlloc dt=82 heapalloc_value=13275376 +HeapAlloc dt=12 heapalloc_value=13283568 +HeapAlloc dt=9 heapalloc_value=13291760 +HeapAlloc dt=9 heapalloc_value=13299952 +HeapAlloc dt=10 heapalloc_value=13308144 +HeapAlloc dt=10 heapalloc_value=13316336 +HeapAlloc dt=7 heapalloc_value=13324528 +HeapAlloc dt=6 heapalloc_value=13332720 +HeapAlloc dt=6 heapalloc_value=13340912 +HeapAlloc dt=6 heapalloc_value=13349104 +HeapAlloc dt=7 heapalloc_value=13357296 +HeapAlloc dt=6 heapalloc_value=13365488 +HeapAlloc dt=6 heapalloc_value=13373680 +HeapAlloc dt=520 heapalloc_value=13381872 +HeapAlloc dt=15 heapalloc_value=13390064 +HeapAlloc dt=7 heapalloc_value=13398256 +HeapAlloc dt=6 heapalloc_value=13406448 +HeapAlloc dt=8 heapalloc_value=13414640 +HeapAlloc dt=6 heapalloc_value=13422832 +HeapAlloc dt=6 heapalloc_value=13431024 +HeapAlloc dt=7 heapalloc_value=13439216 +HeapAlloc dt=8 heapalloc_value=13447408 +HeapAlloc dt=7 heapalloc_value=13455600 +HeapAlloc dt=6 heapalloc_value=13463792 +HeapAlloc dt=6 heapalloc_value=13471984 +HeapAlloc dt=48 heapalloc_value=13480176 +HeapAlloc dt=7 heapalloc_value=13488368 +HeapAlloc dt=6 heapalloc_value=13496560 +HeapAlloc dt=7 heapalloc_value=13504752 +HeapAlloc dt=9 heapalloc_value=13512944 +HeapAlloc dt=6 heapalloc_value=13521136 +HeapAlloc dt=7 heapalloc_value=13529328 +HeapAlloc dt=6 heapalloc_value=13537520 +HeapAlloc dt=7 heapalloc_value=13545712 +HeapAlloc dt=6 heapalloc_value=13553904 +HeapAlloc dt=7 heapalloc_value=13562096 +HeapAlloc dt=6 heapalloc_value=13570288 +HeapAlloc dt=8 heapalloc_value=13578480 +HeapAlloc dt=6 heapalloc_value=13586672 +HeapAlloc dt=6 heapalloc_value=13594864 +HeapAlloc dt=6 heapalloc_value=13603056 +HeapAlloc dt=6 heapalloc_value=13611248 +HeapAlloc dt=7 heapalloc_value=13619440 +HeapAlloc dt=6 heapalloc_value=13627632 +HeapAlloc dt=6 heapalloc_value=13635824 +HeapAlloc dt=76 heapalloc_value=13644016 +HeapAlloc dt=8 heapalloc_value=13652208 +HeapAlloc dt=6 heapalloc_value=13660400 +HeapAlloc dt=6 heapalloc_value=13668592 +HeapAlloc dt=6 heapalloc_value=13676784 +HeapAlloc dt=7 heapalloc_value=13684976 +HeapAlloc dt=6 heapalloc_value=13693168 +HeapAlloc dt=6 heapalloc_value=13701360 +HeapAlloc dt=8 heapalloc_value=13709552 +HeapAlloc dt=6 heapalloc_value=13717744 +HeapAlloc dt=64 heapalloc_value=13725936 +HeapAlloc dt=7 heapalloc_value=13734128 +HeapAlloc dt=7 heapalloc_value=13742320 +HeapAlloc dt=6 heapalloc_value=13750512 +HeapAlloc dt=6 heapalloc_value=13758704 +HeapAlloc dt=6 heapalloc_value=13766896 +HeapAlloc dt=8 heapalloc_value=13775088 +HeapAlloc dt=7 heapalloc_value=13783280 +HeapAlloc dt=6 heapalloc_value=13791472 +HeapAlloc dt=7 heapalloc_value=13799664 +HeapAlloc dt=6 heapalloc_value=13807856 +HeapAlloc dt=6 heapalloc_value=13816048 +HeapAlloc dt=6 heapalloc_value=13824240 +HeapAlloc dt=6 heapalloc_value=13832432 +HeapAlloc dt=9 heapalloc_value=13840624 +HeapAlloc dt=6 heapalloc_value=13848816 +HeapAlloc dt=6 heapalloc_value=13857008 +HeapAlloc dt=6 heapalloc_value=13865200 +HeapAlloc dt=7 heapalloc_value=13873392 +HeapAlloc dt=7 heapalloc_value=13881584 +HeapAlloc dt=6 heapalloc_value=13889776 +HeapAlloc dt=45 heapalloc_value=13897968 +HeapAlloc dt=75 heapalloc_value=13906160 +HeapAlloc dt=8 heapalloc_value=13914352 +HeapAlloc dt=6 heapalloc_value=13922544 +HeapAlloc dt=6 heapalloc_value=13930736 +HeapAlloc dt=7 heapalloc_value=13938928 +HeapAlloc dt=6 heapalloc_value=13947120 +HeapAlloc dt=6 heapalloc_value=13955312 +HeapAlloc dt=6 heapalloc_value=13963504 +HeapAlloc dt=6 heapalloc_value=13971696 +HeapAlloc dt=7 heapalloc_value=13979888 +HeapAlloc dt=6 heapalloc_value=13988080 +HeapAlloc dt=6 heapalloc_value=13996272 +HeapAlloc dt=6 heapalloc_value=14004464 +HeapAlloc dt=6 heapalloc_value=14012656 +HeapAlloc dt=6 heapalloc_value=14020848 +HeapAlloc dt=7 heapalloc_value=14029040 +HeapAlloc dt=6 heapalloc_value=14037232 +HeapAlloc dt=6 heapalloc_value=14045424 +HeapAlloc dt=7 heapalloc_value=14053616 +HeapAlloc dt=6 heapalloc_value=14061808 +HeapAlloc dt=6 heapalloc_value=14070000 +HeapAlloc dt=6 heapalloc_value=14078192 +HeapAlloc dt=6 heapalloc_value=14086384 +HeapAlloc dt=6 heapalloc_value=14094576 +HeapAlloc dt=9 heapalloc_value=14102768 +HeapAlloc dt=6 heapalloc_value=14110960 +HeapAlloc dt=7 heapalloc_value=14119152 +HeapAlloc dt=6 heapalloc_value=14127344 +HeapAlloc dt=7 heapalloc_value=14135536 +HeapAlloc dt=6 heapalloc_value=14143728 +HeapAlloc dt=6 heapalloc_value=14151920 +HeapAlloc dt=6 heapalloc_value=14160112 +HeapAlloc dt=69 heapalloc_value=14168304 +HeapAlloc dt=8 heapalloc_value=14176496 +HeapAlloc dt=6 heapalloc_value=14184688 +HeapAlloc dt=6 heapalloc_value=14192880 +HeapAlloc dt=7 heapalloc_value=14201072 +HeapAlloc dt=6 heapalloc_value=14209264 +HeapAlloc dt=6 heapalloc_value=14217456 +HeapAlloc dt=16 heapalloc_value=14586096 +HeapAlloc dt=3676 heapalloc_value=14594288 +HeapAlloc dt=11 heapalloc_value=14602480 +HeapAlloc dt=72 heapalloc_value=14610672 +HeapAlloc dt=10 heapalloc_value=14618864 +HeapAlloc dt=7 heapalloc_value=14627056 +HeapAlloc dt=9 heapalloc_value=14635248 +GoBlock dt=13 reason_string=19 stack=21 +ProcStop dt=219 +ProcStart dt=17778 p=2 p_seq=19 +ProcStop dt=25 +ProcStart dt=2221 p=1 p_seq=29 +ProcStop dt=18 +ProcStart dt=16821 p=1 p_seq=30 +GoUnblock dt=23 g=1 g_seq=43 stack=0 +GoStart dt=193 g=1 g_seq=44 +HeapAlloc dt=59 heapalloc_value=15667440 +HeapAlloc dt=26 heapalloc_value=15675632 +HeapAlloc dt=15 heapalloc_value=15683824 +HeapAlloc dt=10 heapalloc_value=15692016 +HeapAlloc dt=9 heapalloc_value=15700208 +HeapAlloc dt=10 heapalloc_value=15708400 +HeapAlloc dt=11 heapalloc_value=15716592 +HeapAlloc dt=9 heapalloc_value=15724784 +HeapAlloc dt=96 heapalloc_value=15732976 +HeapAlloc dt=324 heapalloc_value=15741168 +HeapAlloc dt=17 heapalloc_value=15749360 +HeapAlloc dt=9 heapalloc_value=15757552 +HeapAlloc dt=9 heapalloc_value=15765744 +HeapAlloc dt=7 heapalloc_value=15773936 +HeapAlloc dt=8 heapalloc_value=15782128 +HeapAlloc dt=6 heapalloc_value=15790320 +HeapAlloc dt=6 heapalloc_value=15798512 +HeapAlloc dt=8 heapalloc_value=15806704 +HeapAlloc dt=5 heapalloc_value=15814896 +HeapAlloc dt=7 heapalloc_value=15823088 +HeapAlloc dt=6 heapalloc_value=15831280 +HeapAlloc dt=6 heapalloc_value=15839472 +HeapAlloc dt=6 heapalloc_value=15847664 +HeapAlloc dt=6 heapalloc_value=15855856 +HeapAlloc dt=7 heapalloc_value=15864048 +HeapAlloc dt=10 heapalloc_value=15872240 +HeapAlloc dt=6 heapalloc_value=15880432 +HeapAlloc dt=6 heapalloc_value=15888624 +HeapAlloc dt=6 heapalloc_value=15896816 +HeapAlloc dt=7 heapalloc_value=15905008 +HeapAlloc dt=6 heapalloc_value=15913200 +HeapAlloc dt=6 heapalloc_value=15921392 +HeapAlloc dt=7 heapalloc_value=15929584 +HeapAlloc dt=8 heapalloc_value=15937776 +HeapAlloc dt=48 heapalloc_value=15945968 +HeapAlloc dt=7 heapalloc_value=15954160 +HeapAlloc dt=7 heapalloc_value=15962352 +HeapAlloc dt=6 heapalloc_value=15970544 +HeapAlloc dt=8 heapalloc_value=15978736 +HeapAlloc dt=6 heapalloc_value=15986928 +HeapAlloc dt=7 heapalloc_value=15995120 +HeapAlloc dt=104 heapalloc_value=16003312 +HeapAlloc dt=9 heapalloc_value=16011504 +HeapAlloc dt=8 heapalloc_value=16019696 +HeapAlloc dt=9 heapalloc_value=16027888 +HeapAlloc dt=8 heapalloc_value=16036080 +HeapAlloc dt=7 heapalloc_value=16044272 +HeapAlloc dt=6 heapalloc_value=16052464 +HeapAlloc dt=7 heapalloc_value=16060656 +HeapAlloc dt=6 heapalloc_value=16068848 +HeapAlloc dt=6 heapalloc_value=16077040 +HeapAlloc dt=6 heapalloc_value=16085232 +HeapAlloc dt=7 heapalloc_value=16093424 +HeapAlloc dt=6 heapalloc_value=16101616 +HeapAlloc dt=6 heapalloc_value=16109808 +HeapAlloc dt=6 heapalloc_value=16118000 +HeapAlloc dt=7 heapalloc_value=16126192 +HeapAlloc dt=6 heapalloc_value=16134384 +HeapAlloc dt=6 heapalloc_value=16142576 +HeapAlloc dt=6 heapalloc_value=16150768 +HeapAlloc dt=7 heapalloc_value=16158960 +HeapAlloc dt=6 heapalloc_value=16167152 +HeapAlloc dt=6 heapalloc_value=16175344 +HeapAlloc dt=78 heapalloc_value=16183536 +HeapAlloc dt=7 heapalloc_value=16191728 +HeapAlloc dt=6 heapalloc_value=16199920 +HeapAlloc dt=6 heapalloc_value=16208112 +HeapAlloc dt=7 heapalloc_value=16216304 +HeapAlloc dt=6 heapalloc_value=16224496 +HeapAlloc dt=6 heapalloc_value=16232688 +HeapAlloc dt=6 heapalloc_value=16240880 +HeapAlloc dt=6 heapalloc_value=16249072 +HeapAlloc dt=7 heapalloc_value=16257264 +HeapAlloc dt=73 heapalloc_value=16265456 +HeapAlloc dt=8 heapalloc_value=16273648 +HeapAlloc dt=6 heapalloc_value=16281840 +HeapAlloc dt=6 heapalloc_value=16290032 +HeapAlloc dt=6 heapalloc_value=16298224 +HeapAlloc dt=7 heapalloc_value=16306416 +HeapAlloc dt=6 heapalloc_value=16314608 +HeapAlloc dt=6 heapalloc_value=16322800 +HeapAlloc dt=6 heapalloc_value=16330992 +HeapAlloc dt=7 heapalloc_value=16339184 +HeapAlloc dt=6 heapalloc_value=16347376 +HeapAlloc dt=8 heapalloc_value=16355568 +HeapAlloc dt=44 heapalloc_value=16363760 +HeapAlloc dt=7 heapalloc_value=16371952 +HeapAlloc dt=6 heapalloc_value=16380144 +HeapAlloc dt=6 heapalloc_value=16388336 +HeapAlloc dt=6 heapalloc_value=16396528 +HeapAlloc dt=7 heapalloc_value=16404720 +HeapAlloc dt=6 heapalloc_value=16412912 +HeapAlloc dt=6 heapalloc_value=16421104 +HeapAlloc dt=6 heapalloc_value=16429296 +HeapAlloc dt=7 heapalloc_value=16437488 +HeapAlloc dt=6 heapalloc_value=16445680 +HeapAlloc dt=6 heapalloc_value=16453872 +HeapAlloc dt=6 heapalloc_value=16462064 +HeapAlloc dt=6 heapalloc_value=16470256 +HeapAlloc dt=6 heapalloc_value=16478448 +HeapAlloc dt=7 heapalloc_value=16486640 +HeapAlloc dt=6 heapalloc_value=16494832 +GCBegin dt=18 gc_seq=5 stack=41 +STWBegin dt=46 kind_string=22 stack=42 +GoUnblock dt=209 g=4 g_seq=7 stack=43 +ProcsChange dt=70 procs_value=8 stack=44 +STWEnd dt=24 +GCMarkAssistBegin dt=182 stack=30 +GCMarkAssistEnd dt=3877 +HeapAlloc dt=628 heapalloc_value=16509392 +HeapAlloc dt=22 heapalloc_value=16517584 +HeapAlloc dt=18 heapalloc_value=16525776 +HeapAlloc dt=371 heapalloc_value=16533968 +HeapAlloc dt=14 heapalloc_value=16542160 +HeapAlloc dt=11 heapalloc_value=16550352 +HeapAlloc dt=13 heapalloc_value=16558544 +HeapAlloc dt=13 heapalloc_value=16566736 +HeapAlloc dt=10 heapalloc_value=16574928 +HeapAlloc dt=10 heapalloc_value=16583120 +HeapAlloc dt=8 heapalloc_value=16591312 +HeapAlloc dt=8 heapalloc_value=16599504 +HeapAlloc dt=8 heapalloc_value=16607696 +HeapAlloc dt=7 heapalloc_value=16615888 +HeapAlloc dt=8 heapalloc_value=16624080 +HeapAlloc dt=8 heapalloc_value=16632272 +HeapAlloc dt=9 heapalloc_value=16640464 +HeapAlloc dt=7 heapalloc_value=16648656 +HeapAlloc dt=8 heapalloc_value=16656848 +HeapAlloc dt=9 heapalloc_value=16665040 +HeapAlloc dt=8 heapalloc_value=16673232 +HeapAlloc dt=9 heapalloc_value=16681424 +HeapAlloc dt=8 heapalloc_value=16689616 +GoBlock dt=17 reason_string=19 stack=21 +ProcStop dt=2869 +ProcStart dt=110180 p=4 p_seq=5 +GoStart dt=268 g=15 g_seq=1 +GoStop dt=304685 reason_string=16 stack=52 +GoStart dt=20 g=15 g_seq=2 +GoStop dt=316415 reason_string=16 stack=52 +GoStart dt=23 g=15 g_seq=3 +GoDestroy dt=160136 +ProcStop dt=32 +EventBatch gen=1 m=2852344 time=420901833895 size=3430 +ProcStart dt=383 p=2 p_seq=3 +GoStart dt=284 g=7 g_seq=1 +HeapAlloc dt=35 heapalloc_value=4055040 +GoBlock dt=148 reason_string=15 stack=26 +ProcStop dt=12 +ProcStart dt=791 p=1 p_seq=8 +ProcStop dt=4 +ProcStart dt=817 p=1 p_seq=9 +ProcStop dt=14 +ProcStart dt=796 p=0 p_seq=21 +ProcStop dt=9 +ProcStart dt=393 p=1 p_seq=11 +ProcStop dt=19 +ProcStart dt=324 p=2 p_seq=9 +GoStart dt=339 g=25 g_seq=1 +GoBlock dt=112 reason_string=15 stack=26 +ProcStop dt=4 +ProcStart dt=1331 p=1 p_seq=15 +GoUnblock dt=13 g=9 g_seq=2 stack=0 +GoStart dt=145 g=9 g_seq=3 +GoLabel dt=1 label_string=2 +STWBegin dt=4838 kind_string=23 stack=34 +GoUnblock dt=44 g=1 g_seq=18 stack=35 +HeapAlloc dt=17 heapalloc_value=4112624 +GoStatus dt=15 g=3 m=18446744073709551615 gstatus=4 +GoUnblock dt=5 g=3 g_seq=1 stack=36 +GCEnd dt=4 gc_seq=2 +HeapGoal dt=5 heapgoal_value=8644048 +ProcsChange dt=37 procs_value=8 stack=37 +STWEnd dt=1475 +GoBlock dt=2304 reason_string=15 stack=26 +GoStart dt=12 g=3 g_seq=2 +GoBlock dt=2449 reason_string=14 stack=40 +ProcStop dt=16 +ProcStart dt=67967 p=1 p_seq=19 +GoUnblock dt=21 g=9 g_seq=4 stack=0 +GoStart dt=191 g=9 g_seq=5 +GoLabel dt=1 label_string=2 +GoStop dt=4205 reason_string=16 stack=45 +GoStart dt=189 g=9 g_seq=6 +STWBegin dt=1152 kind_string=23 stack=34 +GoUnblock dt=46 g=1 g_seq=29 stack=35 +HeapAlloc dt=17 heapalloc_value=8626416 +GoUnblock dt=11 g=3 g_seq=3 stack=36 +GCEnd dt=5 gc_seq=4 +HeapGoal dt=5 heapgoal_value=17671632 +ProcsChange dt=43 procs_value=8 stack=37 +STWEnd dt=28 +GoBlock dt=1941 reason_string=15 stack=26 +GoStart dt=12 g=3 g_seq=4 +GoBlock dt=4694 reason_string=14 stack=40 +GoUnblock dt=33 g=1 g_seq=31 stack=0 +GoStart dt=214 g=1 g_seq=32 +HeapAlloc dt=62 heapalloc_value=8646896 +HeapAlloc dt=32 heapalloc_value=8655088 +HeapAlloc dt=18 heapalloc_value=8663280 +HeapAlloc dt=18 heapalloc_value=8671472 +HeapAlloc dt=15 heapalloc_value=8679664 +HeapAlloc dt=18 heapalloc_value=8687856 +HeapAlloc dt=17 heapalloc_value=8696048 +HeapAlloc dt=17 heapalloc_value=8704240 +HeapAlloc dt=19 heapalloc_value=8712432 +HeapAlloc dt=24 heapalloc_value=8720624 +HeapAlloc dt=20 heapalloc_value=8728816 +HeapAlloc dt=31 heapalloc_value=8737008 +HeapAlloc dt=19 heapalloc_value=8745200 +HeapAlloc dt=14 heapalloc_value=8753392 +HeapAlloc dt=14 heapalloc_value=8761584 +HeapAlloc dt=15 heapalloc_value=8769776 +HeapAlloc dt=17 heapalloc_value=8777968 +HeapAlloc dt=16 heapalloc_value=8786160 +HeapAlloc dt=16 heapalloc_value=8794352 +HeapAlloc dt=13 heapalloc_value=8802544 +HeapAlloc dt=14 heapalloc_value=8810736 +HeapAlloc dt=12 heapalloc_value=8818928 +HeapAlloc dt=38 heapalloc_value=9040112 +HeapAlloc dt=3065 heapalloc_value=9048304 +HeapAlloc dt=21 heapalloc_value=9056496 +HeapAlloc dt=16 heapalloc_value=9064688 +HeapAlloc dt=22 heapalloc_value=9072880 +HeapAlloc dt=37 heapalloc_value=9081072 +HeapAlloc dt=28 heapalloc_value=9089264 +HeapAlloc dt=30 heapalloc_value=9097456 +HeapAlloc dt=22 heapalloc_value=9105648 +HeapAlloc dt=36 heapalloc_value=9113840 +HeapAlloc dt=30 heapalloc_value=9122032 +HeapAlloc dt=28 heapalloc_value=9130224 +HeapAlloc dt=26 heapalloc_value=9138416 +HeapAlloc dt=27 heapalloc_value=9146608 +HeapAlloc dt=31 heapalloc_value=9154800 +HeapAlloc dt=37 heapalloc_value=9162992 +HeapAlloc dt=24 heapalloc_value=9171184 +HeapAlloc dt=27 heapalloc_value=9179376 +HeapAlloc dt=26 heapalloc_value=9187568 +HeapAlloc dt=34 heapalloc_value=9195760 +HeapAlloc dt=30 heapalloc_value=9203952 +HeapAlloc dt=30 heapalloc_value=9212144 +HeapAlloc dt=30 heapalloc_value=9220336 +HeapAlloc dt=29 heapalloc_value=9228528 +HeapAlloc dt=28 heapalloc_value=9236720 +HeapAlloc dt=46 heapalloc_value=9244912 +HeapAlloc dt=118 heapalloc_value=9253104 +HeapAlloc dt=31 heapalloc_value=9261296 +HeapAlloc dt=39 heapalloc_value=9269488 +HeapAlloc dt=27 heapalloc_value=9277680 +HeapAlloc dt=32 heapalloc_value=9285872 +HeapAlloc dt=27 heapalloc_value=9294064 +HeapAlloc dt=32 heapalloc_value=9302256 +HeapAlloc dt=33 heapalloc_value=9310448 +HeapAlloc dt=39 heapalloc_value=9318640 +HeapAlloc dt=30 heapalloc_value=9326832 +HeapAlloc dt=33 heapalloc_value=9335024 +HeapAlloc dt=28 heapalloc_value=9343216 +HeapAlloc dt=27 heapalloc_value=9351408 +HeapAlloc dt=27 heapalloc_value=9359600 +HeapAlloc dt=26 heapalloc_value=9367792 +HeapAlloc dt=36 heapalloc_value=9375984 +HeapAlloc dt=20 heapalloc_value=9384176 +HeapAlloc dt=16 heapalloc_value=9392368 +HeapAlloc dt=17 heapalloc_value=9400560 +HeapAlloc dt=22 heapalloc_value=9408752 +HeapAlloc dt=7 heapalloc_value=9416944 +HeapAlloc dt=49 heapalloc_value=9425136 +HeapAlloc dt=7 heapalloc_value=9433328 +HeapAlloc dt=7 heapalloc_value=9441520 +HeapAlloc dt=74 heapalloc_value=9449712 +HeapAlloc dt=8 heapalloc_value=9457904 +HeapAlloc dt=6 heapalloc_value=9466096 +HeapAlloc dt=7 heapalloc_value=9474288 +HeapAlloc dt=6 heapalloc_value=9482480 +HeapAlloc dt=6 heapalloc_value=9490672 +HeapAlloc dt=7 heapalloc_value=9498864 +HeapAlloc dt=6 heapalloc_value=9507056 +HeapAlloc dt=6 heapalloc_value=9515248 +HeapAlloc dt=6 heapalloc_value=9523440 +HeapAlloc dt=6 heapalloc_value=9531632 +HeapAlloc dt=6 heapalloc_value=9539824 +HeapAlloc dt=7 heapalloc_value=9548016 +HeapAlloc dt=7 heapalloc_value=9556208 +HeapAlloc dt=5 heapalloc_value=9564400 +HeapAlloc dt=7 heapalloc_value=9572592 +HeapAlloc dt=6 heapalloc_value=9580784 +HeapAlloc dt=6 heapalloc_value=9588976 +HeapAlloc dt=6 heapalloc_value=9597168 +HeapAlloc dt=6 heapalloc_value=9605360 +HeapAlloc dt=6 heapalloc_value=9613552 +HeapAlloc dt=7 heapalloc_value=9621744 +HeapAlloc dt=6 heapalloc_value=9629936 +HeapAlloc dt=43 heapalloc_value=9638128 +HeapAlloc dt=7 heapalloc_value=9646320 +HeapAlloc dt=7 heapalloc_value=9654512 +HeapAlloc dt=6 heapalloc_value=9662704 +HeapAlloc dt=6 heapalloc_value=9670896 +HeapAlloc dt=6 heapalloc_value=9679088 +HeapAlloc dt=10 heapalloc_value=9687280 +HeapAlloc dt=7 heapalloc_value=9695472 +HeapAlloc dt=8 heapalloc_value=9703664 +HeapAlloc dt=726 heapalloc_value=9711856 +HeapAlloc dt=16 heapalloc_value=9720048 +HeapAlloc dt=7 heapalloc_value=9728240 +HeapAlloc dt=6 heapalloc_value=9736432 +HeapAlloc dt=6 heapalloc_value=9744624 +HeapAlloc dt=6 heapalloc_value=9752816 +HeapAlloc dt=7 heapalloc_value=9761008 +HeapAlloc dt=6 heapalloc_value=9769200 +HeapAlloc dt=63 heapalloc_value=9777392 +HeapAlloc dt=8 heapalloc_value=9785584 +HeapAlloc dt=6 heapalloc_value=9793776 +HeapAlloc dt=7 heapalloc_value=9801968 +HeapAlloc dt=7 heapalloc_value=9810160 +HeapAlloc dt=6 heapalloc_value=9818352 +HeapAlloc dt=6 heapalloc_value=9826544 +HeapAlloc dt=7 heapalloc_value=9834736 +HeapAlloc dt=43 heapalloc_value=9842928 +HeapAlloc dt=7 heapalloc_value=9851120 +HeapAlloc dt=7 heapalloc_value=9859312 +HeapAlloc dt=6 heapalloc_value=9867504 +HeapAlloc dt=6 heapalloc_value=9875696 +HeapAlloc dt=6 heapalloc_value=9883888 +GoBlock dt=13 reason_string=19 stack=21 +ProcStop dt=225 +ProcStart dt=17576 p=0 p_seq=37 +ProcStop dt=18 +ProcStart dt=2169 p=1 p_seq=22 +ProcStop dt=14 +ProcStart dt=16799 p=1 p_seq=23 +GoUnblock dt=15 g=1 g_seq=35 stack=0 +GoStart dt=168 g=1 g_seq=36 +HeapAlloc dt=44 heapalloc_value=10916080 +HeapAlloc dt=18 heapalloc_value=10924272 +HeapAlloc dt=13 heapalloc_value=10932464 +HeapAlloc dt=12 heapalloc_value=10940656 +HeapAlloc dt=11 heapalloc_value=10948848 +HeapAlloc dt=12 heapalloc_value=10957040 +HeapAlloc dt=9 heapalloc_value=10965232 +HeapAlloc dt=11 heapalloc_value=10973424 +HeapAlloc dt=9 heapalloc_value=10981616 +HeapAlloc dt=9 heapalloc_value=10989808 +HeapAlloc dt=6 heapalloc_value=10998000 +HeapAlloc dt=6 heapalloc_value=11006192 +HeapAlloc dt=7 heapalloc_value=11014384 +HeapAlloc dt=303 heapalloc_value=11022576 +HeapAlloc dt=15 heapalloc_value=11030768 +HeapAlloc dt=8 heapalloc_value=11038960 +HeapAlloc dt=6 heapalloc_value=11047152 +HeapAlloc dt=7 heapalloc_value=11055344 +HeapAlloc dt=6 heapalloc_value=11063536 +HeapAlloc dt=6 heapalloc_value=11071728 +HeapAlloc dt=6 heapalloc_value=11079920 +HeapAlloc dt=9 heapalloc_value=11088112 +HeapAlloc dt=6 heapalloc_value=11096304 +HeapAlloc dt=52 heapalloc_value=11104496 +HeapAlloc dt=8 heapalloc_value=11112688 +HeapAlloc dt=7 heapalloc_value=11120880 +HeapAlloc dt=6 heapalloc_value=11129072 +HeapAlloc dt=7 heapalloc_value=11137264 +HeapAlloc dt=396 heapalloc_value=11423984 +HeapAlloc dt=2772 heapalloc_value=11432176 +HeapAlloc dt=23 heapalloc_value=11440368 +HeapAlloc dt=13 heapalloc_value=11448560 +HeapAlloc dt=10 heapalloc_value=11456752 +HeapAlloc dt=9 heapalloc_value=11464944 +HeapAlloc dt=9 heapalloc_value=11473136 +HeapAlloc dt=9 heapalloc_value=11481328 +HeapAlloc dt=9 heapalloc_value=11489520 +HeapAlloc dt=9 heapalloc_value=11497712 +HeapAlloc dt=12 heapalloc_value=11505904 +HeapAlloc dt=9 heapalloc_value=11514096 +HeapAlloc dt=10 heapalloc_value=11522288 +HeapAlloc dt=9 heapalloc_value=11530480 +HeapAlloc dt=10 heapalloc_value=11538672 +HeapAlloc dt=10 heapalloc_value=11546864 +HeapAlloc dt=10 heapalloc_value=11555056 +HeapAlloc dt=9 heapalloc_value=11563248 +HeapAlloc dt=21 heapalloc_value=11571440 +HeapAlloc dt=9 heapalloc_value=11579632 +HeapAlloc dt=6 heapalloc_value=11587824 +HeapAlloc dt=7 heapalloc_value=11596016 +HeapAlloc dt=6 heapalloc_value=11604208 +HeapAlloc dt=6 heapalloc_value=11612400 +HeapAlloc dt=6 heapalloc_value=11620592 +HeapAlloc dt=103 heapalloc_value=11628784 +HeapAlloc dt=9 heapalloc_value=11636976 +HeapAlloc dt=7 heapalloc_value=11645168 +HeapAlloc dt=6 heapalloc_value=11653360 +HeapAlloc dt=7 heapalloc_value=11661552 +HeapAlloc dt=6 heapalloc_value=11669744 +HeapAlloc dt=6 heapalloc_value=11677936 +HeapAlloc dt=6 heapalloc_value=11686128 +HeapAlloc dt=6 heapalloc_value=11694320 +HeapAlloc dt=7 heapalloc_value=11702512 +HeapAlloc dt=6 heapalloc_value=11710704 +HeapAlloc dt=6 heapalloc_value=11718896 +HeapAlloc dt=6 heapalloc_value=11727088 +HeapAlloc dt=6 heapalloc_value=11735280 +HeapAlloc dt=6 heapalloc_value=11743472 +HeapAlloc dt=6 heapalloc_value=11751664 +HeapAlloc dt=6 heapalloc_value=11759856 +HeapAlloc dt=7 heapalloc_value=11768048 +HeapAlloc dt=5 heapalloc_value=11776240 +HeapAlloc dt=7 heapalloc_value=11784432 +HeapAlloc dt=6 heapalloc_value=11792624 +HeapAlloc dt=44 heapalloc_value=11800816 +HeapAlloc dt=82 heapalloc_value=11809008 +HeapAlloc dt=9 heapalloc_value=11817200 +HeapAlloc dt=6 heapalloc_value=11825392 +HeapAlloc dt=6 heapalloc_value=11833584 +HeapAlloc dt=7 heapalloc_value=11841776 +HeapAlloc dt=6 heapalloc_value=11849968 +HeapAlloc dt=6 heapalloc_value=11858160 +HeapAlloc dt=6 heapalloc_value=11866352 +HeapAlloc dt=7 heapalloc_value=11874544 +HeapAlloc dt=6 heapalloc_value=11882736 +HeapAlloc dt=6 heapalloc_value=11890928 +HeapAlloc dt=6 heapalloc_value=11899120 +HeapAlloc dt=6 heapalloc_value=11907312 +HeapAlloc dt=7 heapalloc_value=11915504 +HeapAlloc dt=6 heapalloc_value=11923696 +HeapAlloc dt=6 heapalloc_value=11931888 +HeapAlloc dt=6 heapalloc_value=11940080 +HeapAlloc dt=6 heapalloc_value=11948272 +HeapAlloc dt=6 heapalloc_value=11956464 +HeapAlloc dt=6 heapalloc_value=11964656 +HeapAlloc dt=6 heapalloc_value=11972848 +HeapAlloc dt=7 heapalloc_value=11981040 +HeapAlloc dt=6 heapalloc_value=11989232 +HeapAlloc dt=6 heapalloc_value=11997424 +HeapAlloc dt=6 heapalloc_value=12005616 +HeapAlloc dt=7 heapalloc_value=12013808 +HeapAlloc dt=6 heapalloc_value=12022000 +HeapAlloc dt=6 heapalloc_value=12030192 +HeapAlloc dt=6 heapalloc_value=12038384 +HeapAlloc dt=6 heapalloc_value=12046576 +HeapAlloc dt=6 heapalloc_value=12054768 +HeapAlloc dt=6 heapalloc_value=12062960 +HeapAlloc dt=67 heapalloc_value=12071152 +HeapAlloc dt=8 heapalloc_value=12079344 +HeapAlloc dt=7 heapalloc_value=12087536 +HeapAlloc dt=6 heapalloc_value=12095728 +HeapAlloc dt=6 heapalloc_value=12103920 +HeapAlloc dt=6 heapalloc_value=12112112 +HeapAlloc dt=6 heapalloc_value=12120304 +HeapAlloc dt=6 heapalloc_value=12128496 +HeapAlloc dt=6 heapalloc_value=12136688 +HeapAlloc dt=6 heapalloc_value=12144880 +HeapAlloc dt=59 heapalloc_value=12153072 +HeapAlloc dt=8 heapalloc_value=12161264 +HeapAlloc dt=6 heapalloc_value=12169456 +HeapAlloc dt=6 heapalloc_value=12177648 +HeapAlloc dt=6 heapalloc_value=12185840 +HeapAlloc dt=6 heapalloc_value=12194032 +HeapAlloc dt=7 heapalloc_value=12202224 +HeapAlloc dt=6 heapalloc_value=12210416 +HeapAlloc dt=6 heapalloc_value=12218608 +GoBlock dt=12 reason_string=19 stack=21 +ProcStop dt=223 +ProcStart dt=12071 p=1 p_seq=25 +GoUnblock dt=11 g=1 g_seq=37 stack=0 +GoStart dt=161 g=1 g_seq=38 +HeapAlloc dt=75 heapalloc_value=12226800 +HeapAlloc dt=11 heapalloc_value=12234992 +HeapAlloc dt=6 heapalloc_value=12243184 +HeapAlloc dt=6 heapalloc_value=12251376 +HeapAlloc dt=7 heapalloc_value=12259568 +HeapAlloc dt=6 heapalloc_value=12267760 +HeapAlloc dt=6 heapalloc_value=12275952 +HeapAlloc dt=6 heapalloc_value=12284144 +HeapAlloc dt=6 heapalloc_value=12292336 +HeapAlloc dt=7 heapalloc_value=12300528 +HeapAlloc dt=6 heapalloc_value=12308720 +HeapAlloc dt=6 heapalloc_value=12316912 +HeapAlloc dt=7 heapalloc_value=12325104 +HeapAlloc dt=87 heapalloc_value=12333296 +HeapAlloc dt=25 heapalloc_value=12341488 +HeapAlloc dt=7 heapalloc_value=12349680 +HeapAlloc dt=6 heapalloc_value=12357872 +HeapAlloc dt=7 heapalloc_value=12366064 +HeapAlloc dt=10 heapalloc_value=12374256 +HeapAlloc dt=7 heapalloc_value=12382448 +HeapAlloc dt=9 heapalloc_value=12390640 +HeapAlloc dt=6 heapalloc_value=12398832 +HeapAlloc dt=6 heapalloc_value=12407024 +HeapAlloc dt=7 heapalloc_value=12415216 +HeapAlloc dt=6 heapalloc_value=12423408 +HeapAlloc dt=44 heapalloc_value=12431600 +HeapAlloc dt=7 heapalloc_value=12439792 +HeapAlloc dt=7 heapalloc_value=12447984 +HeapAlloc dt=6 heapalloc_value=12456176 +HeapAlloc dt=6 heapalloc_value=12464368 +HeapAlloc dt=6 heapalloc_value=12472560 +HeapAlloc dt=6 heapalloc_value=12480752 +HeapAlloc dt=7 heapalloc_value=12488944 +HeapAlloc dt=6 heapalloc_value=12497136 +HeapAlloc dt=6 heapalloc_value=12505328 +HeapAlloc dt=6 heapalloc_value=12513520 +HeapAlloc dt=6 heapalloc_value=12521712 +HeapAlloc dt=7 heapalloc_value=12529904 +HeapAlloc dt=6 heapalloc_value=12538096 +HeapAlloc dt=6 heapalloc_value=12546288 +HeapAlloc dt=6 heapalloc_value=12554480 +HeapAlloc dt=6 heapalloc_value=12562672 +HeapAlloc dt=6 heapalloc_value=12570864 +HeapAlloc dt=11 heapalloc_value=12579056 +HeapAlloc dt=6 heapalloc_value=12587248 +HeapAlloc dt=455 heapalloc_value=12595440 +HeapAlloc dt=12 heapalloc_value=12603632 +HeapAlloc dt=7 heapalloc_value=12611824 +HeapAlloc dt=6 heapalloc_value=12620016 +HeapAlloc dt=7 heapalloc_value=12628208 +HeapAlloc dt=6 heapalloc_value=12636400 +HeapAlloc dt=6 heapalloc_value=12644592 +HeapAlloc dt=6 heapalloc_value=12652784 +HeapAlloc dt=7 heapalloc_value=12660976 +HeapAlloc dt=6 heapalloc_value=12669168 +HeapAlloc dt=97 heapalloc_value=12677360 +HeapAlloc dt=8 heapalloc_value=12685552 +HeapAlloc dt=6 heapalloc_value=12693744 +HeapAlloc dt=6 heapalloc_value=12701936 +HeapAlloc dt=6 heapalloc_value=12710128 +HeapAlloc dt=6 heapalloc_value=12718320 +HeapAlloc dt=6 heapalloc_value=12726512 +HeapAlloc dt=7 heapalloc_value=12734704 +HeapAlloc dt=6 heapalloc_value=12742896 +HeapAlloc dt=6 heapalloc_value=12751088 +HeapAlloc dt=6 heapalloc_value=12759280 +HeapAlloc dt=7 heapalloc_value=12767472 +HeapAlloc dt=7 heapalloc_value=12775664 +HeapAlloc dt=6 heapalloc_value=12783856 +HeapAlloc dt=6 heapalloc_value=12792048 +HeapAlloc dt=6 heapalloc_value=12800240 +HeapAlloc dt=7 heapalloc_value=12808432 +HeapAlloc dt=6 heapalloc_value=12816624 +HeapAlloc dt=6 heapalloc_value=12824816 +HeapAlloc dt=6 heapalloc_value=12833008 +HeapAlloc dt=6 heapalloc_value=12841200 +HeapAlloc dt=42 heapalloc_value=12849392 +HeapAlloc dt=79 heapalloc_value=12857584 +HeapAlloc dt=8 heapalloc_value=12865776 +HeapAlloc dt=6 heapalloc_value=12873968 +HeapAlloc dt=6 heapalloc_value=12882160 +HeapAlloc dt=7 heapalloc_value=12890352 +HeapAlloc dt=6 heapalloc_value=12898544 +HeapAlloc dt=6 heapalloc_value=12906736 +HeapAlloc dt=6 heapalloc_value=12914928 +HeapAlloc dt=7 heapalloc_value=12923120 +HeapAlloc dt=6 heapalloc_value=12931312 +HeapAlloc dt=6 heapalloc_value=12939504 +HeapAlloc dt=6 heapalloc_value=12947696 +HeapAlloc dt=6 heapalloc_value=12955888 +HeapAlloc dt=6 heapalloc_value=12964080 +HeapAlloc dt=6 heapalloc_value=12972272 +HeapAlloc dt=6 heapalloc_value=12980464 +HeapAlloc dt=7 heapalloc_value=12988656 +HeapAlloc dt=6 heapalloc_value=12996848 +HeapAlloc dt=6 heapalloc_value=13005040 +HeapAlloc dt=6 heapalloc_value=13013232 +HeapAlloc dt=7 heapalloc_value=13021424 +HeapAlloc dt=6 heapalloc_value=13029616 +HeapAlloc dt=6 heapalloc_value=13037808 +HeapAlloc dt=6 heapalloc_value=13046000 +HeapAlloc dt=6 heapalloc_value=13054192 +HeapAlloc dt=7 heapalloc_value=13062384 +HeapAlloc dt=6 heapalloc_value=13070576 +HeapAlloc dt=6 heapalloc_value=13078768 +HeapAlloc dt=6 heapalloc_value=13086960 +HeapAlloc dt=6 heapalloc_value=13095152 +HeapAlloc dt=7 heapalloc_value=13103344 +HeapAlloc dt=6 heapalloc_value=13111536 +HeapAlloc dt=67 heapalloc_value=13119728 +HeapAlloc dt=8 heapalloc_value=13127920 +HeapAlloc dt=6 heapalloc_value=13136112 +HeapAlloc dt=6 heapalloc_value=13144304 +HeapAlloc dt=7 heapalloc_value=13152496 +HeapAlloc dt=6 heapalloc_value=13160688 +HeapAlloc dt=6 heapalloc_value=13168880 +HeapAlloc dt=6 heapalloc_value=13177072 +HeapAlloc dt=6 heapalloc_value=13185264 +HeapAlloc dt=6 heapalloc_value=13193456 +HeapAlloc dt=105 heapalloc_value=13201648 +HeapAlloc dt=8 heapalloc_value=13209840 +HeapAlloc dt=6 heapalloc_value=13218032 +HeapAlloc dt=6 heapalloc_value=13226224 +HeapAlloc dt=6 heapalloc_value=13234416 +HeapAlloc dt=6 heapalloc_value=13242608 +GoBlock dt=10 reason_string=19 stack=21 +ProcStop dt=13 +ProcStart dt=3484 p=2 p_seq=18 +ProcStop dt=18 +ProcStart dt=5821 p=1 p_seq=27 +ProcStop dt=12 +ProcStart dt=16793 p=1 p_seq=28 +GoUnblock dt=16 g=1 g_seq=41 stack=0 +GoStart dt=193 g=1 g_seq=42 +HeapAlloc dt=36 heapalloc_value=14643440 +HeapAlloc dt=29 heapalloc_value=14651632 +HeapAlloc dt=16 heapalloc_value=14659824 +HeapAlloc dt=20 heapalloc_value=14668016 +HeapAlloc dt=13 heapalloc_value=14676208 +HeapAlloc dt=84 heapalloc_value=14684400 +HeapAlloc dt=17 heapalloc_value=14692592 +HeapAlloc dt=12 heapalloc_value=14700784 +HeapAlloc dt=12 heapalloc_value=14708976 +HeapAlloc dt=12 heapalloc_value=14717168 +HeapAlloc dt=12 heapalloc_value=14725360 +HeapAlloc dt=22 heapalloc_value=14733552 +HeapAlloc dt=12 heapalloc_value=14741744 +HeapAlloc dt=13 heapalloc_value=14749936 +HeapAlloc dt=12 heapalloc_value=14758128 +HeapAlloc dt=11 heapalloc_value=14766320 +HeapAlloc dt=13 heapalloc_value=14774512 +HeapAlloc dt=12 heapalloc_value=14782704 +HeapAlloc dt=12 heapalloc_value=14790896 +HeapAlloc dt=61 heapalloc_value=14799088 +HeapAlloc dt=13 heapalloc_value=14807280 +HeapAlloc dt=7 heapalloc_value=14815472 +HeapAlloc dt=11 heapalloc_value=14823664 +HeapAlloc dt=9 heapalloc_value=14831856 +HeapAlloc dt=11 heapalloc_value=14840048 +HeapAlloc dt=6 heapalloc_value=14848240 +HeapAlloc dt=7 heapalloc_value=14856432 +HeapAlloc dt=9 heapalloc_value=14864624 +HeapAlloc dt=6 heapalloc_value=14872816 +HeapAlloc dt=6 heapalloc_value=14881008 +HeapAlloc dt=46 heapalloc_value=14889200 +HeapAlloc dt=8 heapalloc_value=14897392 +HeapAlloc dt=6 heapalloc_value=14905584 +HeapAlloc dt=7 heapalloc_value=14913776 +HeapAlloc dt=6 heapalloc_value=14921968 +HeapAlloc dt=7 heapalloc_value=14930160 +HeapAlloc dt=7 heapalloc_value=14938352 +HeapAlloc dt=6 heapalloc_value=14946544 +HeapAlloc dt=155 heapalloc_value=14954736 +HeapAlloc dt=9 heapalloc_value=14962928 +HeapAlloc dt=6 heapalloc_value=14971120 +HeapAlloc dt=7 heapalloc_value=14979312 +HeapAlloc dt=6 heapalloc_value=14987504 +HeapAlloc dt=6 heapalloc_value=14995696 +HeapAlloc dt=6 heapalloc_value=15003888 +HeapAlloc dt=6 heapalloc_value=15012080 +HeapAlloc dt=8 heapalloc_value=15020272 +HeapAlloc dt=6 heapalloc_value=15028464 +HeapAlloc dt=7 heapalloc_value=15036656 +HeapAlloc dt=6 heapalloc_value=15044848 +HeapAlloc dt=6 heapalloc_value=15053040 +HeapAlloc dt=6 heapalloc_value=15061232 +HeapAlloc dt=6 heapalloc_value=15069424 +HeapAlloc dt=6 heapalloc_value=15077616 +HeapAlloc dt=8 heapalloc_value=15085808 +HeapAlloc dt=6 heapalloc_value=15094000 +HeapAlloc dt=7 heapalloc_value=15102192 +HeapAlloc dt=6 heapalloc_value=15110384 +HeapAlloc dt=6 heapalloc_value=15118576 +HeapAlloc dt=6 heapalloc_value=15126768 +HeapAlloc dt=68 heapalloc_value=15134960 +HeapAlloc dt=8 heapalloc_value=15143152 +HeapAlloc dt=6 heapalloc_value=15151344 +HeapAlloc dt=6 heapalloc_value=15159536 +HeapAlloc dt=6 heapalloc_value=15167728 +HeapAlloc dt=6 heapalloc_value=15175920 +HeapAlloc dt=6 heapalloc_value=15184112 +HeapAlloc dt=6 heapalloc_value=15192304 +HeapAlloc dt=6 heapalloc_value=15200496 +HeapAlloc dt=6 heapalloc_value=15208688 +HeapAlloc dt=68 heapalloc_value=15216880 +HeapAlloc dt=8 heapalloc_value=15225072 +HeapAlloc dt=7 heapalloc_value=15233264 +HeapAlloc dt=6 heapalloc_value=15241456 +HeapAlloc dt=6 heapalloc_value=15249648 +HeapAlloc dt=7 heapalloc_value=15257840 +HeapAlloc dt=6 heapalloc_value=15266032 +HeapAlloc dt=6 heapalloc_value=15274224 +HeapAlloc dt=8 heapalloc_value=15282416 +HeapAlloc dt=6 heapalloc_value=15290608 +HeapAlloc dt=7 heapalloc_value=15298800 +HeapAlloc dt=43 heapalloc_value=15306992 +HeapAlloc dt=7 heapalloc_value=15315184 +HeapAlloc dt=6 heapalloc_value=15323376 +HeapAlloc dt=7 heapalloc_value=15331568 +HeapAlloc dt=6 heapalloc_value=15339760 +HeapAlloc dt=8 heapalloc_value=15347952 +HeapAlloc dt=6 heapalloc_value=15356144 +HeapAlloc dt=6 heapalloc_value=15364336 +HeapAlloc dt=7 heapalloc_value=15372528 +HeapAlloc dt=6 heapalloc_value=15380720 +HeapAlloc dt=6 heapalloc_value=15388912 +HeapAlloc dt=6 heapalloc_value=15397104 +HeapAlloc dt=7 heapalloc_value=15405296 +HeapAlloc dt=8 heapalloc_value=15413488 +HeapAlloc dt=6 heapalloc_value=15421680 +HeapAlloc dt=6 heapalloc_value=15429872 +HeapAlloc dt=6 heapalloc_value=15438064 +HeapAlloc dt=7 heapalloc_value=15446256 +HeapAlloc dt=7 heapalloc_value=15454448 +HeapAlloc dt=6 heapalloc_value=15462640 +HeapAlloc dt=6 heapalloc_value=15470832 +HeapAlloc dt=470 heapalloc_value=15479024 +HeapAlloc dt=14 heapalloc_value=15487216 +HeapAlloc dt=6 heapalloc_value=15495408 +HeapAlloc dt=7 heapalloc_value=15503600 +HeapAlloc dt=6 heapalloc_value=15511792 +HeapAlloc dt=7 heapalloc_value=15519984 +HeapAlloc dt=6 heapalloc_value=15528176 +HeapAlloc dt=6 heapalloc_value=15536368 +HeapAlloc dt=6 heapalloc_value=15544560 +HeapAlloc dt=5 heapalloc_value=15552752 +HeapAlloc dt=6 heapalloc_value=15560944 +HeapAlloc dt=6 heapalloc_value=15569136 +HeapAlloc dt=6 heapalloc_value=15577328 +HeapAlloc dt=6 heapalloc_value=15585520 +HeapAlloc dt=6 heapalloc_value=15593712 +HeapAlloc dt=6 heapalloc_value=15601904 +HeapAlloc dt=6 heapalloc_value=15610096 +HeapAlloc dt=6 heapalloc_value=15618288 +HeapAlloc dt=6 heapalloc_value=15626480 +HeapAlloc dt=6 heapalloc_value=15634672 +HeapAlloc dt=6 heapalloc_value=15642864 +HeapAlloc dt=6 heapalloc_value=15651056 +HeapAlloc dt=77 heapalloc_value=15659248 +GoBlock dt=13 reason_string=19 stack=21 +ProcStop dt=214 +ProcStart dt=17833 p=2 p_seq=20 +ProcStop dt=18 +ProcStart dt=9948 p=4 p_seq=4 +ProcStop dt=23 +ProcStart dt=5868 p=3 p_seq=6 +ProcStop dt=25 +ProcStart dt=94440 p=3 p_seq=7 +ProcStop dt=17 +ProcStart dt=7801 p=3 p_seq=8 +GoStart dt=172 g=13 g_seq=1 +GoStop dt=306385 reason_string=16 stack=52 +GoStart dt=19 g=13 g_seq=2 +GoStop dt=316412 reason_string=16 stack=52 +GoStart dt=14 g=13 g_seq=3 +GoDestroy dt=158437 +ProcStop dt=31 +EventBatch gen=1 m=2852342 time=420901452973 size=3683 +ProcStart dt=335 p=2 p_seq=1 +GoStart dt=164 g=21 g_seq=1 +HeapAlloc dt=242 heapalloc_value=1654784 +GoSyscallBegin dt=3053 p_seq=2 stack=17 +GoSyscallEnd dt=264 +GoBlock dt=22 reason_string=15 stack=18 +ProcStop dt=21 +ProcStart dt=370120 p=0 p_seq=11 +ProcStop dt=21 +ProcStart dt=7624 p=1 p_seq=5 +ProcStop dt=18 +ProcStart dt=386 p=2 p_seq=4 +GoStart dt=180 g=24 g_seq=1 +GoBlock dt=122 reason_string=15 stack=26 +ProcStop dt=14 +ProcStart dt=378 p=2 p_seq=7 +ProcStop dt=16 +ProcStart dt=1400 p=2 p_seq=8 +GoStart dt=127 g=9 g_seq=1 +GoBlock dt=106 reason_string=15 stack=26 +ProcStop dt=5 +ProcStart dt=482 p=1 p_seq=14 +ProcStop dt=11 +ProcStart dt=2026 p=3 p_seq=2 +HeapAlloc dt=470 heapalloc_value=4079616 +HeapAlloc dt=451 heapalloc_value=4128768 +HeapAlloc dt=21 heapalloc_value=4136960 +GoStart dt=1190 g=4 g_seq=2 +GoBlock dt=29 reason_string=15 stack=32 +ProcStop dt=34 +ProcStart dt=77810 p=3 p_seq=3 +ProcStop dt=32 +ProcStart dt=600 p=3 p_seq=4 +GoUnblock dt=14 g=25 g_seq=6 stack=0 +GoStart dt=184 g=25 g_seq=7 +GoLabel dt=3 label_string=2 +GoBlock dt=145 reason_string=15 stack=26 +ProcStop dt=27 +ProcStart dt=122643 p=3 p_seq=5 +GoStart dt=236 g=4 g_seq=8 +GoBlock dt=24 reason_string=15 stack=32 +GoUnblock dt=25 g=8 g_seq=4 stack=0 +GoStart dt=9 g=8 g_seq=5 +GoLabel dt=1 label_string=4 +GoBlock dt=1341 reason_string=15 stack=26 +GoUnblock dt=4399 g=1 g_seq=45 stack=0 +GoStart dt=12 g=1 g_seq=46 +HeapAlloc dt=416 heapalloc_value=16705232 +HeapAlloc dt=47 heapalloc_value=16721328 +HeapAlloc dt=35 heapalloc_value=16729520 +HeapAlloc dt=24 heapalloc_value=16737712 +HeapAlloc dt=26 heapalloc_value=16745904 +HeapAlloc dt=24 heapalloc_value=16754096 +HeapAlloc dt=13 heapalloc_value=16762288 +HeapAlloc dt=15 heapalloc_value=16770480 +HeapAlloc dt=14 heapalloc_value=16778672 +HeapAlloc dt=14 heapalloc_value=16786864 +HeapAlloc dt=14 heapalloc_value=16795056 +HeapAlloc dt=13 heapalloc_value=16803248 +HeapAlloc dt=12 heapalloc_value=16811440 +HeapAlloc dt=14 heapalloc_value=16819632 +HeapAlloc dt=13 heapalloc_value=16827824 +HeapAlloc dt=13 heapalloc_value=16836016 +HeapAlloc dt=14 heapalloc_value=16844208 +HeapAlloc dt=14 heapalloc_value=16852400 +HeapAlloc dt=13 heapalloc_value=16860592 +HeapAlloc dt=13 heapalloc_value=16868784 +HeapAlloc dt=12 heapalloc_value=16876976 +HeapAlloc dt=19 heapalloc_value=16885168 +HeapAlloc dt=15 heapalloc_value=16893360 +HeapAlloc dt=14 heapalloc_value=16901552 +HeapAlloc dt=14 heapalloc_value=16909744 +HeapAlloc dt=13 heapalloc_value=16917936 +HeapAlloc dt=13 heapalloc_value=16926128 +HeapAlloc dt=12 heapalloc_value=16934320 +HeapAlloc dt=14 heapalloc_value=16942512 +HeapAlloc dt=14 heapalloc_value=16950704 +HeapAlloc dt=12 heapalloc_value=16958896 +HeapAlloc dt=13 heapalloc_value=16967088 +HeapAlloc dt=479 heapalloc_value=16975280 +HeapAlloc dt=207 heapalloc_value=16983472 +HeapAlloc dt=15 heapalloc_value=16991664 +HeapAlloc dt=111 heapalloc_value=16999856 +HeapAlloc dt=14 heapalloc_value=17008048 +HeapAlloc dt=13 heapalloc_value=17016240 +HeapAlloc dt=13 heapalloc_value=17024432 +HeapAlloc dt=13 heapalloc_value=17032624 +HeapAlloc dt=12 heapalloc_value=17040816 +HeapAlloc dt=14 heapalloc_value=17049008 +HeapAlloc dt=13 heapalloc_value=17057200 +HeapAlloc dt=15 heapalloc_value=17065392 +HeapAlloc dt=14 heapalloc_value=17073584 +HeapAlloc dt=15 heapalloc_value=17081776 +HeapAlloc dt=14 heapalloc_value=17089968 +HeapAlloc dt=14 heapalloc_value=17098160 +HeapAlloc dt=14 heapalloc_value=17106352 +HeapAlloc dt=15 heapalloc_value=17114544 +HeapAlloc dt=14 heapalloc_value=17122736 +HeapAlloc dt=19 heapalloc_value=17130928 +HeapAlloc dt=20 heapalloc_value=17139120 +HeapAlloc dt=19 heapalloc_value=17147312 +HeapAlloc dt=14 heapalloc_value=17155504 +HeapAlloc dt=14 heapalloc_value=17163696 +HeapAlloc dt=15 heapalloc_value=17171888 +HeapAlloc dt=14 heapalloc_value=17180080 +HeapAlloc dt=14 heapalloc_value=17188272 +HeapAlloc dt=16 heapalloc_value=17196464 +HeapAlloc dt=147 heapalloc_value=17204656 +HeapAlloc dt=17 heapalloc_value=17212848 +HeapAlloc dt=14 heapalloc_value=17221040 +HeapAlloc dt=15 heapalloc_value=17229232 +HeapAlloc dt=133 heapalloc_value=17237424 +HeapAlloc dt=66 heapalloc_value=17245616 +HeapAlloc dt=17 heapalloc_value=17253808 +HeapAlloc dt=14 heapalloc_value=17262000 +HeapAlloc dt=14 heapalloc_value=17270192 +HeapAlloc dt=15 heapalloc_value=17278384 +HeapAlloc dt=14 heapalloc_value=17286576 +HeapAlloc dt=14 heapalloc_value=17294768 +HeapAlloc dt=17 heapalloc_value=17302960 +HeapAlloc dt=14 heapalloc_value=17311152 +GoStop dt=24 reason_string=16 stack=46 +GoStart dt=859 g=1 g_seq=47 +HeapAlloc dt=19 heapalloc_value=17319344 +HeapAlloc dt=16 heapalloc_value=17327536 +HeapAlloc dt=14 heapalloc_value=17335728 +HeapAlloc dt=14 heapalloc_value=17343920 +HeapAlloc dt=15 heapalloc_value=17352112 +HeapAlloc dt=14 heapalloc_value=17360304 +HeapAlloc dt=14 heapalloc_value=17368496 +HeapAlloc dt=14 heapalloc_value=17376688 +HeapAlloc dt=18 heapalloc_value=17384880 +HeapAlloc dt=17 heapalloc_value=17393072 +HeapAlloc dt=14 heapalloc_value=17401264 +HeapAlloc dt=18 heapalloc_value=17409456 +HeapAlloc dt=14 heapalloc_value=17417648 +HeapAlloc dt=14 heapalloc_value=17425840 +HeapAlloc dt=15 heapalloc_value=17434032 +HeapAlloc dt=12 heapalloc_value=17442224 +HeapAlloc dt=18 heapalloc_value=17450416 +HeapAlloc dt=69 heapalloc_value=17458608 +HeapAlloc dt=15 heapalloc_value=17466800 +HeapAlloc dt=14 heapalloc_value=17474992 +HeapAlloc dt=12 heapalloc_value=17483184 +HeapAlloc dt=14 heapalloc_value=17491376 +HeapAlloc dt=405 heapalloc_value=17499568 +GoStop dt=11 reason_string=16 stack=31 +ProcStop dt=10 +ProcStart dt=1071 p=0 p_seq=41 +GoStart dt=509 g=1 g_seq=48 +HeapAlloc dt=31 heapalloc_value=16800656 +GCSweepBegin dt=40 stack=38 +GCSweepEnd dt=407 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=25 heapalloc_value=16808848 +GCSweepBegin dt=25 stack=38 +GCSweepEnd dt=1029 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=20 heapalloc_value=16817040 +GCSweepBegin dt=33 stack=38 +GCSweepEnd dt=1076 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=13 heapalloc_value=16825232 +GCSweepBegin dt=30 stack=38 +GCSweepEnd dt=1298 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=17 heapalloc_value=16833424 +GCSweepBegin dt=29 stack=38 +GCSweepEnd dt=1140 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=11 heapalloc_value=16841616 +GCSweepBegin dt=32 stack=38 +GCSweepEnd dt=1161 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=14 heapalloc_value=16849808 +GCSweepBegin dt=31 stack=38 +GCSweepEnd dt=763 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=12 heapalloc_value=16858000 +GCSweepBegin dt=29 stack=38 +GCSweepEnd dt=1113 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=9 heapalloc_value=16866192 +GCSweepBegin dt=25 stack=38 +GCSweepEnd dt=1068 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=21 heapalloc_value=16874384 +GCSweepBegin dt=36 stack=38 +GCSweepEnd dt=478 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=7 heapalloc_value=16882576 +GCSweepBegin dt=16 stack=38 +GCSweepEnd dt=32 swept_value=90112 reclaimed_value=0 +HeapAlloc dt=11 heapalloc_value=16890768 +HeapAlloc dt=31 heapalloc_value=16898960 +HeapAlloc dt=24 heapalloc_value=16907152 +HeapAlloc dt=17 heapalloc_value=16915344 +HeapAlloc dt=17 heapalloc_value=16923536 +HeapAlloc dt=23 heapalloc_value=16931728 +HeapAlloc dt=18 heapalloc_value=16939920 +HeapAlloc dt=22 heapalloc_value=16948112 +HeapAlloc dt=17 heapalloc_value=16956304 +HeapAlloc dt=16 heapalloc_value=16964496 +HeapAlloc dt=16 heapalloc_value=16972688 +HeapAlloc dt=106 heapalloc_value=16980880 +HeapAlloc dt=19 heapalloc_value=16989072 +HeapAlloc dt=16 heapalloc_value=16997264 +HeapAlloc dt=13 heapalloc_value=17005456 +HeapAlloc dt=13 heapalloc_value=17013648 +HeapAlloc dt=96 heapalloc_value=17021840 +HeapAlloc dt=16 heapalloc_value=17030032 +GoBlock dt=18 reason_string=19 stack=21 +ProcStop dt=315 +ProcStart dt=17450 p=2 p_seq=23 +ProcStop dt=14 +ProcStart dt=6669 p=0 p_seq=44 +ProcStop dt=11 +ProcStart dt=16752 p=0 p_seq=45 +GoUnblock dt=14 g=1 g_seq=51 stack=0 +GoStart dt=146 g=1 g_seq=52 +HeapAlloc dt=31 heapalloc_value=18529168 +HeapAlloc dt=21 heapalloc_value=18537360 +HeapAlloc dt=13 heapalloc_value=18545552 +HeapAlloc dt=77 heapalloc_value=18553744 +HeapAlloc dt=21 heapalloc_value=18561936 +HeapAlloc dt=15 heapalloc_value=18570128 +HeapAlloc dt=12 heapalloc_value=18578320 +HeapAlloc dt=12 heapalloc_value=18586512 +HeapAlloc dt=12 heapalloc_value=18594704 +HeapAlloc dt=16 heapalloc_value=18602896 +HeapAlloc dt=14 heapalloc_value=18611088 +HeapAlloc dt=13 heapalloc_value=18619280 +HeapAlloc dt=17 heapalloc_value=18627472 +HeapAlloc dt=13 heapalloc_value=18635664 +HeapAlloc dt=14 heapalloc_value=18643856 +HeapAlloc dt=12 heapalloc_value=18652048 +HeapAlloc dt=12 heapalloc_value=18660240 +HeapAlloc dt=12 heapalloc_value=18668432 +HeapAlloc dt=12 heapalloc_value=18676624 +HeapAlloc dt=12 heapalloc_value=18684816 +HeapAlloc dt=93 heapalloc_value=18693008 +HeapAlloc dt=17 heapalloc_value=18701200 +HeapAlloc dt=12 heapalloc_value=18709392 +HeapAlloc dt=13 heapalloc_value=18717584 +HeapAlloc dt=15 heapalloc_value=18725776 +HeapAlloc dt=12 heapalloc_value=18733968 +HeapAlloc dt=13 heapalloc_value=18742160 +HeapAlloc dt=14 heapalloc_value=18750352 +HeapAlloc dt=12 heapalloc_value=18758544 +HeapAlloc dt=54 heapalloc_value=18766736 +HeapAlloc dt=13 heapalloc_value=18774928 +HeapAlloc dt=13 heapalloc_value=18783120 +HeapAlloc dt=12 heapalloc_value=18791312 +HeapAlloc dt=13 heapalloc_value=18799504 +HeapAlloc dt=12 heapalloc_value=18807696 +HeapAlloc dt=13 heapalloc_value=18815888 +HeapAlloc dt=12 heapalloc_value=18824080 +HeapAlloc dt=13 heapalloc_value=18832272 +HeapAlloc dt=12 heapalloc_value=18840464 +HeapAlloc dt=13 heapalloc_value=18848656 +HeapAlloc dt=12 heapalloc_value=18856848 +HeapAlloc dt=13 heapalloc_value=18865040 +HeapAlloc dt=13 heapalloc_value=18873232 +HeapAlloc dt=12 heapalloc_value=18881424 +HeapAlloc dt=14 heapalloc_value=18889616 +HeapAlloc dt=13 heapalloc_value=18897808 +HeapAlloc dt=12 heapalloc_value=18906000 +HeapAlloc dt=13 heapalloc_value=18914192 +HeapAlloc dt=13 heapalloc_value=18922384 +HeapAlloc dt=86 heapalloc_value=18930576 +HeapAlloc dt=15 heapalloc_value=18938768 +HeapAlloc dt=13 heapalloc_value=18946960 +HeapAlloc dt=26 heapalloc_value=18955152 +HeapAlloc dt=19 heapalloc_value=18963344 +HeapAlloc dt=12 heapalloc_value=18971536 +HeapAlloc dt=14 heapalloc_value=18979728 +HeapAlloc dt=14 heapalloc_value=18987920 +HeapAlloc dt=13 heapalloc_value=18996112 +HeapAlloc dt=12 heapalloc_value=19004304 +HeapAlloc dt=64 heapalloc_value=19012496 +HeapAlloc dt=15 heapalloc_value=19020688 +HeapAlloc dt=14 heapalloc_value=19028880 +HeapAlloc dt=14 heapalloc_value=19037072 +HeapAlloc dt=16 heapalloc_value=19045264 +HeapAlloc dt=77 heapalloc_value=19053456 +HeapAlloc dt=16 heapalloc_value=19061648 +HeapAlloc dt=13 heapalloc_value=19069840 +HeapAlloc dt=16 heapalloc_value=19078032 +HeapAlloc dt=12 heapalloc_value=19086224 +HeapAlloc dt=12 heapalloc_value=19094416 +HeapAlloc dt=13 heapalloc_value=19102608 +HeapAlloc dt=14 heapalloc_value=19110800 +HeapAlloc dt=15 heapalloc_value=19118992 +HeapAlloc dt=14 heapalloc_value=19127184 +HeapAlloc dt=13 heapalloc_value=19135376 +HeapAlloc dt=13 heapalloc_value=19143568 +HeapAlloc dt=15 heapalloc_value=19151760 +HeapAlloc dt=18 heapalloc_value=19159952 +HeapAlloc dt=16 heapalloc_value=19168144 +HeapAlloc dt=15 heapalloc_value=19176336 +HeapAlloc dt=113 heapalloc_value=19184528 +HeapAlloc dt=17 heapalloc_value=19192720 +HeapAlloc dt=13 heapalloc_value=19200912 +HeapAlloc dt=18 heapalloc_value=19209104 +HeapAlloc dt=15 heapalloc_value=19217296 +HeapAlloc dt=18 heapalloc_value=19225488 +HeapAlloc dt=15 heapalloc_value=19233680 +HeapAlloc dt=16 heapalloc_value=19241872 +HeapAlloc dt=16 heapalloc_value=19250064 +HeapAlloc dt=15 heapalloc_value=19258256 +HeapAlloc dt=14 heapalloc_value=19266448 +HeapAlloc dt=15 heapalloc_value=19274640 +HeapAlloc dt=13 heapalloc_value=19282832 +HeapAlloc dt=20 heapalloc_value=19291024 +HeapAlloc dt=15 heapalloc_value=19299216 +HeapAlloc dt=16 heapalloc_value=19307408 +HeapAlloc dt=26 heapalloc_value=19315600 +HeapAlloc dt=9 heapalloc_value=19323792 +HeapAlloc dt=6 heapalloc_value=19331984 +HeapAlloc dt=7 heapalloc_value=19340176 +HeapAlloc dt=7 heapalloc_value=19348368 +HeapAlloc dt=8 heapalloc_value=19356560 +HeapAlloc dt=70 heapalloc_value=19364752 +HeapAlloc dt=8 heapalloc_value=19372944 +HeapAlloc dt=7 heapalloc_value=19381136 +HeapAlloc dt=6 heapalloc_value=19389328 +HeapAlloc dt=7 heapalloc_value=19397520 +HeapAlloc dt=8 heapalloc_value=19405712 +HeapAlloc dt=7 heapalloc_value=19413904 +HeapAlloc dt=7 heapalloc_value=19422096 +HeapAlloc dt=8 heapalloc_value=19430288 +HeapAlloc dt=7 heapalloc_value=19438480 +HeapAlloc dt=6 heapalloc_value=19446672 +HeapAlloc dt=7 heapalloc_value=19454864 +HeapAlloc dt=7 heapalloc_value=19463056 +HeapAlloc dt=7 heapalloc_value=19471248 +HeapAlloc dt=6 heapalloc_value=19479440 +HeapAlloc dt=7 heapalloc_value=19487632 +HeapAlloc dt=6 heapalloc_value=19495824 +HeapAlloc dt=7 heapalloc_value=19504016 +HeapAlloc dt=7 heapalloc_value=19512208 +HeapAlloc dt=6 heapalloc_value=19520400 +HeapAlloc dt=8 heapalloc_value=19528592 +HeapAlloc dt=53 heapalloc_value=19536784 +HeapAlloc dt=8 heapalloc_value=19544976 +GoBlock dt=12 reason_string=19 stack=21 +ProcStop dt=196 +ProcStart dt=17347 p=2 p_seq=25 +ProcStop dt=14 +ProcStart dt=2376 p=0 p_seq=48 +ProcStop dt=11 +ProcStart dt=16736 p=0 p_seq=49 +GoUnblock dt=12 g=1 g_seq=55 stack=0 +GoStart dt=137 g=1 g_seq=56 +HeapAlloc dt=24 heapalloc_value=20577168 +HeapAlloc dt=87 heapalloc_value=20585360 +HeapAlloc dt=9 heapalloc_value=20593552 +HeapAlloc dt=6 heapalloc_value=20601744 +HeapAlloc dt=7 heapalloc_value=20609936 +HeapAlloc dt=7 heapalloc_value=20618128 +HeapAlloc dt=6 heapalloc_value=20626320 +HeapAlloc dt=7 heapalloc_value=20634512 +HeapAlloc dt=7 heapalloc_value=20642704 +HeapAlloc dt=6 heapalloc_value=20650896 +HeapAlloc dt=7 heapalloc_value=20659088 +HeapAlloc dt=7 heapalloc_value=20667280 +HeapAlloc dt=238 heapalloc_value=20675472 +HeapAlloc dt=10 heapalloc_value=20683664 +HeapAlloc dt=6 heapalloc_value=20691856 +HeapAlloc dt=7 heapalloc_value=20700048 +HeapAlloc dt=7 heapalloc_value=20708240 +HeapAlloc dt=6 heapalloc_value=20716432 +HeapAlloc dt=7 heapalloc_value=20724624 +HeapAlloc dt=6 heapalloc_value=20732816 +HeapAlloc dt=46 heapalloc_value=20741008 +HeapAlloc dt=8 heapalloc_value=20749200 +HeapAlloc dt=7 heapalloc_value=20757392 +HeapAlloc dt=7 heapalloc_value=20765584 +HeapAlloc dt=7 heapalloc_value=20773776 +HeapAlloc dt=7 heapalloc_value=20781968 +HeapAlloc dt=6 heapalloc_value=20790160 +HeapAlloc dt=7 heapalloc_value=20798352 +HeapAlloc dt=7 heapalloc_value=20806544 +HeapAlloc dt=6 heapalloc_value=20814736 +HeapAlloc dt=7 heapalloc_value=20822928 +HeapAlloc dt=7 heapalloc_value=20831120 +HeapAlloc dt=7 heapalloc_value=20839312 +HeapAlloc dt=7 heapalloc_value=20847504 +HeapAlloc dt=6 heapalloc_value=20855696 +HeapAlloc dt=7 heapalloc_value=20863888 +HeapAlloc dt=6 heapalloc_value=20872080 +HeapAlloc dt=7 heapalloc_value=20880272 +HeapAlloc dt=7 heapalloc_value=20888464 +HeapAlloc dt=6 heapalloc_value=20896656 +HeapAlloc dt=7 heapalloc_value=20904848 +HeapAlloc dt=7 heapalloc_value=20913040 +HeapAlloc dt=6 heapalloc_value=20921232 +HeapAlloc dt=7 heapalloc_value=20929424 +HeapAlloc dt=74 heapalloc_value=20937616 +HeapAlloc dt=8 heapalloc_value=20945808 +HeapAlloc dt=7 heapalloc_value=20954000 +HeapAlloc dt=6 heapalloc_value=20962192 +HeapAlloc dt=7 heapalloc_value=20970384 +HeapAlloc dt=7 heapalloc_value=20978576 +HeapAlloc dt=7 heapalloc_value=20986768 +HeapAlloc dt=6 heapalloc_value=20994960 +HeapAlloc dt=7 heapalloc_value=21003152 +HeapAlloc dt=7 heapalloc_value=21011344 +HeapAlloc dt=7 heapalloc_value=21019536 +HeapAlloc dt=6 heapalloc_value=21027728 +HeapAlloc dt=7 heapalloc_value=21035920 +HeapAlloc dt=6 heapalloc_value=21044112 +HeapAlloc dt=7 heapalloc_value=21052304 +HeapAlloc dt=7 heapalloc_value=21060496 +HeapAlloc dt=6 heapalloc_value=21068688 +HeapAlloc dt=7 heapalloc_value=21076880 +HeapAlloc dt=6 heapalloc_value=21085072 +HeapAlloc dt=7 heapalloc_value=21093264 +HeapAlloc dt=7 heapalloc_value=21101456 +HeapAlloc dt=90 heapalloc_value=21109648 +HeapAlloc dt=8 heapalloc_value=21117840 +HeapAlloc dt=6 heapalloc_value=21126032 +HeapAlloc dt=7 heapalloc_value=21134224 +HeapAlloc dt=7 heapalloc_value=21142416 +HeapAlloc dt=7 heapalloc_value=21150608 +HeapAlloc dt=6 heapalloc_value=21158800 +HeapAlloc dt=44 heapalloc_value=21166992 +HeapAlloc dt=7 heapalloc_value=21175184 +HeapAlloc dt=7 heapalloc_value=21183376 +HeapAlloc dt=7 heapalloc_value=21191568 +HeapAlloc dt=71 heapalloc_value=21199760 +HeapAlloc dt=8 heapalloc_value=21207952 +HeapAlloc dt=7 heapalloc_value=21216144 +HeapAlloc dt=7 heapalloc_value=21224336 +HeapAlloc dt=7 heapalloc_value=21232528 +HeapAlloc dt=6 heapalloc_value=21240720 +HeapAlloc dt=7 heapalloc_value=21248912 +HeapAlloc dt=7 heapalloc_value=21257104 +HeapAlloc dt=6 heapalloc_value=21265296 +HeapAlloc dt=7 heapalloc_value=21273488 +HeapAlloc dt=6 heapalloc_value=21281680 +HeapAlloc dt=7 heapalloc_value=21289872 +HeapAlloc dt=7 heapalloc_value=21298064 +HeapAlloc dt=6 heapalloc_value=21306256 +HeapAlloc dt=7 heapalloc_value=21314448 +HeapAlloc dt=6 heapalloc_value=21322640 +HeapAlloc dt=7 heapalloc_value=21330832 +HeapAlloc dt=7 heapalloc_value=21339024 +HeapAlloc dt=6 heapalloc_value=21347216 +HeapAlloc dt=7 heapalloc_value=21355408 +HeapAlloc dt=6 heapalloc_value=21363600 +HeapAlloc dt=43 heapalloc_value=21371792 +HeapAlloc dt=8 heapalloc_value=21379984 +HeapAlloc dt=7 heapalloc_value=21388176 +HeapAlloc dt=7 heapalloc_value=21396368 +HeapAlloc dt=6 heapalloc_value=21404560 +HeapAlloc dt=7 heapalloc_value=21412752 +HeapAlloc dt=7 heapalloc_value=21420944 +HeapAlloc dt=6 heapalloc_value=21429136 +HeapAlloc dt=7 heapalloc_value=21437328 +HeapAlloc dt=6 heapalloc_value=21445520 +HeapAlloc dt=7 heapalloc_value=21453712 +HeapAlloc dt=68 heapalloc_value=21461904 +HeapAlloc dt=8 heapalloc_value=21470096 +HeapAlloc dt=6 heapalloc_value=21478288 +HeapAlloc dt=7 heapalloc_value=21486480 +HeapAlloc dt=6 heapalloc_value=21494672 +HeapAlloc dt=7 heapalloc_value=21502864 +HeapAlloc dt=7 heapalloc_value=21511056 +HeapAlloc dt=6 heapalloc_value=21519248 +HeapAlloc dt=7 heapalloc_value=21527440 +HeapAlloc dt=6 heapalloc_value=21535632 +HeapAlloc dt=7 heapalloc_value=21543824 +HeapAlloc dt=7 heapalloc_value=21552016 +HeapAlloc dt=6 heapalloc_value=21560208 +HeapAlloc dt=7 heapalloc_value=21568400 +HeapAlloc dt=7 heapalloc_value=21576592 +HeapAlloc dt=7 heapalloc_value=21584784 +HeapAlloc dt=6 heapalloc_value=21592976 +GoBlock dt=11 reason_string=19 stack=21 +ProcStop dt=159 +ProcStart dt=1372 p=0 p_seq=51 +GoUnblock dt=19 g=1 g_seq=57 stack=0 +GoStart dt=211 g=1 g_seq=58 +HeapAlloc dt=39 heapalloc_value=21601168 +HeapAlloc dt=16 heapalloc_value=21609360 +HeapAlloc dt=8 heapalloc_value=21617552 +HeapAlloc dt=6 heapalloc_value=21625744 +HeapAlloc dt=101 heapalloc_value=21633936 +HeapAlloc dt=8 heapalloc_value=21642128 +HeapAlloc dt=7 heapalloc_value=21650320 +HeapAlloc dt=6 heapalloc_value=21658512 +HeapAlloc dt=7 heapalloc_value=21666704 +HeapAlloc dt=6 heapalloc_value=21674896 +HeapAlloc dt=6 heapalloc_value=21683088 +HeapAlloc dt=7 heapalloc_value=21691280 +HeapAlloc dt=6 heapalloc_value=21699472 +HeapAlloc dt=7 heapalloc_value=21707664 +HeapAlloc dt=6 heapalloc_value=21715856 +HeapAlloc dt=102 heapalloc_value=21724048 +HeapAlloc dt=8 heapalloc_value=21732240 +HeapAlloc dt=6 heapalloc_value=21740432 +HeapAlloc dt=7 heapalloc_value=21748624 +HeapAlloc dt=6 heapalloc_value=21756816 +HeapAlloc dt=7 heapalloc_value=21765008 +HeapAlloc dt=6 heapalloc_value=21773200 +HeapAlloc dt=7 heapalloc_value=21781392 +HeapAlloc dt=44 heapalloc_value=21789584 +HeapAlloc dt=7 heapalloc_value=21797776 +HeapAlloc dt=8 heapalloc_value=21805968 +HeapAlloc dt=7 heapalloc_value=21814160 +HeapAlloc dt=6 heapalloc_value=21822352 +HeapAlloc dt=7 heapalloc_value=21830544 +HeapAlloc dt=6 heapalloc_value=21838736 +HeapAlloc dt=7 heapalloc_value=21846928 +HeapAlloc dt=6 heapalloc_value=21855120 +HeapAlloc dt=6 heapalloc_value=21863312 +HeapAlloc dt=7 heapalloc_value=21871504 +HeapAlloc dt=6 heapalloc_value=21879696 +HeapAlloc dt=7 heapalloc_value=21887888 +HeapAlloc dt=6 heapalloc_value=21896080 +HeapAlloc dt=7 heapalloc_value=21904272 +HeapAlloc dt=6 heapalloc_value=21912464 +HeapAlloc dt=7 heapalloc_value=21920656 +HeapAlloc dt=6 heapalloc_value=21928848 +HeapAlloc dt=6 heapalloc_value=21937040 +HeapAlloc dt=7 heapalloc_value=21945232 +HeapAlloc dt=6 heapalloc_value=21953424 +HeapAlloc dt=7 heapalloc_value=21961616 +HeapAlloc dt=6 heapalloc_value=21969808 +HeapAlloc dt=7 heapalloc_value=21978000 +HeapAlloc dt=248 heapalloc_value=21986192 +HeapAlloc dt=18 heapalloc_value=21994384 +HeapAlloc dt=7 heapalloc_value=22002576 +HeapAlloc dt=6 heapalloc_value=22010768 +HeapAlloc dt=7 heapalloc_value=22018960 +HeapAlloc dt=6 heapalloc_value=22027152 +HeapAlloc dt=7 heapalloc_value=22035344 +HeapAlloc dt=6 heapalloc_value=22043536 +HeapAlloc dt=7 heapalloc_value=22051728 +HeapAlloc dt=6 heapalloc_value=22059920 +HeapAlloc dt=7 heapalloc_value=22068112 +HeapAlloc dt=16 heapalloc_value=22657936 +HeapAlloc dt=3547 heapalloc_value=22666128 +HeapAlloc dt=3135 heapalloc_value=22674320 +HeapAlloc dt=11 heapalloc_value=22682512 +HeapAlloc dt=8 heapalloc_value=22690704 +HeapAlloc dt=8 heapalloc_value=22698896 +HeapAlloc dt=8 heapalloc_value=22707088 +HeapAlloc dt=10 heapalloc_value=22715280 +HeapAlloc dt=8 heapalloc_value=22723472 +HeapAlloc dt=8 heapalloc_value=22731664 +HeapAlloc dt=71 heapalloc_value=22739856 +HeapAlloc dt=10 heapalloc_value=22748048 +HeapAlloc dt=8 heapalloc_value=22756240 +HeapAlloc dt=9 heapalloc_value=22764432 +HeapAlloc dt=8 heapalloc_value=22772624 +HeapAlloc dt=8 heapalloc_value=22780816 +HeapAlloc dt=9 heapalloc_value=22789008 +HeapAlloc dt=47 heapalloc_value=22797200 +HeapAlloc dt=9 heapalloc_value=22805392 +HeapAlloc dt=9 heapalloc_value=22813584 +HeapAlloc dt=8 heapalloc_value=22821776 +HeapAlloc dt=9 heapalloc_value=22829968 +HeapAlloc dt=17 heapalloc_value=22838160 +HeapAlloc dt=8 heapalloc_value=22846352 +HeapAlloc dt=6 heapalloc_value=22854544 +HeapAlloc dt=7 heapalloc_value=22862736 +HeapAlloc dt=6 heapalloc_value=22870928 +HeapAlloc dt=6 heapalloc_value=22879120 +HeapAlloc dt=6 heapalloc_value=22887312 +HeapAlloc dt=6 heapalloc_value=22895504 +HeapAlloc dt=7 heapalloc_value=22903696 +HeapAlloc dt=6 heapalloc_value=22911888 +HeapAlloc dt=6 heapalloc_value=22920080 +HeapAlloc dt=6 heapalloc_value=22928272 +HeapAlloc dt=6 heapalloc_value=22936464 +HeapAlloc dt=6 heapalloc_value=22944656 +HeapAlloc dt=7 heapalloc_value=22952848 +HeapAlloc dt=6 heapalloc_value=22961040 +HeapAlloc dt=8 heapalloc_value=22969232 +HeapAlloc dt=6 heapalloc_value=22977424 +HeapAlloc dt=6 heapalloc_value=22985616 +HeapAlloc dt=6 heapalloc_value=22993808 +HeapAlloc dt=43 heapalloc_value=23002000 +HeapAlloc dt=8 heapalloc_value=23010192 +HeapAlloc dt=6 heapalloc_value=23018384 +HeapAlloc dt=7 heapalloc_value=23026576 +HeapAlloc dt=76 heapalloc_value=23034768 +HeapAlloc dt=9 heapalloc_value=23042960 +HeapAlloc dt=6 heapalloc_value=23051152 +HeapAlloc dt=7 heapalloc_value=23059344 +HeapAlloc dt=6 heapalloc_value=23067536 +HeapAlloc dt=6 heapalloc_value=23075728 +HeapAlloc dt=7 heapalloc_value=23083920 +HeapAlloc dt=6 heapalloc_value=23092112 +HeapAlloc dt=6 heapalloc_value=23100304 +HeapAlloc dt=6 heapalloc_value=23108496 +HeapAlloc dt=6 heapalloc_value=23116688 +HeapAlloc dt=6 heapalloc_value=23124880 +HeapAlloc dt=7 heapalloc_value=23133072 +HeapAlloc dt=6 heapalloc_value=23141264 +HeapAlloc dt=8 heapalloc_value=23149456 +HeapAlloc dt=6 heapalloc_value=23157648 +HeapAlloc dt=6 heapalloc_value=23165840 +HeapAlloc dt=7 heapalloc_value=23174032 +HeapAlloc dt=6 heapalloc_value=23182224 +HeapAlloc dt=7 heapalloc_value=23190416 +HeapAlloc dt=6 heapalloc_value=23198608 +HeapAlloc dt=6 heapalloc_value=23206800 +HeapAlloc dt=22 heapalloc_value=23214912 +HeapAlloc dt=22 heapalloc_value=23223008 +HeapAlloc dt=21 heapalloc_value=23224960 +GoCreate dt=50 new_g=10 new_stack=49 stack=50 +GoCreate dt=193 new_g=11 new_stack=49 stack=50 +GoCreate dt=10 new_g=12 new_stack=49 stack=50 +GoCreate dt=5 new_g=13 new_stack=49 stack=50 +HeapAlloc dt=120 heapalloc_value=23232736 +GoCreate dt=9 new_g=14 new_stack=49 stack=50 +GoCreate dt=8 new_g=15 new_stack=49 stack=50 +GoCreate dt=7 new_g=16 new_stack=49 stack=50 +GoCreate dt=8 new_g=50 new_stack=49 stack=50 +GoBlock dt=17 reason_string=10 stack=51 +GoStart dt=7 g=50 g_seq=1 +GoStop dt=306070 reason_string=16 stack=52 +GoStart dt=17 g=50 g_seq=2 +GoStop dt=316463 reason_string=16 stack=52 +GoStart dt=9 g=50 g_seq=3 +GoDestroy dt=158709 +ProcStop dt=33 +ProcStart dt=9387 p=7 p_seq=3 +ProcStop dt=14 +ProcStart dt=63662 p=7 p_seq=4 +ProcStop dt=14 +ProcStart dt=16745 p=7 p_seq=5 +GoUnblock dt=39 g=19 g_seq=2 stack=0 +GoStart dt=155 g=19 g_seq=3 +HeapAlloc dt=297 heapalloc_value=23312520 +GoBlock dt=30 reason_string=12 stack=11 +ProcStop dt=28 +ProcStart dt=706341 p=7 p_seq=6 +ProcStop dt=15 +ProcStart dt=50 p=7 p_seq=7 +ProcStop dt=8 +ProcStart dt=3274 p=6 p_seq=14 +ProcStop dt=13 +ProcStart dt=2696 p=4 p_seq=6 +ProcStop dt=17 +ProcStart dt=416 p=7 p_seq=19 +GoUnblock dt=7 g=1 g_seq=64 stack=0 +GoStart dt=7 g=1 g_seq=65 +GoSyscallBegin dt=33 p_seq=20 stack=81 +GoSyscallEnd dt=43 +GoSyscallBegin dt=134 p_seq=21 stack=82 +GoSyscallEnd dt=38 +GoSyscallBegin dt=10 p_seq=22 stack=83 +GoSyscallEnd dt=40 +GoSyscallBegin dt=7 p_seq=23 stack=84 +GoSyscallEnd dt=26 +GoSyscallBegin dt=10 p_seq=24 stack=85 +GoSyscallEnd dt=31 +GoSyscallBegin dt=39 p_seq=25 stack=86 +GoSyscallEnd dt=61 +GoBlock dt=13 reason_string=7 stack=87 +ProcStop dt=15 +EventBatch gen=1 m=2852341 time=420901453987 size=3492 +ProcStart dt=448 p=3 p_seq=1 +ProcStop dt=26 +ProcStart dt=312314 p=0 p_seq=4 +ProcStop dt=17 +ProcStart dt=16776 p=0 p_seq=5 +GoUnblock dt=31 g=1 g_seq=3 stack=0 +GoStart dt=182 g=1 g_seq=4 +HeapAlloc dt=181 heapalloc_value=1662976 +HeapAlloc dt=25 heapalloc_value=1671168 +HeapAlloc dt=210 heapalloc_value=1679360 +HeapAlloc dt=19 heapalloc_value=1687552 +HeapAlloc dt=15 heapalloc_value=1695744 +HeapAlloc dt=8 heapalloc_value=1703936 +HeapAlloc dt=15 heapalloc_value=1712128 +HeapAlloc dt=7 heapalloc_value=1720320 +HeapAlloc dt=9 heapalloc_value=1728512 +HeapAlloc dt=5 heapalloc_value=1736704 +HeapAlloc dt=8 heapalloc_value=1761280 +HeapAlloc dt=9 heapalloc_value=1769472 +HeapAlloc dt=8 heapalloc_value=1777664 +HeapAlloc dt=6 heapalloc_value=1785856 +HeapAlloc dt=8 heapalloc_value=1794048 +HeapAlloc dt=6 heapalloc_value=1802240 +HeapAlloc dt=6 heapalloc_value=1810432 +HeapAlloc dt=6 heapalloc_value=1818624 +HeapAlloc dt=6 heapalloc_value=1826816 +HeapAlloc dt=5 heapalloc_value=1851392 +HeapAlloc dt=62 heapalloc_value=1859584 +HeapAlloc dt=8 heapalloc_value=1867776 +HeapAlloc dt=6 heapalloc_value=1875968 +HeapAlloc dt=6 heapalloc_value=1884160 +HeapAlloc dt=6 heapalloc_value=1892352 +HeapAlloc dt=6 heapalloc_value=1900544 +HeapAlloc dt=6 heapalloc_value=1908736 +HeapAlloc dt=6 heapalloc_value=1916928 +HeapAlloc dt=75 heapalloc_value=1925120 +HeapAlloc dt=8 heapalloc_value=1933312 +HeapAlloc dt=6 heapalloc_value=1941504 +HeapAlloc dt=7 heapalloc_value=1949696 +HeapAlloc dt=5 heapalloc_value=1957888 +HeapAlloc dt=7 heapalloc_value=1966080 +HeapAlloc dt=7 heapalloc_value=1974272 +HeapAlloc dt=6 heapalloc_value=1982464 +HeapAlloc dt=13 heapalloc_value=2007040 +HeapAlloc dt=12 heapalloc_value=2015232 +HeapAlloc dt=7 heapalloc_value=2023424 +HeapAlloc dt=6 heapalloc_value=2031616 +HeapAlloc dt=6 heapalloc_value=2039808 +HeapAlloc dt=6 heapalloc_value=2048000 +HeapAlloc dt=8 heapalloc_value=2056192 +HeapAlloc dt=6 heapalloc_value=2064384 +HeapAlloc dt=6 heapalloc_value=2072576 +HeapAlloc dt=6 heapalloc_value=2080768 +HeapAlloc dt=6 heapalloc_value=2088960 +HeapAlloc dt=6 heapalloc_value=2097152 +HeapAlloc dt=6 heapalloc_value=2105344 +HeapAlloc dt=6 heapalloc_value=2113536 +HeapAlloc dt=9 heapalloc_value=2121728 +HeapAlloc dt=5 heapalloc_value=2129920 +HeapAlloc dt=67 heapalloc_value=2138112 +HeapAlloc dt=7 heapalloc_value=2146304 +HeapAlloc dt=7 heapalloc_value=2154496 +HeapAlloc dt=5 heapalloc_value=2162688 +HeapAlloc dt=6 heapalloc_value=2170880 +HeapAlloc dt=6 heapalloc_value=2179072 +HeapAlloc dt=79 heapalloc_value=2187264 +HeapAlloc dt=8 heapalloc_value=2195456 +HeapAlloc dt=6 heapalloc_value=2203648 +HeapAlloc dt=6 heapalloc_value=2211840 +HeapAlloc dt=6 heapalloc_value=2220032 +HeapAlloc dt=6 heapalloc_value=2228224 +HeapAlloc dt=6 heapalloc_value=2236416 +HeapAlloc dt=6 heapalloc_value=2244608 +HeapAlloc dt=8 heapalloc_value=2252800 +HeapAlloc dt=6 heapalloc_value=2260992 +HeapAlloc dt=6 heapalloc_value=2269184 +HeapAlloc dt=5 heapalloc_value=2310144 +HeapAlloc dt=19 heapalloc_value=2318336 +HeapAlloc dt=6 heapalloc_value=2326528 +HeapAlloc dt=7 heapalloc_value=2334720 +HeapAlloc dt=6 heapalloc_value=2342912 +HeapAlloc dt=6 heapalloc_value=2351104 +HeapAlloc dt=43 heapalloc_value=2359296 +HeapAlloc dt=8 heapalloc_value=2367488 +HeapAlloc dt=6 heapalloc_value=2375680 +HeapAlloc dt=8 heapalloc_value=2383872 +HeapAlloc dt=6 heapalloc_value=2392064 +HeapAlloc dt=6 heapalloc_value=2400256 +HeapAlloc dt=6 heapalloc_value=2408448 +HeapAlloc dt=6 heapalloc_value=2416640 +HeapAlloc dt=6 heapalloc_value=2424832 +HeapAlloc dt=6 heapalloc_value=2433024 +HeapAlloc dt=90 heapalloc_value=2441216 +HeapAlloc dt=74 heapalloc_value=2449408 +HeapAlloc dt=7 heapalloc_value=2457600 +HeapAlloc dt=7 heapalloc_value=2465792 +HeapAlloc dt=5 heapalloc_value=2473984 +HeapAlloc dt=6 heapalloc_value=2482176 +HeapAlloc dt=6 heapalloc_value=2490368 +HeapAlloc dt=6 heapalloc_value=2498560 +HeapAlloc dt=6 heapalloc_value=2506752 +HeapAlloc dt=8 heapalloc_value=2514944 +HeapAlloc dt=6 heapalloc_value=2523136 +HeapAlloc dt=7 heapalloc_value=2531328 +HeapAlloc dt=6 heapalloc_value=2539520 +HeapAlloc dt=6 heapalloc_value=2547712 +HeapAlloc dt=6 heapalloc_value=2555904 +HeapAlloc dt=6 heapalloc_value=2564096 +HeapAlloc dt=6 heapalloc_value=2572288 +HeapAlloc dt=8 heapalloc_value=2580480 +HeapAlloc dt=6 heapalloc_value=2588672 +HeapAlloc dt=28 heapalloc_value=2596864 +HeapAlloc dt=8 heapalloc_value=2605056 +HeapAlloc dt=5 heapalloc_value=2613248 +HeapAlloc dt=6 heapalloc_value=2621440 +HeapAlloc dt=6 heapalloc_value=2629632 +HeapAlloc dt=7 heapalloc_value=2637824 +HeapAlloc dt=8 heapalloc_value=2646016 +HeapAlloc dt=6 heapalloc_value=2654208 +HeapAlloc dt=13 heapalloc_value=2686976 +HeapAlloc dt=23 heapalloc_value=2695168 +HeapAlloc dt=6 heapalloc_value=2703360 +HeapAlloc dt=75 heapalloc_value=2711552 +HeapAlloc dt=55 heapalloc_value=2719744 +HeapAlloc dt=8 heapalloc_value=2727936 +HeapAlloc dt=6 heapalloc_value=2736128 +HeapAlloc dt=6 heapalloc_value=2744320 +HeapAlloc dt=6 heapalloc_value=2752512 +HeapAlloc dt=6 heapalloc_value=2760704 +HeapAlloc dt=6 heapalloc_value=2768896 +HeapAlloc dt=9 heapalloc_value=2777088 +HeapAlloc dt=5 heapalloc_value=2785280 +HeapAlloc dt=6 heapalloc_value=2793472 +HeapAlloc dt=6 heapalloc_value=2801664 +HeapAlloc dt=6 heapalloc_value=2809856 +HeapAlloc dt=6 heapalloc_value=2818048 +HeapAlloc dt=6 heapalloc_value=2826240 +HeapAlloc dt=6 heapalloc_value=2834432 +GoBlock dt=19 reason_string=19 stack=21 +ProcStop dt=236 +ProcStart dt=17547 p=1 p_seq=2 +ProcStop dt=18 +ProcStart dt=5588 p=0 p_seq=8 +ProcStop dt=13 +ProcStart dt=16789 p=0 p_seq=9 +GoUnblock dt=17 g=1 g_seq=7 stack=0 +GoStart dt=173 g=1 g_seq=8 +HeapAlloc dt=54 heapalloc_value=3915776 +HeapAlloc dt=17 heapalloc_value=3923968 +HeapAlloc dt=6 heapalloc_value=3932160 +HeapAlloc dt=6 heapalloc_value=3940352 +HeapAlloc dt=8 heapalloc_value=3948544 +HeapAlloc dt=10 heapalloc_value=3956736 +HeapAlloc dt=7 heapalloc_value=3964928 +HeapAlloc dt=10 heapalloc_value=4038656 +GCBegin dt=207 gc_seq=1 stack=22 +GoCreate dt=117 new_g=5 new_stack=23 stack=24 +GoSyscallBegin dt=172 p_seq=10 stack=25 +ProcStop dt=2 +ProcStart dt=6567 p=0 p_seq=12 +GoSyscallEndBlocked dt=4 +GoStart dt=1 g=1 g_seq=9 +GoCreate dt=36 new_g=6 new_stack=23 stack=24 +GoSyscallBegin dt=11 p_seq=13 stack=25 +ProcStop dt=1 +ProcStart dt=815 p=0 p_seq=15 +GoSyscallEndBlocked dt=2 +GoStart dt=1 g=1 g_seq=10 +GoCreate dt=23 new_g=7 new_stack=23 stack=24 +GoSyscallBegin dt=4 p_seq=16 stack=25 +ProcStop dt=1 +ProcStart dt=814 p=1 p_seq=6 +GoSyscallEndBlocked dt=2 +GoStart dt=1 g=1 g_seq=11 +GoCreate dt=14 new_g=24 new_stack=23 stack=24 +GoSyscallBegin dt=122 p_seq=7 stack=25 +ProcStop dt=1 +ProcStart dt=519 p=2 p_seq=5 +GoSyscallEndBlocked dt=1 +GoStart dt=1 g=1 g_seq=12 +HeapAlloc dt=19 heapalloc_value=4063232 +GoCreate dt=21 new_g=34 new_stack=23 stack=24 +GoSyscallBegin dt=5 p_seq=6 stack=25 +ProcStop dt=1 +ProcStart dt=924 p=0 p_seq=19 +GoSyscallEndBlocked dt=1 +GoStart dt=1 g=1 g_seq=13 +GoCreate dt=19 new_g=8 new_stack=23 stack=24 +GoSyscallBegin dt=140 p_seq=20 stack=25 +ProcStop dt=2 +ProcStart dt=512 p=0 p_seq=22 +GoSyscallEndBlocked dt=1 +GoStart dt=1 g=1 g_seq=14 +GoCreate dt=14 new_g=9 new_stack=23 stack=24 +GoSyscallBegin dt=3 p_seq=23 stack=25 +ProcStop dt=1 +ProcStart dt=375 p=1 p_seq=12 +GoSyscallEndBlocked dt=2 +GoStart dt=1 g=1 g_seq=15 +HeapAlloc dt=36 heapalloc_value=4071424 +GoCreate dt=13 new_g=25 new_stack=23 stack=24 +GoSyscallBegin dt=115 p_seq=13 stack=25 +ProcStop dt=1 +ProcStart dt=623 p=2 p_seq=10 +GoSyscallEndBlocked dt=1 +GoStart dt=1 g=1 g_seq=16 +STWBegin dt=37 kind_string=22 stack=27 +GoStatus dt=138 g=4 m=18446744073709551615 gstatus=4 +GoUnblock dt=7 g=4 g_seq=1 stack=28 +ProcsChange dt=158 procs_value=8 stack=29 +STWEnd dt=25 +GCMarkAssistBegin dt=1078 stack=30 +GCMarkAssistEnd dt=684 +HeapAlloc dt=15 heapalloc_value=4087808 +HeapAlloc dt=21 heapalloc_value=4096000 +HeapAlloc dt=11 heapalloc_value=4104192 +HeapAlloc dt=9 heapalloc_value=4112384 +HeapAlloc dt=9 heapalloc_value=4120576 +HeapAlloc dt=736 heapalloc_value=4145152 +HeapAlloc dt=27 heapalloc_value=4153344 +HeapAlloc dt=19 heapalloc_value=4161536 +HeapAlloc dt=15 heapalloc_value=4169728 +HeapAlloc dt=19 heapalloc_value=4177920 +HeapAlloc dt=15 heapalloc_value=4186112 +HeapAlloc dt=11 heapalloc_value=4194304 +HeapAlloc dt=16 heapalloc_value=4202496 +HeapAlloc dt=16 heapalloc_value=4210688 +HeapAlloc dt=9 heapalloc_value=4218880 +HeapAlloc dt=9 heapalloc_value=4227072 +HeapAlloc dt=9 heapalloc_value=4235264 +HeapAlloc dt=9 heapalloc_value=4243456 +HeapAlloc dt=10 heapalloc_value=4251648 +HeapAlloc dt=9 heapalloc_value=4259840 +HeapAlloc dt=20 heapalloc_value=4268032 +GoStop dt=11 reason_string=16 stack=31 +GoStart dt=361 g=1 g_seq=17 +HeapAlloc dt=16 heapalloc_value=4276224 +HeapAlloc dt=10 heapalloc_value=4284416 +HeapAlloc dt=9 heapalloc_value=4292608 +HeapAlloc dt=10 heapalloc_value=4300800 +HeapAlloc dt=9 heapalloc_value=4308992 +HeapAlloc dt=10 heapalloc_value=4317184 +HeapAlloc dt=9 heapalloc_value=4325376 +HeapAlloc dt=9 heapalloc_value=4333568 +HeapAlloc dt=11 heapalloc_value=4341760 +HeapAlloc dt=9 heapalloc_value=4349952 +HeapAlloc dt=67 heapalloc_value=4358144 +HeapAlloc dt=10 heapalloc_value=4366336 +HeapAlloc dt=10 heapalloc_value=4374528 +HeapAlloc dt=9 heapalloc_value=4382720 +HeapAlloc dt=9 heapalloc_value=4390912 +HeapAlloc dt=9 heapalloc_value=4399104 +HeapAlloc dt=283 heapalloc_value=4407296 +HeapAlloc dt=15 heapalloc_value=4415488 +HeapAlloc dt=7 heapalloc_value=4423680 +HeapAlloc dt=7 heapalloc_value=4431872 +HeapAlloc dt=7 heapalloc_value=4440064 +HeapAlloc dt=7 heapalloc_value=4448256 +HeapAlloc dt=7 heapalloc_value=4456448 +HeapAlloc dt=7 heapalloc_value=4464640 +HeapAlloc dt=7 heapalloc_value=4472832 +HeapAlloc dt=7 heapalloc_value=4481024 +HeapAlloc dt=7 heapalloc_value=4489216 +HeapAlloc dt=7 heapalloc_value=4497408 +HeapAlloc dt=7 heapalloc_value=4505600 +HeapAlloc dt=6 heapalloc_value=4513792 +HeapAlloc dt=7 heapalloc_value=4521984 +HeapAlloc dt=39 heapalloc_value=4530176 +HeapAlloc dt=8 heapalloc_value=4538368 +HeapAlloc dt=8 heapalloc_value=4546560 +HeapAlloc dt=7 heapalloc_value=4554752 +HeapAlloc dt=7 heapalloc_value=4562944 +HeapAlloc dt=10 heapalloc_value=4571136 +HeapAlloc dt=9 heapalloc_value=4579328 +HeapAlloc dt=72 heapalloc_value=4587520 +HeapAlloc dt=9 heapalloc_value=4595712 +HeapAlloc dt=7 heapalloc_value=4603904 +HeapAlloc dt=7 heapalloc_value=4612096 +HeapAlloc dt=7 heapalloc_value=4620288 +HeapAlloc dt=7 heapalloc_value=4628480 +HeapAlloc dt=7 heapalloc_value=4636672 +HeapAlloc dt=7 heapalloc_value=4644864 +HeapAlloc dt=8 heapalloc_value=4653056 +HeapAlloc dt=7 heapalloc_value=4661248 +HeapAlloc dt=266 heapalloc_value=4669440 +HeapAlloc dt=9 heapalloc_value=4677632 +HeapAlloc dt=50 heapalloc_value=4685824 +HeapAlloc dt=9 heapalloc_value=4694016 +HeapAlloc dt=7 heapalloc_value=4702208 +HeapAlloc dt=8 heapalloc_value=4710400 +HeapAlloc dt=7 heapalloc_value=4718592 +HeapAlloc dt=7 heapalloc_value=4726784 +HeapAlloc dt=7 heapalloc_value=4734976 +HeapAlloc dt=7 heapalloc_value=4743168 +GCMarkAssistBegin dt=9 stack=30 +HeapAlloc dt=40 heapalloc_value=4751360 +GoBlock dt=247 reason_string=10 stack=33 +ProcStop dt=18 +ProcStart dt=5438 p=2 p_seq=11 +ProcStop dt=22 +ProcStart dt=70608 p=2 p_seq=12 +GoUnblock dt=18 g=25 g_seq=4 stack=0 +GoStart dt=190 g=25 g_seq=5 +GoLabel dt=1 label_string=2 +GoBlock dt=594 reason_string=15 stack=26 +ProcStop dt=28 +ProcStart dt=802 p=2 p_seq=13 +ProcStop dt=17 +ProcStart dt=2684 p=2 p_seq=14 +ProcStop dt=29 +ProcStart dt=382 p=2 p_seq=15 +ProcStop dt=51 +ProcStart dt=2622 p=2 p_seq=16 +ProcStop dt=22 +ProcStart dt=66146 p=2 p_seq=17 +ProcStop dt=20 +ProcStart dt=49429 p=0 p_seq=40 +GoUnblock dt=13 g=9 g_seq=7 stack=0 +GoStart dt=174 g=9 g_seq=8 +GoLabel dt=1 label_string=2 +GoBlock dt=1963 reason_string=15 stack=26 +ProcStop dt=4345 +ProcStart dt=16958 p=2 p_seq=22 +ProcStop dt=18 +ProcStart dt=723 p=0 p_seq=42 +ProcStop dt=10 +ProcStart dt=16754 p=0 p_seq=43 +GoUnblock dt=14 g=1 g_seq=49 stack=0 +GoStart dt=152 g=1 g_seq=50 +HeapAlloc dt=32 heapalloc_value=17038224 +HeapAlloc dt=24 heapalloc_value=17046416 +HeapAlloc dt=15 heapalloc_value=17054608 +HeapAlloc dt=16 heapalloc_value=17062800 +HeapAlloc dt=13 heapalloc_value=17070992 +HeapAlloc dt=14 heapalloc_value=17079184 +HeapAlloc dt=17 heapalloc_value=17087376 +HeapAlloc dt=14 heapalloc_value=17095568 +HeapAlloc dt=14 heapalloc_value=17103760 +HeapAlloc dt=13 heapalloc_value=17111952 +HeapAlloc dt=81 heapalloc_value=17120144 +HeapAlloc dt=20 heapalloc_value=17128336 +HeapAlloc dt=14 heapalloc_value=17136528 +HeapAlloc dt=14 heapalloc_value=17144720 +HeapAlloc dt=16 heapalloc_value=17152912 +HeapAlloc dt=15 heapalloc_value=17161104 +HeapAlloc dt=13 heapalloc_value=17169296 +HeapAlloc dt=13 heapalloc_value=17177488 +HeapAlloc dt=16 heapalloc_value=17185680 +HeapAlloc dt=15 heapalloc_value=17193872 +HeapAlloc dt=14 heapalloc_value=17202064 +HeapAlloc dt=13 heapalloc_value=17210256 +HeapAlloc dt=16 heapalloc_value=17218448 +HeapAlloc dt=14 heapalloc_value=17226640 +HeapAlloc dt=14 heapalloc_value=17234832 +HeapAlloc dt=16 heapalloc_value=17243024 +HeapAlloc dt=16 heapalloc_value=17251216 +HeapAlloc dt=15 heapalloc_value=17259408 +HeapAlloc dt=14 heapalloc_value=17267600 +HeapAlloc dt=13 heapalloc_value=17275792 +HeapAlloc dt=45 heapalloc_value=17283984 +HeapAlloc dt=18 heapalloc_value=17292176 +HeapAlloc dt=16 heapalloc_value=17300368 +HeapAlloc dt=16 heapalloc_value=17308560 +HeapAlloc dt=15 heapalloc_value=17316752 +HeapAlloc dt=17 heapalloc_value=17324944 +HeapAlloc dt=15 heapalloc_value=17333136 +HeapAlloc dt=14 heapalloc_value=17341328 +HeapAlloc dt=16 heapalloc_value=17349520 +HeapAlloc dt=14 heapalloc_value=17357712 +HeapAlloc dt=14 heapalloc_value=17365904 +HeapAlloc dt=12 heapalloc_value=17374096 +HeapAlloc dt=14 heapalloc_value=17382288 +HeapAlloc dt=13 heapalloc_value=17390480 +HeapAlloc dt=13 heapalloc_value=17398672 +HeapAlloc dt=13 heapalloc_value=17406864 +HeapAlloc dt=36 heapalloc_value=17873808 +HeapAlloc dt=3813 heapalloc_value=17882000 +HeapAlloc dt=47 heapalloc_value=17890192 +HeapAlloc dt=10 heapalloc_value=17898384 +HeapAlloc dt=10 heapalloc_value=17906576 +HeapAlloc dt=12 heapalloc_value=17914768 +HeapAlloc dt=21 heapalloc_value=17922960 +HeapAlloc dt=17 heapalloc_value=17931152 +HeapAlloc dt=12 heapalloc_value=17939344 +HeapAlloc dt=13 heapalloc_value=17947536 +HeapAlloc dt=24 heapalloc_value=17955728 +HeapAlloc dt=91 heapalloc_value=17963920 +HeapAlloc dt=11 heapalloc_value=17972112 +HeapAlloc dt=9 heapalloc_value=17980304 +HeapAlloc dt=11 heapalloc_value=17988496 +HeapAlloc dt=8 heapalloc_value=17996688 +HeapAlloc dt=9 heapalloc_value=18004880 +HeapAlloc dt=9 heapalloc_value=18013072 +HeapAlloc dt=10 heapalloc_value=18021264 +HeapAlloc dt=9 heapalloc_value=18029456 +HeapAlloc dt=9 heapalloc_value=18037648 +HeapAlloc dt=8 heapalloc_value=18045840 +HeapAlloc dt=11 heapalloc_value=18054032 +HeapAlloc dt=8 heapalloc_value=18062224 +HeapAlloc dt=9 heapalloc_value=18070416 +HeapAlloc dt=9 heapalloc_value=18078608 +HeapAlloc dt=8 heapalloc_value=18086800 +HeapAlloc dt=9 heapalloc_value=18094992 +HeapAlloc dt=9 heapalloc_value=18103184 +HeapAlloc dt=8 heapalloc_value=18111376 +HeapAlloc dt=11 heapalloc_value=18119568 +HeapAlloc dt=9 heapalloc_value=18127760 +HeapAlloc dt=52 heapalloc_value=18135952 +HeapAlloc dt=10 heapalloc_value=18144144 +HeapAlloc dt=12 heapalloc_value=18152336 +HeapAlloc dt=10 heapalloc_value=18160528 +HeapAlloc dt=10 heapalloc_value=18168720 +HeapAlloc dt=25 heapalloc_value=18176912 +HeapAlloc dt=37 heapalloc_value=18185104 +HeapAlloc dt=32 heapalloc_value=18193296 +HeapAlloc dt=27 heapalloc_value=18201488 +HeapAlloc dt=27 heapalloc_value=18209680 +HeapAlloc dt=29 heapalloc_value=18217872 +HeapAlloc dt=28 heapalloc_value=18226064 +HeapAlloc dt=22 heapalloc_value=18234256 +HeapAlloc dt=32 heapalloc_value=18242448 +HeapAlloc dt=30 heapalloc_value=18250640 +HeapAlloc dt=26 heapalloc_value=18258832 +HeapAlloc dt=30 heapalloc_value=18267024 +HeapAlloc dt=33 heapalloc_value=18275216 +HeapAlloc dt=27 heapalloc_value=18283408 +HeapAlloc dt=33 heapalloc_value=18291600 +HeapAlloc dt=25 heapalloc_value=18299792 +HeapAlloc dt=40 heapalloc_value=18307984 +HeapAlloc dt=23 heapalloc_value=18316176 +HeapAlloc dt=32 heapalloc_value=18324368 +HeapAlloc dt=31 heapalloc_value=18332560 +HeapAlloc dt=30 heapalloc_value=18340752 +HeapAlloc dt=25 heapalloc_value=18348944 +HeapAlloc dt=32 heapalloc_value=18357136 +HeapAlloc dt=30 heapalloc_value=18365328 +HeapAlloc dt=32 heapalloc_value=18373520 +HeapAlloc dt=34 heapalloc_value=18381712 +HeapAlloc dt=30 heapalloc_value=18389904 +HeapAlloc dt=31 heapalloc_value=18398096 +HeapAlloc dt=29 heapalloc_value=18406288 +HeapAlloc dt=29 heapalloc_value=18414480 +HeapAlloc dt=29 heapalloc_value=18422672 +HeapAlloc dt=28 heapalloc_value=18430864 +HeapAlloc dt=35 heapalloc_value=18439056 +HeapAlloc dt=31 heapalloc_value=18447248 +HeapAlloc dt=30 heapalloc_value=18455440 +HeapAlloc dt=116 heapalloc_value=18463632 +HeapAlloc dt=21 heapalloc_value=18471824 +HeapAlloc dt=13 heapalloc_value=18480016 +HeapAlloc dt=65 heapalloc_value=18488208 +HeapAlloc dt=21 heapalloc_value=18496400 +HeapAlloc dt=16 heapalloc_value=18504592 +HeapAlloc dt=14 heapalloc_value=18512784 +HeapAlloc dt=13 heapalloc_value=18520976 +GoBlock dt=19 reason_string=19 stack=21 +ProcStop dt=197 +ProcStart dt=17439 p=2 p_seq=24 +ProcStop dt=12 +ProcStart dt=2355 p=0 p_seq=46 +ProcStop dt=8 +ProcStart dt=16730 p=0 p_seq=47 +GoUnblock dt=11 g=1 g_seq=53 stack=0 +GoStart dt=144 g=1 g_seq=54 +HeapAlloc dt=26 heapalloc_value=19553168 +HeapAlloc dt=13 heapalloc_value=19561360 +HeapAlloc dt=8 heapalloc_value=19569552 +HeapAlloc dt=6 heapalloc_value=19577744 +HeapAlloc dt=7 heapalloc_value=19585936 +HeapAlloc dt=7 heapalloc_value=19594128 +HeapAlloc dt=69 heapalloc_value=19602320 +HeapAlloc dt=7 heapalloc_value=19610512 +HeapAlloc dt=7 heapalloc_value=19618704 +HeapAlloc dt=250 heapalloc_value=19626896 +HeapAlloc dt=9 heapalloc_value=19635088 +HeapAlloc dt=7 heapalloc_value=19643280 +HeapAlloc dt=7 heapalloc_value=19651472 +HeapAlloc dt=7 heapalloc_value=19659664 +HeapAlloc dt=7 heapalloc_value=19667856 +HeapAlloc dt=7 heapalloc_value=19676048 +HeapAlloc dt=7 heapalloc_value=19684240 +HeapAlloc dt=6 heapalloc_value=19692432 +HeapAlloc dt=8 heapalloc_value=19700624 +HeapAlloc dt=6 heapalloc_value=19708816 +HeapAlloc dt=7 heapalloc_value=19717008 +HeapAlloc dt=7 heapalloc_value=19725200 +HeapAlloc dt=6 heapalloc_value=19733392 +HeapAlloc dt=7 heapalloc_value=19741584 +HeapAlloc dt=7 heapalloc_value=19749776 +HeapAlloc dt=6 heapalloc_value=19757968 +HeapAlloc dt=7 heapalloc_value=19766160 +HeapAlloc dt=7 heapalloc_value=19774352 +HeapAlloc dt=6 heapalloc_value=19782544 +HeapAlloc dt=7 heapalloc_value=19790736 +HeapAlloc dt=7 heapalloc_value=19798928 +HeapAlloc dt=6 heapalloc_value=19807120 +HeapAlloc dt=48 heapalloc_value=19815312 +HeapAlloc dt=8 heapalloc_value=19823504 +HeapAlloc dt=6 heapalloc_value=19831696 +HeapAlloc dt=7 heapalloc_value=19839888 +HeapAlloc dt=6 heapalloc_value=19848080 +HeapAlloc dt=7 heapalloc_value=19856272 +HeapAlloc dt=7 heapalloc_value=19864464 +HeapAlloc dt=7 heapalloc_value=19872656 +HeapAlloc dt=6 heapalloc_value=19880848 +HeapAlloc dt=70 heapalloc_value=19889040 +HeapAlloc dt=8 heapalloc_value=19897232 +HeapAlloc dt=7 heapalloc_value=19905424 +HeapAlloc dt=8 heapalloc_value=19913616 +HeapAlloc dt=9 heapalloc_value=19921808 +HeapAlloc dt=6 heapalloc_value=19930000 +HeapAlloc dt=7 heapalloc_value=19938192 +HeapAlloc dt=6 heapalloc_value=19946384 +HeapAlloc dt=7 heapalloc_value=19954576 +HeapAlloc dt=7 heapalloc_value=19962768 +HeapAlloc dt=6 heapalloc_value=19970960 +HeapAlloc dt=7 heapalloc_value=19979152 +HeapAlloc dt=7 heapalloc_value=19987344 +HeapAlloc dt=6 heapalloc_value=19995536 +HeapAlloc dt=7 heapalloc_value=20003728 +HeapAlloc dt=6 heapalloc_value=20011920 +HeapAlloc dt=7 heapalloc_value=20020112 +HeapAlloc dt=7 heapalloc_value=20028304 +HeapAlloc dt=7 heapalloc_value=20036496 +HeapAlloc dt=7 heapalloc_value=20044688 +HeapAlloc dt=6 heapalloc_value=20052880 +HeapAlloc dt=177 heapalloc_value=20061072 +HeapAlloc dt=8 heapalloc_value=20069264 +HeapAlloc dt=7 heapalloc_value=20077456 +HeapAlloc dt=7 heapalloc_value=20085648 +HeapAlloc dt=6 heapalloc_value=20093840 +HeapAlloc dt=7 heapalloc_value=20102032 +HeapAlloc dt=7 heapalloc_value=20110224 +HeapAlloc dt=46 heapalloc_value=20118416 +HeapAlloc dt=8 heapalloc_value=20126608 +HeapAlloc dt=6 heapalloc_value=20134800 +HeapAlloc dt=7 heapalloc_value=20142992 +HeapAlloc dt=494 heapalloc_value=20151184 +HeapAlloc dt=13 heapalloc_value=20159376 +HeapAlloc dt=8 heapalloc_value=20167568 +HeapAlloc dt=6 heapalloc_value=20175760 +HeapAlloc dt=93 heapalloc_value=20183952 +HeapAlloc dt=7 heapalloc_value=20192144 +HeapAlloc dt=6 heapalloc_value=20200336 +HeapAlloc dt=7 heapalloc_value=20208528 +HeapAlloc dt=7 heapalloc_value=20216720 +HeapAlloc dt=6 heapalloc_value=20224912 +HeapAlloc dt=46 heapalloc_value=20233104 +HeapAlloc dt=8 heapalloc_value=20241296 +HeapAlloc dt=6 heapalloc_value=20249488 +HeapAlloc dt=7 heapalloc_value=20257680 +HeapAlloc dt=7 heapalloc_value=20265872 +HeapAlloc dt=6 heapalloc_value=20274064 +HeapAlloc dt=7 heapalloc_value=20282256 +HeapAlloc dt=7 heapalloc_value=20290448 +HeapAlloc dt=7 heapalloc_value=20298640 +HeapAlloc dt=6 heapalloc_value=20306832 +HeapAlloc dt=7 heapalloc_value=20315024 +HeapAlloc dt=6 heapalloc_value=20323216 +HeapAlloc dt=7 heapalloc_value=20331408 +HeapAlloc dt=6 heapalloc_value=20339600 +HeapAlloc dt=7 heapalloc_value=20347792 +HeapAlloc dt=7 heapalloc_value=20355984 +HeapAlloc dt=6 heapalloc_value=20364176 +HeapAlloc dt=7 heapalloc_value=20372368 +HeapAlloc dt=7 heapalloc_value=20380560 +HeapAlloc dt=6 heapalloc_value=20388752 +HeapAlloc dt=7 heapalloc_value=20396944 +HeapAlloc dt=7 heapalloc_value=20405136 +HeapAlloc dt=68 heapalloc_value=20413328 +HeapAlloc dt=8 heapalloc_value=20421520 +HeapAlloc dt=6 heapalloc_value=20429712 +HeapAlloc dt=7 heapalloc_value=20437904 +HeapAlloc dt=7 heapalloc_value=20446096 +HeapAlloc dt=6 heapalloc_value=20454288 +HeapAlloc dt=7 heapalloc_value=20462480 +HeapAlloc dt=7 heapalloc_value=20470672 +HeapAlloc dt=7 heapalloc_value=20478864 +HeapAlloc dt=6 heapalloc_value=20487056 +HeapAlloc dt=7 heapalloc_value=20495248 +HeapAlloc dt=7 heapalloc_value=20503440 +HeapAlloc dt=6 heapalloc_value=20511632 +HeapAlloc dt=7 heapalloc_value=20519824 +HeapAlloc dt=7 heapalloc_value=20528016 +HeapAlloc dt=6 heapalloc_value=20536208 +HeapAlloc dt=7 heapalloc_value=20544400 +HeapAlloc dt=7 heapalloc_value=20552592 +HeapAlloc dt=6 heapalloc_value=20560784 +HeapAlloc dt=7 heapalloc_value=20568976 +GoBlock dt=13 reason_string=19 stack=21 +ProcStop dt=190 +ProcStart dt=17383 p=2 p_seq=26 +ProcStop dt=13 +ProcStart dt=1688 p=0 p_seq=50 +ProcStop dt=9 +ProcStart dt=16778 p=7 p_seq=1 +GoStart dt=16 g=12 g_seq=1 +GoStop dt=300490 reason_string=16 stack=52 +GoStart dt=19 g=12 g_seq=2 +GoStop dt=316380 reason_string=16 stack=52 +GoStart dt=17 g=12 g_seq=3 +GoDestroy dt=164357 +ProcStop dt=28 +ProcStart dt=1828 p=7 p_seq=2 +ProcStop dt=17 +ProcStart dt=81856 p=5 p_seq=4 +ProcStop dt=18 +ProcStart dt=688851 p=6 p_seq=10 +ProcStop dt=18 +ProcStart dt=16754 p=6 p_seq=11 +HeapAlloc dt=31 heapalloc_value=23313224 +GoCreate dt=50 new_g=67 new_stack=64 stack=0 +GoStart dt=169 g=67 g_seq=1 +GoSyscallBegin dt=30 p_seq=12 stack=65 +GoSyscallEnd dt=257 +GoDestroy dt=6 +ProcStop dt=8 +ProcStart dt=1281 p=6 p_seq=13 +ProcStop dt=20 +ProcStart dt=3460 p=6 p_seq=15 +GoStart dt=1376 g=82 g_seq=1 +GoSyscallBegin dt=34 p_seq=16 stack=79 +GoSyscallEnd dt=172 +HeapAlloc dt=3741 heapalloc_value=23466520 +HeapAlloc dt=37 heapalloc_value=23474712 +GoSyscallBegin dt=381 p_seq=17 stack=88 +GoSyscallEnd dt=29 +GoSyscallBegin dt=9 p_seq=18 stack=89 +GoSyscallEnd dt=33 +GoSyscallBegin dt=6 p_seq=19 stack=90 +GoSyscallEnd dt=20 +GoSyscallBegin dt=5 p_seq=20 stack=91 +GoSyscallEnd dt=25 +GoBlock dt=19 reason_string=19 stack=92 +ProcStop dt=69 +ProcStart dt=17618 p=7 p_seq=26 +ProcStop dt=33 +ProcStart dt=468 p=7 p_seq=27 +GoUnblock dt=5 g=1 g_seq=66 stack=0 +GoStart dt=5 g=1 g_seq=67 +GoSyscallBegin dt=14 p_seq=28 stack=86 +GoSyscallEnd dt=70 +GoSyscallBegin dt=82 p_seq=29 stack=95 +GoSyscallEnd dt=579 +HeapAlloc dt=276 heapalloc_value=23482840 +EventBatch gen=1 m=2852340 time=420901451500 size=3466 +ProcStart dt=290 p=0 p_seq=1 +GoStart dt=264 g=19 g_seq=1 +GoBlock dt=542 reason_string=12 stack=11 +GoStart dt=20 g=20 g_seq=1 +GoBlock dt=922 reason_string=12 stack=16 +GoStart dt=19 g=22 g_seq=1 +GoDestroy dt=156281 +ProcStop dt=46 +ProcStart dt=66693 p=0 p_seq=2 +ProcStop dt=20 +ProcStart dt=89853 p=0 p_seq=3 +ProcStop dt=20 +ProcStart dt=17575 p=1 p_seq=1 +ProcStop dt=20 +ProcStart dt=2159 p=0 p_seq=6 +ProcStop dt=13 +ProcStart dt=16751 p=0 p_seq=7 +GoUnblock dt=32 g=1 g_seq=5 stack=0 +GoStart dt=182 g=1 g_seq=6 +HeapAlloc dt=62 heapalloc_value=2842624 +HeapAlloc dt=25 heapalloc_value=2850816 +HeapAlloc dt=14 heapalloc_value=2859008 +HeapAlloc dt=11 heapalloc_value=2867200 +HeapAlloc dt=8 heapalloc_value=2875392 +HeapAlloc dt=9 heapalloc_value=2883584 +HeapAlloc dt=9 heapalloc_value=2891776 +HeapAlloc dt=8 heapalloc_value=2899968 +HeapAlloc dt=11 heapalloc_value=2908160 +HeapAlloc dt=102 heapalloc_value=2916352 +HeapAlloc dt=10 heapalloc_value=2924544 +HeapAlloc dt=13 heapalloc_value=2932736 +HeapAlloc dt=7 heapalloc_value=2940928 +HeapAlloc dt=8 heapalloc_value=2949120 +HeapAlloc dt=9 heapalloc_value=2957312 +HeapAlloc dt=8 heapalloc_value=2965504 +HeapAlloc dt=90 heapalloc_value=2973696 +HeapAlloc dt=9 heapalloc_value=2981888 +HeapAlloc dt=7 heapalloc_value=2990080 +HeapAlloc dt=8 heapalloc_value=2998272 +HeapAlloc dt=7 heapalloc_value=3006464 +HeapAlloc dt=6 heapalloc_value=3014656 +HeapAlloc dt=48 heapalloc_value=3022848 +HeapAlloc dt=7 heapalloc_value=3031040 +HeapAlloc dt=9 heapalloc_value=3039232 +HeapAlloc dt=6 heapalloc_value=3047424 +HeapAlloc dt=7 heapalloc_value=3055616 +HeapAlloc dt=8 heapalloc_value=3063808 +HeapAlloc dt=7 heapalloc_value=3072000 +HeapAlloc dt=7 heapalloc_value=3080192 +HeapAlloc dt=6 heapalloc_value=3088384 +HeapAlloc dt=7 heapalloc_value=3096576 +HeapAlloc dt=8 heapalloc_value=3104768 +HeapAlloc dt=8 heapalloc_value=3112960 +HeapAlloc dt=6 heapalloc_value=3121152 +HeapAlloc dt=7 heapalloc_value=3129344 +HeapAlloc dt=6 heapalloc_value=3137536 +HeapAlloc dt=6 heapalloc_value=3145728 +HeapAlloc dt=7 heapalloc_value=3153920 +HeapAlloc dt=6 heapalloc_value=3162112 +HeapAlloc dt=9 heapalloc_value=3170304 +HeapAlloc dt=6 heapalloc_value=3178496 +HeapAlloc dt=6 heapalloc_value=3186688 +HeapAlloc dt=7 heapalloc_value=3194880 +HeapAlloc dt=6 heapalloc_value=3203072 +HeapAlloc dt=7 heapalloc_value=3211264 +HeapAlloc dt=730 heapalloc_value=3260416 +HeapAlloc dt=3100 heapalloc_value=3268608 +HeapAlloc dt=18 heapalloc_value=3276800 +HeapAlloc dt=102 heapalloc_value=3284992 +HeapAlloc dt=9 heapalloc_value=3293184 +HeapAlloc dt=7 heapalloc_value=3301376 +HeapAlloc dt=6 heapalloc_value=3309568 +HeapAlloc dt=7 heapalloc_value=3317760 +HeapAlloc dt=6 heapalloc_value=3325952 +HeapAlloc dt=6 heapalloc_value=3334144 +HeapAlloc dt=7 heapalloc_value=3342336 +HeapAlloc dt=6 heapalloc_value=3350528 +HeapAlloc dt=7 heapalloc_value=3358720 +HeapAlloc dt=6 heapalloc_value=3366912 +HeapAlloc dt=44 heapalloc_value=3375104 +HeapAlloc dt=8 heapalloc_value=3383296 +HeapAlloc dt=6 heapalloc_value=3391488 +HeapAlloc dt=7 heapalloc_value=3399680 +HeapAlloc dt=6 heapalloc_value=3407872 +HeapAlloc dt=7 heapalloc_value=3416064 +HeapAlloc dt=7 heapalloc_value=3424256 +HeapAlloc dt=6 heapalloc_value=3432448 +HeapAlloc dt=6 heapalloc_value=3440640 +HeapAlloc dt=7 heapalloc_value=3448832 +HeapAlloc dt=6 heapalloc_value=3457024 +HeapAlloc dt=7 heapalloc_value=3465216 +HeapAlloc dt=6 heapalloc_value=3473408 +HeapAlloc dt=6 heapalloc_value=3481600 +HeapAlloc dt=7 heapalloc_value=3489792 +HeapAlloc dt=73 heapalloc_value=3497984 +HeapAlloc dt=8 heapalloc_value=3506176 +HeapAlloc dt=7 heapalloc_value=3514368 +HeapAlloc dt=6 heapalloc_value=3522560 +HeapAlloc dt=6 heapalloc_value=3530752 +HeapAlloc dt=7 heapalloc_value=3538944 +HeapAlloc dt=7 heapalloc_value=3547136 +HeapAlloc dt=6 heapalloc_value=3555328 +HeapAlloc dt=7 heapalloc_value=3563520 +HeapAlloc dt=6 heapalloc_value=3571712 +HeapAlloc dt=6 heapalloc_value=3579904 +HeapAlloc dt=47 heapalloc_value=3588096 +HeapAlloc dt=7 heapalloc_value=3596288 +HeapAlloc dt=6 heapalloc_value=3604480 +HeapAlloc dt=7 heapalloc_value=3612672 +HeapAlloc dt=6 heapalloc_value=3620864 +HeapAlloc dt=7 heapalloc_value=3629056 +HeapAlloc dt=6 heapalloc_value=3637248 +HeapAlloc dt=7 heapalloc_value=3645440 +HeapAlloc dt=6 heapalloc_value=3653632 +HeapAlloc dt=6 heapalloc_value=3661824 +HeapAlloc dt=7 heapalloc_value=3670016 +HeapAlloc dt=6 heapalloc_value=3678208 +HeapAlloc dt=6 heapalloc_value=3686400 +HeapAlloc dt=7 heapalloc_value=3694592 +HeapAlloc dt=6 heapalloc_value=3702784 +HeapAlloc dt=7 heapalloc_value=3710976 +HeapAlloc dt=6 heapalloc_value=3719168 +HeapAlloc dt=6 heapalloc_value=3727360 +HeapAlloc dt=7 heapalloc_value=3735552 +HeapAlloc dt=6 heapalloc_value=3743744 +HeapAlloc dt=9 heapalloc_value=3751936 +HeapAlloc dt=72 heapalloc_value=3760128 +HeapAlloc dt=8 heapalloc_value=3768320 +HeapAlloc dt=7 heapalloc_value=3776512 +HeapAlloc dt=6 heapalloc_value=3784704 +HeapAlloc dt=7 heapalloc_value=3792896 +HeapAlloc dt=8 heapalloc_value=3801088 +HeapAlloc dt=64 heapalloc_value=3809280 +HeapAlloc dt=8 heapalloc_value=3817472 +HeapAlloc dt=6 heapalloc_value=3825664 +HeapAlloc dt=7 heapalloc_value=3833856 +HeapAlloc dt=6 heapalloc_value=3842048 +HeapAlloc dt=7 heapalloc_value=3850240 +HeapAlloc dt=6 heapalloc_value=3858432 +HeapAlloc dt=6 heapalloc_value=3866624 +HeapAlloc dt=7 heapalloc_value=3874816 +HeapAlloc dt=7 heapalloc_value=3883008 +HeapAlloc dt=6 heapalloc_value=3891200 +HeapAlloc dt=7 heapalloc_value=3899392 +HeapAlloc dt=6 heapalloc_value=3907584 +GoBlock dt=19 reason_string=19 stack=21 +ProcStop dt=232 +ProcStart dt=17560 p=1 p_seq=3 +ProcStop dt=23 +ProcStart dt=25946 p=0 p_seq=28 +ProcStop dt=14 +ProcStart dt=16839 p=0 p_seq=29 +GoUnblock dt=21 g=1 g_seq=20 stack=0 +GoStart dt=209 g=1 g_seq=21 +HeapAlloc dt=60 heapalloc_value=4452592 +HeapAlloc dt=28 heapalloc_value=4460784 +HeapAlloc dt=29 heapalloc_value=4468976 +HeapAlloc dt=17 heapalloc_value=4477168 +HeapAlloc dt=19 heapalloc_value=4485360 +HeapAlloc dt=26 heapalloc_value=4493552 +HeapAlloc dt=17 heapalloc_value=4501744 +HeapAlloc dt=21 heapalloc_value=4509936 +HeapAlloc dt=22 heapalloc_value=4518128 +HeapAlloc dt=22 heapalloc_value=4526320 +HeapAlloc dt=36 heapalloc_value=4624624 +HeapAlloc dt=174 heapalloc_value=4632816 +HeapAlloc dt=22 heapalloc_value=4641008 +HeapAlloc dt=23 heapalloc_value=4649200 +HeapAlloc dt=144 heapalloc_value=4657392 +HeapAlloc dt=18 heapalloc_value=4665584 +HeapAlloc dt=19 heapalloc_value=4673776 +HeapAlloc dt=59 heapalloc_value=4681968 +HeapAlloc dt=15 heapalloc_value=4690160 +HeapAlloc dt=10 heapalloc_value=4698352 +HeapAlloc dt=20 heapalloc_value=4706544 +HeapAlloc dt=37 heapalloc_value=4714736 +HeapAlloc dt=33 heapalloc_value=4722928 +HeapAlloc dt=32 heapalloc_value=4731120 +HeapAlloc dt=30 heapalloc_value=4739312 +HeapAlloc dt=33 heapalloc_value=4747504 +HeapAlloc dt=28 heapalloc_value=4755696 +HeapAlloc dt=10 heapalloc_value=4763888 +HeapAlloc dt=9 heapalloc_value=4772080 +HeapAlloc dt=10 heapalloc_value=4780272 +HeapAlloc dt=10 heapalloc_value=4788464 +HeapAlloc dt=12 heapalloc_value=4796656 +HeapAlloc dt=11 heapalloc_value=4804848 +HeapAlloc dt=9 heapalloc_value=4813040 +HeapAlloc dt=9 heapalloc_value=4821232 +HeapAlloc dt=9 heapalloc_value=4829424 +HeapAlloc dt=9 heapalloc_value=4837616 +HeapAlloc dt=10 heapalloc_value=4845808 +HeapAlloc dt=10 heapalloc_value=4854000 +HeapAlloc dt=105 heapalloc_value=4862192 +HeapAlloc dt=13 heapalloc_value=4870384 +HeapAlloc dt=10 heapalloc_value=4878576 +HeapAlloc dt=9 heapalloc_value=4886768 +HeapAlloc dt=59 heapalloc_value=4894960 +HeapAlloc dt=11 heapalloc_value=4903152 +HeapAlloc dt=10 heapalloc_value=4911344 +HeapAlloc dt=9 heapalloc_value=4919536 +HeapAlloc dt=11 heapalloc_value=4927728 +HeapAlloc dt=12 heapalloc_value=4935920 +HeapAlloc dt=10 heapalloc_value=4944112 +HeapAlloc dt=9 heapalloc_value=4952304 +HeapAlloc dt=10 heapalloc_value=4960496 +HeapAlloc dt=9 heapalloc_value=4968688 +HeapAlloc dt=10 heapalloc_value=4976880 +HeapAlloc dt=9 heapalloc_value=4985072 +HeapAlloc dt=12 heapalloc_value=4993264 +HeapAlloc dt=9 heapalloc_value=5001456 +HeapAlloc dt=9 heapalloc_value=5009648 +HeapAlloc dt=10 heapalloc_value=5017840 +HeapAlloc dt=9 heapalloc_value=5026032 +HeapAlloc dt=10 heapalloc_value=5034224 +HeapAlloc dt=9 heapalloc_value=5042416 +HeapAlloc dt=10 heapalloc_value=5050608 +HeapAlloc dt=11 heapalloc_value=5058800 +HeapAlloc dt=10 heapalloc_value=5066992 +HeapAlloc dt=14 heapalloc_value=5075184 +HeapAlloc dt=9 heapalloc_value=5083376 +HeapAlloc dt=10 heapalloc_value=5091568 +HeapAlloc dt=9 heapalloc_value=5099760 +HeapAlloc dt=10 heapalloc_value=5107952 +HeapAlloc dt=10 heapalloc_value=5116144 +HeapAlloc dt=21 heapalloc_value=5124336 +HeapAlloc dt=11 heapalloc_value=5132528 +HeapAlloc dt=8 heapalloc_value=5140720 +HeapAlloc dt=7 heapalloc_value=5148912 +HeapAlloc dt=8 heapalloc_value=5157104 +HeapAlloc dt=9 heapalloc_value=5165296 +HeapAlloc dt=10 heapalloc_value=5173488 +HeapAlloc dt=78 heapalloc_value=5181680 +HeapAlloc dt=11 heapalloc_value=5189872 +HeapAlloc dt=7 heapalloc_value=5198064 +HeapAlloc dt=8 heapalloc_value=5206256 +HeapAlloc dt=8 heapalloc_value=5214448 +HeapAlloc dt=7 heapalloc_value=5222640 +HeapAlloc dt=10 heapalloc_value=5230832 +HeapAlloc dt=7 heapalloc_value=5239024 +HeapAlloc dt=8 heapalloc_value=5247216 +HeapAlloc dt=7 heapalloc_value=5255408 +HeapAlloc dt=8 heapalloc_value=5263600 +HeapAlloc dt=7 heapalloc_value=5271792 +HeapAlloc dt=8 heapalloc_value=5279984 +HeapAlloc dt=8 heapalloc_value=5288176 +HeapAlloc dt=96 heapalloc_value=5296368 +HeapAlloc dt=11 heapalloc_value=5304560 +HeapAlloc dt=53 heapalloc_value=5312752 +HeapAlloc dt=9 heapalloc_value=5320944 +HeapAlloc dt=8 heapalloc_value=5329136 +HeapAlloc dt=8 heapalloc_value=5337328 +HeapAlloc dt=7 heapalloc_value=5345520 +HeapAlloc dt=8 heapalloc_value=5353712 +HeapAlloc dt=9 heapalloc_value=5361904 +HeapAlloc dt=8 heapalloc_value=5370096 +HeapAlloc dt=7 heapalloc_value=5378288 +HeapAlloc dt=8 heapalloc_value=5386480 +HeapAlloc dt=7 heapalloc_value=5394672 +HeapAlloc dt=7 heapalloc_value=5402864 +HeapAlloc dt=8 heapalloc_value=5411056 +HeapAlloc dt=8 heapalloc_value=5419248 +HeapAlloc dt=9 heapalloc_value=5427440 +HeapAlloc dt=7 heapalloc_value=5435632 +HeapAlloc dt=8 heapalloc_value=5443824 +HeapAlloc dt=7 heapalloc_value=5452016 +HeapAlloc dt=8 heapalloc_value=5460208 +HeapAlloc dt=7 heapalloc_value=5468400 +HeapAlloc dt=8 heapalloc_value=5476592 +HeapAlloc dt=7 heapalloc_value=5484784 +HeapAlloc dt=10 heapalloc_value=5492976 +HeapAlloc dt=8 heapalloc_value=5501168 +HeapAlloc dt=7 heapalloc_value=5509360 +HeapAlloc dt=8 heapalloc_value=5517552 +HeapAlloc dt=7 heapalloc_value=5525744 +HeapAlloc dt=8 heapalloc_value=5533936 +HeapAlloc dt=8 heapalloc_value=5542128 +HeapAlloc dt=8 heapalloc_value=5550320 +HeapAlloc dt=84 heapalloc_value=5558512 +HeapAlloc dt=10 heapalloc_value=5566704 +GoBlock dt=17 reason_string=19 stack=21 +ProcStop dt=237 +ProcStart dt=17614 p=1 p_seq=17 +ProcStop dt=23 +ProcStart dt=4599 p=0 p_seq=32 +ProcStop dt=14 +ProcStart dt=16769 p=0 p_seq=33 +GoUnblock dt=22 g=1 g_seq=24 stack=0 +GoStart dt=189 g=1 g_seq=25 +HeapAlloc dt=55 heapalloc_value=6729968 +HeapAlloc dt=24 heapalloc_value=6738160 +HeapAlloc dt=12 heapalloc_value=6746352 +HeapAlloc dt=9 heapalloc_value=6754544 +HeapAlloc dt=10 heapalloc_value=6762736 +HeapAlloc dt=11 heapalloc_value=6770928 +HeapAlloc dt=8 heapalloc_value=6779120 +HeapAlloc dt=12 heapalloc_value=6787312 +HeapAlloc dt=8 heapalloc_value=6795504 +HeapAlloc dt=7 heapalloc_value=6803696 +HeapAlloc dt=9 heapalloc_value=6811888 +HeapAlloc dt=6 heapalloc_value=6820080 +HeapAlloc dt=6 heapalloc_value=6828272 +HeapAlloc dt=6 heapalloc_value=6836464 +HeapAlloc dt=6 heapalloc_value=6844656 +HeapAlloc dt=6 heapalloc_value=6852848 +HeapAlloc dt=6 heapalloc_value=6861040 +HeapAlloc dt=595 heapalloc_value=6869232 +HeapAlloc dt=89 heapalloc_value=6877424 +HeapAlloc dt=8 heapalloc_value=6885616 +HeapAlloc dt=7 heapalloc_value=6893808 +HeapAlloc dt=8 heapalloc_value=6902000 +HeapAlloc dt=43 heapalloc_value=6910192 +HeapAlloc dt=7 heapalloc_value=6918384 +HeapAlloc dt=6 heapalloc_value=6926576 +HeapAlloc dt=7 heapalloc_value=6934768 +HeapAlloc dt=6 heapalloc_value=6942960 +HeapAlloc dt=6 heapalloc_value=6951152 +HeapAlloc dt=6 heapalloc_value=6959344 +HeapAlloc dt=6 heapalloc_value=6967536 +HeapAlloc dt=6 heapalloc_value=6975728 +HeapAlloc dt=5 heapalloc_value=6983920 +HeapAlloc dt=6 heapalloc_value=6992112 +HeapAlloc dt=6 heapalloc_value=7000304 +HeapAlloc dt=6 heapalloc_value=7008496 +HeapAlloc dt=6 heapalloc_value=7016688 +HeapAlloc dt=6 heapalloc_value=7024880 +HeapAlloc dt=8 heapalloc_value=7033072 +HeapAlloc dt=5 heapalloc_value=7041264 +HeapAlloc dt=6 heapalloc_value=7049456 +HeapAlloc dt=6 heapalloc_value=7057648 +HeapAlloc dt=6 heapalloc_value=7065840 +HeapAlloc dt=5 heapalloc_value=7074032 +HeapAlloc dt=6 heapalloc_value=7082224 +HeapAlloc dt=6 heapalloc_value=7090416 +HeapAlloc dt=6 heapalloc_value=7098608 +HeapAlloc dt=5 heapalloc_value=7106800 +HeapAlloc dt=43 heapalloc_value=7114992 +HeapAlloc dt=7 heapalloc_value=7123184 +HeapAlloc dt=74 heapalloc_value=7131376 +HeapAlloc dt=8 heapalloc_value=7139568 +HeapAlloc dt=6 heapalloc_value=7147760 +HeapAlloc dt=6 heapalloc_value=7155952 +HeapAlloc dt=5 heapalloc_value=7164144 +HeapAlloc dt=6 heapalloc_value=7172336 +HeapAlloc dt=6 heapalloc_value=7180528 +HeapAlloc dt=6 heapalloc_value=7188720 +HeapAlloc dt=6 heapalloc_value=7196912 +HeapAlloc dt=379 heapalloc_value=7368944 +HeapAlloc dt=4398 heapalloc_value=7377136 +HeapAlloc dt=19 heapalloc_value=7385328 +HeapAlloc dt=14 heapalloc_value=7393520 +HeapAlloc dt=16 heapalloc_value=7401712 +HeapAlloc dt=12 heapalloc_value=7409904 +HeapAlloc dt=11 heapalloc_value=7418096 +HeapAlloc dt=13 heapalloc_value=7426288 +HeapAlloc dt=12 heapalloc_value=7434480 +HeapAlloc dt=12 heapalloc_value=7442672 +HeapAlloc dt=11 heapalloc_value=7450864 +HeapAlloc dt=12 heapalloc_value=7459056 +HeapAlloc dt=13 heapalloc_value=7467248 +HeapAlloc dt=13 heapalloc_value=7475440 +HeapAlloc dt=12 heapalloc_value=7483632 +HeapAlloc dt=13 heapalloc_value=7491824 +HeapAlloc dt=12 heapalloc_value=7500016 +HeapAlloc dt=12 heapalloc_value=7508208 +HeapAlloc dt=11 heapalloc_value=7516400 +HeapAlloc dt=12 heapalloc_value=7524592 +HeapAlloc dt=14 heapalloc_value=7532784 +HeapAlloc dt=12 heapalloc_value=7540976 +HeapAlloc dt=12 heapalloc_value=7549168 +HeapAlloc dt=13 heapalloc_value=7557360 +HeapAlloc dt=96 heapalloc_value=7565552 +HeapAlloc dt=9 heapalloc_value=7573744 +HeapAlloc dt=7 heapalloc_value=7581936 +HeapAlloc dt=6 heapalloc_value=7590128 +HeapAlloc dt=6 heapalloc_value=7598320 +HeapAlloc dt=6 heapalloc_value=7606512 +HeapAlloc dt=6 heapalloc_value=7614704 +HeapAlloc dt=6 heapalloc_value=7622896 +HeapAlloc dt=7 heapalloc_value=7631088 +HeapAlloc dt=6 heapalloc_value=7639280 +HeapAlloc dt=6 heapalloc_value=7647472 +HeapAlloc dt=81 heapalloc_value=7655664 +HeapAlloc dt=8 heapalloc_value=7663856 +HeapAlloc dt=6 heapalloc_value=7672048 +HeapAlloc dt=6 heapalloc_value=7680240 +HeapAlloc dt=6 heapalloc_value=7688432 +HeapAlloc dt=6 heapalloc_value=7696624 +HeapAlloc dt=45 heapalloc_value=7704816 +HeapAlloc dt=8 heapalloc_value=7713008 +HeapAlloc dt=6 heapalloc_value=7721200 +HeapAlloc dt=6 heapalloc_value=7729392 +HeapAlloc dt=6 heapalloc_value=7737584 +HeapAlloc dt=6 heapalloc_value=7745776 +HeapAlloc dt=6 heapalloc_value=7753968 +HeapAlloc dt=6 heapalloc_value=7762160 +HeapAlloc dt=6 heapalloc_value=7770352 +HeapAlloc dt=6 heapalloc_value=7778544 +HeapAlloc dt=6 heapalloc_value=7786736 +HeapAlloc dt=6 heapalloc_value=7794928 +HeapAlloc dt=6 heapalloc_value=7803120 +HeapAlloc dt=6 heapalloc_value=7811312 +HeapAlloc dt=6 heapalloc_value=7819504 +HeapAlloc dt=6 heapalloc_value=7827696 +HeapAlloc dt=6 heapalloc_value=7835888 +HeapAlloc dt=6 heapalloc_value=7844080 +HeapAlloc dt=6 heapalloc_value=7852272 +HeapAlloc dt=6 heapalloc_value=7860464 +HeapAlloc dt=6 heapalloc_value=7868656 +HeapAlloc dt=6 heapalloc_value=7876848 +HeapAlloc dt=6 heapalloc_value=7885040 +HeapAlloc dt=7 heapalloc_value=7893232 +HeapAlloc dt=5 heapalloc_value=7901424 +HeapAlloc dt=7 heapalloc_value=7909616 +HeapAlloc dt=72 heapalloc_value=7917808 +GCBegin dt=27 gc_seq=3 stack=41 +STWBegin dt=46 kind_string=22 stack=42 +GoUnblock dt=163 g=4 g_seq=3 stack=43 +ProcsChange dt=106 procs_value=8 stack=44 +STWEnd dt=26 +GCMarkAssistBegin dt=206 stack=30 +GCMarkAssistEnd dt=1163 +GoBlock dt=20 reason_string=19 stack=21 +GoStart dt=199 g=4 g_seq=4 +GoBlock dt=21 reason_string=15 stack=32 +GoUnblock dt=111 g=8 g_seq=2 stack=0 +GoStart dt=272 g=8 g_seq=3 +GoLabel dt=3 label_string=4 +GoBlock dt=553 reason_string=15 stack=26 +GoUnblock dt=12 g=1 g_seq=26 stack=0 +GoStart dt=9 g=1 g_seq=27 +HeapAlloc dt=172 heapalloc_value=7926000 +HeapAlloc dt=24 heapalloc_value=7934192 +HeapAlloc dt=9 heapalloc_value=7942384 +HeapAlloc dt=9 heapalloc_value=7950576 +HeapAlloc dt=15 heapalloc_value=7958768 +HeapAlloc dt=11 heapalloc_value=7966960 +HeapAlloc dt=12 heapalloc_value=7975152 +HeapAlloc dt=10 heapalloc_value=7983344 +HeapAlloc dt=11 heapalloc_value=7991536 +HeapAlloc dt=8 heapalloc_value=7999728 +HeapAlloc dt=7 heapalloc_value=8007920 +HeapAlloc dt=7 heapalloc_value=8016112 +HeapAlloc dt=9 heapalloc_value=8024304 +HeapAlloc dt=8 heapalloc_value=8032496 +HeapAlloc dt=9 heapalloc_value=8040688 +HeapAlloc dt=8 heapalloc_value=8048880 +HeapAlloc dt=7 heapalloc_value=8057072 +HeapAlloc dt=7 heapalloc_value=8065264 +HeapAlloc dt=8 heapalloc_value=8073456 +HeapAlloc dt=229 heapalloc_value=8081648 +HeapAlloc dt=13 heapalloc_value=8089840 +HeapAlloc dt=7 heapalloc_value=8098032 +HeapAlloc dt=7 heapalloc_value=8106224 +HeapAlloc dt=44 heapalloc_value=8114416 +HeapAlloc dt=9 heapalloc_value=8122608 +HeapAlloc dt=7 heapalloc_value=8130800 +HeapAlloc dt=7 heapalloc_value=8138992 +HeapAlloc dt=263 heapalloc_value=8147184 +HeapAlloc dt=9 heapalloc_value=8155376 +HeapAlloc dt=8 heapalloc_value=8163568 +HeapAlloc dt=7 heapalloc_value=8171760 +HeapAlloc dt=6 heapalloc_value=8179952 +HeapAlloc dt=42 heapalloc_value=8188144 +HeapAlloc dt=7 heapalloc_value=8196336 +HeapAlloc dt=7 heapalloc_value=8204528 +HeapAlloc dt=7 heapalloc_value=8212720 +HeapAlloc dt=8 heapalloc_value=8220912 +HeapAlloc dt=7 heapalloc_value=8229104 +HeapAlloc dt=7 heapalloc_value=8237296 +HeapAlloc dt=7 heapalloc_value=8245488 +HeapAlloc dt=7 heapalloc_value=8253680 +HeapAlloc dt=7 heapalloc_value=8261872 +HeapAlloc dt=6 heapalloc_value=8270064 +HeapAlloc dt=7 heapalloc_value=8278256 +HeapAlloc dt=7 heapalloc_value=8286448 +HeapAlloc dt=7 heapalloc_value=8294640 +HeapAlloc dt=7 heapalloc_value=8302832 +HeapAlloc dt=7 heapalloc_value=8311024 +HeapAlloc dt=50 heapalloc_value=8319216 +HeapAlloc dt=11 heapalloc_value=8327408 +HeapAlloc dt=14 heapalloc_value=8335600 +HeapAlloc dt=14 heapalloc_value=8343792 +HeapAlloc dt=11 heapalloc_value=8351984 +HeapAlloc dt=11 heapalloc_value=8360176 +HeapAlloc dt=13 heapalloc_value=8368368 +HeapAlloc dt=11 heapalloc_value=8376560 +HeapAlloc dt=11 heapalloc_value=8384752 +HeapAlloc dt=12 heapalloc_value=8392944 +HeapAlloc dt=11 heapalloc_value=8401136 +HeapAlloc dt=257 heapalloc_value=8409328 +HeapAlloc dt=19 heapalloc_value=8417520 +HeapAlloc dt=17 heapalloc_value=8425712 +HeapAlloc dt=15 heapalloc_value=8433904 +HeapAlloc dt=14 heapalloc_value=8442096 +HeapAlloc dt=50 heapalloc_value=8450288 +HeapAlloc dt=14 heapalloc_value=8458480 +HeapAlloc dt=14 heapalloc_value=8466672 +HeapAlloc dt=15 heapalloc_value=8474864 +HeapAlloc dt=14 heapalloc_value=8483056 +HeapAlloc dt=12 heapalloc_value=8491248 +HeapAlloc dt=12 heapalloc_value=8499440 +HeapAlloc dt=13 heapalloc_value=8507632 +HeapAlloc dt=14 heapalloc_value=8515824 +HeapAlloc dt=12 heapalloc_value=8524016 +HeapAlloc dt=13 heapalloc_value=8532208 +HeapAlloc dt=13 heapalloc_value=8540400 +HeapAlloc dt=13 heapalloc_value=8548592 +HeapAlloc dt=16 heapalloc_value=8556784 +HeapAlloc dt=14 heapalloc_value=8564976 +HeapAlloc dt=14 heapalloc_value=8573168 +HeapAlloc dt=16 heapalloc_value=8581360 +HeapAlloc dt=14 heapalloc_value=8589552 +HeapAlloc dt=14 heapalloc_value=8597744 +HeapAlloc dt=59 heapalloc_value=8605936 +HeapAlloc dt=15 heapalloc_value=8614128 +HeapAlloc dt=12 heapalloc_value=8622320 +HeapAlloc dt=12 heapalloc_value=8630512 +HeapAlloc dt=11 heapalloc_value=8638704 +HeapAlloc dt=15 heapalloc_value=8646896 +HeapAlloc dt=12 heapalloc_value=8655088 +HeapAlloc dt=11 heapalloc_value=8663280 +HeapAlloc dt=292 heapalloc_value=8671472 +HeapAlloc dt=14 heapalloc_value=8679664 +HeapAlloc dt=12 heapalloc_value=8687856 +HeapAlloc dt=11 heapalloc_value=8696048 +HeapAlloc dt=12 heapalloc_value=8704240 +HeapAlloc dt=44 heapalloc_value=8712432 +HeapAlloc dt=14 heapalloc_value=8720624 +HeapAlloc dt=11 heapalloc_value=8728816 +HeapAlloc dt=14 heapalloc_value=8737008 +HeapAlloc dt=52 heapalloc_value=8745200 +HeapAlloc dt=13 heapalloc_value=8753392 +HeapAlloc dt=13 heapalloc_value=8761584 +HeapAlloc dt=12 heapalloc_value=8769776 +HeapAlloc dt=15 heapalloc_value=8777968 +HeapAlloc dt=12 heapalloc_value=8786160 +HeapAlloc dt=14 heapalloc_value=8794352 +HeapAlloc dt=18 heapalloc_value=8802544 +GoStop dt=25 reason_string=16 stack=46 +GoStart dt=658 g=1 g_seq=28 +HeapAlloc dt=14 heapalloc_value=8810736 +HeapAlloc dt=24 heapalloc_value=8818928 +HeapAlloc dt=12 heapalloc_value=8827120 +HeapAlloc dt=13 heapalloc_value=8835312 +HeapAlloc dt=15 heapalloc_value=8843504 +HeapAlloc dt=12 heapalloc_value=8851696 +HeapAlloc dt=16 heapalloc_value=8859888 +HeapAlloc dt=14 heapalloc_value=8868080 +HeapAlloc dt=14 heapalloc_value=8876272 +HeapAlloc dt=13 heapalloc_value=8884464 +HeapAlloc dt=12 heapalloc_value=8892656 +HeapAlloc dt=13 heapalloc_value=8900848 +HeapAlloc dt=15 heapalloc_value=8909040 +HeapAlloc dt=13 heapalloc_value=8917232 +HeapAlloc dt=15 heapalloc_value=8925424 +HeapAlloc dt=101 heapalloc_value=8933616 +GCMarkAssistBegin dt=13 stack=30 +GoBlock dt=37 reason_string=10 stack=33 +ProcStop dt=16 +ProcStart dt=1559 p=0 p_seq=34 +GoStart dt=433 g=1 g_seq=30 +GCMarkAssistEnd dt=16 +HeapAlloc dt=13 heapalloc_value=8630512 +GCSweepBegin dt=342 stack=47 +GCSweepEnd dt=22 swept_value=131072 reclaimed_value=0 +GCSweepBegin dt=19 stack=38 +GCSweepEnd dt=412 swept_value=827392 reclaimed_value=0 +HeapAlloc dt=32 heapalloc_value=8638704 +GoBlock dt=26 reason_string=19 stack=21 +ProcStop dt=31 +ProcStart dt=4598 p=0 p_seq=35 +ProcStop dt=23 +ProcStart dt=60434 p=0 p_seq=39 +GoStart dt=172 g=4 g_seq=6 +GoBlock dt=37 reason_string=15 stack=32 +ProcStop dt=17 +ProcStart dt=50232 p=2 p_seq=21 +GoUnblock dt=21 g=25 g_seq=8 stack=0 +GoStart dt=277 g=25 g_seq=9 +GoLabel dt=1 label_string=2 +STWBegin dt=10275 kind_string=23 stack=34 +GoUnblock dt=637 g=34 g_seq=4 stack=35 +HeapAlloc dt=30 heapalloc_value=16793488 +GoUnblock dt=20 g=3 g_seq=5 stack=36 +GCEnd dt=7 gc_seq=6 +HeapGoal dt=5 heapgoal_value=34005760 +ProcsChange dt=48 procs_value=8 stack=37 +STWEnd dt=40 +GoBlock dt=1283 reason_string=15 stack=26 +GoStart dt=14 g=3 g_seq=6 +GoBlock dt=10077 reason_string=14 stack=40 +ProcStop dt=21 +ProcStart dt=84537 p=2 p_seq=27 +GoStart dt=249 g=4 g_seq=10 +GoBlock dt=20 reason_string=15 stack=32 +ProcStop dt=102 +ProcStart dt=8641 p=2 p_seq=28 +GoStart dt=201 g=11 g_seq=1 +GoStop dt=305542 reason_string=16 stack=52 +GoStart dt=20 g=11 g_seq=2 +GoStop dt=316424 reason_string=16 stack=52 +GoStart dt=16 g=11 g_seq=3 +GoDestroy dt=159274 +ProcStop dt=45 +EventBatch gen=1 m=2852339 time=420901991582 size=23 +GoUnblock dt=137 g=4 g_seq=5 stack=0 +GoUnblock dt=157581 g=4 g_seq=9 stack=0 +ProcSteal dt=948232 p=6 p_seq=9 m=2852347 +EventBatch gen=1 m=2852338 time=420901450373 size=416 +ProcStatus dt=115 p=1 pstatus=1 +GoStatus dt=4 g=1 m=2852338 gstatus=2 +ProcsChange dt=217 procs_value=8 stack=1 +STWBegin dt=68 kind_string=21 stack=2 +HeapGoal dt=2 heapgoal_value=4194304 +ProcStatus dt=1 p=0 pstatus=2 +ProcStatus dt=4 p=2 pstatus=2 +ProcStatus dt=3 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=2 p=7 pstatus=2 +ProcsChange dt=65 procs_value=8 stack=3 +STWEnd dt=23 +HeapAlloc dt=190 heapalloc_value=1638400 +GoCreate dt=157 new_g=19 new_stack=4 stack=5 +GoCreate dt=565 new_g=20 new_stack=6 stack=7 +HeapAlloc dt=31 heapalloc_value=1646592 +GoCreate dt=523 new_g=21 new_stack=8 stack=9 +GoCreate dt=702 new_g=22 new_stack=10 stack=12 +GoCreate dt=377 new_g=23 new_stack=13 stack=14 +GoBlock dt=18 reason_string=10 stack=15 +GoStart dt=12 g=23 g_seq=1 +GoStop dt=222604 reason_string=16 stack=19 +GoStart dt=399 g=23 g_seq=2 +GoUnblock dt=89532 g=1 g_seq=1 stack=20 +GoDestroy dt=165 +GoStart dt=14 g=1 g_seq=2 +GoBlock dt=21 reason_string=19 stack=21 +ProcStop dt=257 +ProcStart dt=60623 p=1 p_seq=4 +GoStart dt=5704 g=5 g_seq=1 +HeapAlloc dt=34 heapalloc_value=4046848 +GoBlock dt=461 reason_string=15 stack=26 +ProcStop dt=25 +ProcStart dt=294 p=0 p_seq=14 +GoStart dt=9 g=6 g_seq=1 +GoBlock dt=506 reason_string=15 stack=26 +ProcStop dt=8 +ProcStart dt=230 p=0 p_seq=17 +ProcStop dt=23 +ProcStart dt=1406 p=0 p_seq=18 +GoStart dt=339 g=34 g_seq=1 +GoBlock dt=291 reason_string=15 stack=26 +ProcStop dt=13 +ProcStart dt=465 p=1 p_seq=10 +GoStart dt=173 g=8 g_seq=1 +GoBlock dt=120 reason_string=15 stack=26 +ProcStop dt=12 +ProcStart dt=353 p=0 p_seq=24 +ProcStop dt=17 +ProcStart dt=968 p=0 p_seq=25 +ProcStop dt=6 +ProcStart dt=554 p=0 p_seq=26 +GoUnblock dt=16 g=25 g_seq=2 stack=0 +GoStart dt=334 g=25 g_seq=3 +GoLabel dt=1 label_string=2 +GoBlock dt=2066 reason_string=15 stack=26 +ProcStop dt=24 +ProcStart dt=202889 p=4 p_seq=3 +GoUnblock dt=53 g=34 g_seq=2 stack=0 +HeapAlloc dt=50 heapalloc_value=16498416 +HeapAlloc dt=32 heapalloc_value=16501200 +HeapAlloc dt=4276 heapalloc_value=16697040 +GoStart dt=1376 g=34 g_seq=3 +GoLabel dt=2 label_string=4 +HeapAlloc dt=69 heapalloc_value=16713136 +GoBlock dt=35 reason_string=10 stack=48 +ProcStop dt=50 +ProcStart dt=111183 p=5 p_seq=3 +HeapAlloc dt=56 heapalloc_value=23234784 +HeapAlloc dt=25 heapalloc_value=23242144 +HeapAlloc dt=343 heapalloc_value=23249312 +GoStart dt=1532 g=16 g_seq=1 +GoStop dt=302128 reason_string=16 stack=52 +GoStart dt=13 g=16 g_seq=2 +GoStop dt=316412 reason_string=16 stack=52 +GoStart dt=10 g=16 g_seq=3 +GoDestroy dt=162712 +ProcStop dt=30 +ProcStart dt=798510 p=5 p_seq=5 +ProcStop dt=29 +ProcStart dt=4349 p=6 p_seq=21 +ProcStop dt=41 +ProcStart dt=16784 p=6 p_seq=22 +GoUnblock dt=14 g=82 g_seq=2 stack=0 +GoStart dt=161 g=82 g_seq=3 +GoSyscallBegin dt=27 p_seq=23 stack=93 +GoSyscallEnd dt=663 +GoSyscallBegin dt=102 p_seq=24 stack=94 +GoSyscallEnd dt=258 +GoDestroy dt=9 +ProcStop dt=24 +EventBatch gen=1 m=18446744073709551615 time=420903766597 size=28 +GoStatus dt=69 g=2 m=18446744073709551615 gstatus=4 +GoStatus dt=2 g=18 m=18446744073709551615 gstatus=4 +EventBatch gen=1 m=18446744073709551615 time=420903767161 size=4524 +Stacks +Stack id=20 nframes=3 + pc=4700772 func=24 file=25 line=81 + pc=5073062 func=26 file=25 line=87 + pc=5072984 func=27 file=28 line=105 +Stack id=71 nframes=21 + pc=4746903 func=29 file=30 line=736 + pc=4807597 func=31 file=32 line=181 + pc=4807573 func=33 file=34 line=736 + pc=4807216 func=35 file=34 line=160 + pc=4813553 func=36 file=37 line=29 + pc=4813545 func=38 file=39 line=118 + pc=4735439 func=40 file=41 line=335 + pc=5034447 func=42 file=41 line=354 + pc=5034407 func=43 file=44 line=55 + pc=5039623 func=45 file=46 line=40 + pc=5060942 func=47 file=48 line=373 + pc=4696033 func=49 file=50 line=74 + pc=5026795 func=51 file=50 line=65 + pc=5026766 func=52 file=48 line=373 + pc=5040478 func=53 file=54 line=57 + pc=5014167 func=55 file=56 line=154 + pc=5051652 func=57 file=58 line=182 + pc=4960356 func=59 file=58 line=172 + pc=4960318 func=60 file=61 line=734 + pc=4961094 func=62 file=61 line=808 + pc=5070695 func=63 file=28 line=53 +Stack id=21 nframes=3 + pc=4633684 func=64 file=65 line=195 + pc=5073512 func=66 file=28 line=125 + pc=5070323 func=63 file=28 line=32 +Stack id=38 nframes=9 + pc=4578453 func=67 file=68 line=352 + pc=4353540 func=69 file=70 line=521 + pc=4290908 func=71 file=72 line=147 + pc=4288626 func=73 file=74 line=182 + pc=4252996 func=75 file=76 line=948 + pc=4254486 func=77 file=76 line=1149 + pc=4522824 func=78 file=79 line=103 + pc=5073532 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=34 nframes=1 + pc=4314212 func=80 file=81 line=1446 +Stack id=13 nframes=1 + pc=5072896 func=27 file=28 line=102 +Stack id=48 nframes=2 + pc=4307927 func=82 file=81 line=807 + pc=4314212 func=80 file=81 line=1446 +Stack id=65 nframes=7 + pc=4747354 func=83 file=30 line=964 + pc=4808839 func=84 file=32 line=209 + pc=4808831 func=33 file=34 line=736 + pc=4808384 func=85 file=34 line=380 + pc=4813744 func=86 file=37 line=46 + pc=4813736 func=87 file=39 line=183 + pc=5072644 func=88 file=28 line=89 +Stack id=63 nframes=3 + pc=4746903 func=29 file=30 line=736 + pc=5072295 func=31 file=32 line=181 + pc=5072241 func=89 file=28 line=90 +Stack id=85 nframes=15 + pc=4750130 func=90 file=30 line=1488 + pc=4811799 func=91 file=32 line=462 + pc=4811777 func=92 file=93 line=17 + pc=5052502 func=94 file=95 line=21 + pc=5048264 func=96 file=97 line=245 + pc=5050832 func=98 file=58 line=114 + pc=5049860 func=99 file=58 line=68 + pc=5049861 func=100 file=58 line=64 + pc=4958364 func=101 file=61 line=651 + pc=4956653 func=102 file=61 line=616 + pc=4954291 func=103 file=61 line=517 + pc=4952889 func=104 file=61 line=508 + pc=4951126 func=105 file=61 line=434 + pc=4951127 func=106 file=61 line=401 + pc=5070980 func=63 file=28 line=68 +Stack id=1 nframes=4 + pc=4576875 func=107 file=68 line=255 + pc=4561423 func=108 file=109 line=237 + pc=5069285 func=110 file=111 line=125 + pc=5070075 func=63 file=28 line=20 +Stack id=7 nframes=4 + pc=4567652 func=112 file=109 line=868 + pc=4561732 func=108 file=109 line=258 + pc=5069285 func=110 file=111 line=125 + pc=5070075 func=63 file=28 line=20 +Stack id=88 nframes=8 + pc=4750130 func=90 file=30 line=1488 + pc=4811799 func=91 file=32 line=462 + pc=4811777 func=92 file=93 line=17 + pc=5052074 func=113 file=114 line=15 + pc=5048202 func=96 file=97 line=239 + pc=5051452 func=115 file=58 line=156 + pc=5048431 func=116 file=97 line=315 + pc=5071227 func=117 file=28 line=59 +Stack id=16 nframes=3 + pc=4225233 func=118 file=119 line=442 + pc=4568106 func=120 file=109 line=928 + pc=4567719 func=121 file=109 line=871 +Stack id=95 nframes=8 + pc=4746468 func=122 file=30 line=335 + pc=4806160 func=123 file=124 line=24 + pc=4806130 func=125 file=34 line=81 + pc=4803890 func=126 file=127 line=213 + pc=4806308 func=128 file=34 line=104 + pc=4988529 func=129 file=130 line=37 + pc=5026133 func=131 file=48 line=203 + pc=5071131 func=63 file=28 line=74 +Stack id=94 nframes=8 + pc=4746468 func=122 file=30 line=335 + pc=4806160 func=123 file=124 line=24 + pc=4806130 func=125 file=34 line=81 + pc=4803890 func=126 file=127 line=213 + pc=4806308 func=128 file=34 line=104 + pc=4988529 func=129 file=130 line=37 + pc=5026133 func=131 file=48 line=203 + pc=5071317 func=117 file=28 line=66 +Stack id=43 nframes=6 + pc=4637735 func=132 file=133 line=474 + pc=4307012 func=134 file=81 line=684 + pc=4255286 func=77 file=76 line=1292 + pc=4522824 func=78 file=79 line=103 + pc=5073532 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=26 nframes=2 + pc=4433005 func=135 file=136 line=402 + pc=4313604 func=80 file=81 line=1310 +Stack id=66 nframes=2 + pc=4221878 func=137 file=119 line=145 + pc=5072533 func=89 file=28 line=94 +Stack id=55 nframes=1 + pc=5070565 func=63 file=28 line=47 +Stack id=42 nframes=4 + pc=4255286 func=77 file=76 line=1292 + pc=4522824 func=78 file=79 line=103 + pc=5073532 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=14 nframes=1 + pc=5070300 func=63 file=28 line=28 +Stack id=56 nframes=2 + pc=4225233 func=118 file=119 line=442 + pc=5070586 func=63 file=28 line=48 +Stack id=24 nframes=6 + pc=4313307 func=138 file=81 line=1234 + pc=4306780 func=134 file=81 line=663 + pc=4255286 func=77 file=76 line=1292 + pc=4524282 func=139 file=79 line=246 + pc=5073584 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=45 nframes=1 + pc=0 func=0 file=0 line=0 +Stack id=44 nframes=5 + pc=4307322 func=134 file=81 line=746 + pc=4255286 func=77 file=76 line=1292 + pc=4522824 func=78 file=79 line=103 + pc=5073532 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=6 nframes=1 + pc=4567680 func=121 file=109 line=868 +Stack id=11 nframes=3 + pc=4225233 func=118 file=119 line=442 + pc=4568106 func=120 file=109 line=928 + pc=4570874 func=140 file=141 line=54 +Stack id=4 nframes=1 + pc=4570816 func=140 file=141 line=42 +Stack id=22 nframes=4 + pc=4255286 func=77 file=76 line=1292 + pc=4524282 func=139 file=79 line=246 + pc=5073584 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=83 nframes=15 + pc=4750130 func=90 file=30 line=1488 + pc=4811799 func=91 file=32 line=462 + pc=4811777 func=92 file=93 line=17 + pc=5047242 func=142 file=143 line=88 + pc=5048249 func=96 file=97 line=244 + pc=5050832 func=98 file=58 line=114 + pc=5049860 func=99 file=58 line=68 + pc=5049861 func=100 file=58 line=64 + pc=4958364 func=101 file=61 line=651 + pc=4956653 func=102 file=61 line=616 + pc=4954291 func=103 file=61 line=517 + pc=4952889 func=104 file=61 line=508 + pc=4951126 func=105 file=61 line=434 + pc=4951127 func=106 file=61 line=401 + pc=5070980 func=63 file=28 line=68 +Stack id=37 nframes=3 + pc=4310566 func=144 file=81 line=1087 + pc=4308676 func=82 file=81 line=927 + pc=4314212 func=80 file=81 line=1446 +Stack id=9 nframes=2 + pc=5069359 func=110 file=111 line=128 + pc=5070075 func=63 file=28 line=20 +Stack id=35 nframes=2 + pc=4308599 func=82 file=81 line=915 + pc=4314212 func=80 file=81 line=1446 +Stack id=72 nframes=20 + pc=4746468 func=122 file=30 line=335 + pc=4806160 func=123 file=124 line=24 + pc=4806130 func=125 file=34 line=81 + pc=4803890 func=126 file=127 line=213 + pc=4806308 func=128 file=34 line=104 + pc=4816631 func=145 file=146 line=315 + pc=5040044 func=147 file=37 line=23 + pc=5040027 func=148 file=44 line=23 + pc=5039886 func=45 file=46 line=53 + pc=5060942 func=47 file=48 line=373 + pc=4696033 func=49 file=50 line=74 + pc=5026795 func=51 file=50 line=65 + pc=5026766 func=52 file=48 line=373 + pc=5040478 func=53 file=54 line=57 + pc=5014167 func=55 file=56 line=154 + pc=5051652 func=57 file=58 line=182 + pc=4960356 func=59 file=58 line=172 + pc=4960318 func=60 file=61 line=734 + pc=4961094 func=62 file=61 line=808 + pc=5070695 func=63 file=28 line=53 +Stack id=3 nframes=4 + pc=4442379 func=149 file=136 line=1382 + pc=4561715 func=108 file=109 line=255 + pc=5069285 func=110 file=111 line=125 + pc=5070075 func=63 file=28 line=20 +Stack id=19 nframes=1 + pc=5072969 func=27 file=28 line=104 +Stack id=61 nframes=5 + pc=4746660 func=150 file=30 line=432 + pc=4737158 func=151 file=152 line=106 + pc=4806697 func=153 file=34 line=129 + pc=5072228 func=154 file=146 line=90 + pc=5072241 func=89 file=28 line=90 +Stack id=79 nframes=8 + pc=4748798 func=155 file=30 line=1421 + pc=4743029 func=156 file=157 line=684 + pc=4810951 func=158 file=159 line=17 + pc=4809725 func=160 file=34 line=602 + pc=4992776 func=161 file=162 line=172 + pc=5051421 func=115 file=58 line=152 + pc=5048431 func=116 file=97 line=315 + pc=5071227 func=117 file=28 line=59 +Stack id=91 nframes=8 + pc=4750130 func=90 file=30 line=1488 + pc=4811799 func=91 file=32 line=462 + pc=4811777 func=92 file=93 line=17 + pc=5052502 func=94 file=95 line=21 + pc=5048264 func=96 file=97 line=245 + pc=5051452 func=115 file=58 line=156 + pc=5048431 func=116 file=97 line=315 + pc=5071227 func=117 file=28 line=59 +Stack id=62 nframes=5 + pc=4746660 func=150 file=30 line=432 + pc=4737232 func=151 file=152 line=118 + pc=4806697 func=153 file=34 line=129 + pc=5072228 func=154 file=146 line=90 + pc=5072241 func=89 file=28 line=90 +Stack id=75 nframes=9 + pc=4748164 func=163 file=30 line=1213 + pc=5044432 func=164 file=54 line=170 + pc=5040531 func=53 file=54 line=57 + pc=5014167 func=55 file=56 line=154 + pc=5051652 func=57 file=58 line=182 + pc=4960356 func=59 file=58 line=172 + pc=4960318 func=60 file=61 line=734 + pc=4961094 func=62 file=61 line=808 + pc=5070695 func=63 file=28 line=53 +Stack id=73 nframes=11 + pc=4750130 func=90 file=30 line=1488 + pc=5046866 func=91 file=32 line=462 + pc=5046876 func=165 file=166 line=28 + pc=5043829 func=164 file=54 line=152 + pc=5040531 func=53 file=54 line=57 + pc=5014167 func=55 file=56 line=154 + pc=5051652 func=57 file=58 line=182 + pc=4960356 func=59 file=58 line=172 + pc=4960318 func=60 file=61 line=734 + pc=4961094 func=62 file=61 line=808 + pc=5070695 func=63 file=28 line=53 +Stack id=87 nframes=4 + pc=4807527 func=35 file=34 line=164 + pc=4988612 func=167 file=130 line=55 + pc=5025316 func=168 file=48 line=179 + pc=5071115 func=63 file=28 line=73 +Stack id=84 nframes=15 + pc=4750130 func=90 file=30 line=1488 + pc=4811799 func=91 file=32 line=462 + pc=4811777 func=92 file=93 line=17 + pc=5052347 func=94 file=95 line=18 + pc=5048264 func=96 file=97 line=245 + pc=5050832 func=98 file=58 line=114 + pc=5049860 func=99 file=58 line=68 + pc=5049861 func=100 file=58 line=64 + pc=4958364 func=101 file=61 line=651 + pc=4956653 func=102 file=61 line=616 + pc=4954291 func=103 file=61 line=517 + pc=4952889 func=104 file=61 line=508 + pc=4951126 func=105 file=61 line=434 + pc=4951127 func=106 file=61 line=401 + pc=5070980 func=63 file=28 line=68 +Stack id=92 nframes=2 + pc=4633684 func=64 file=65 line=195 + pc=5071262 func=117 file=28 line=63 +Stack id=40 nframes=2 + pc=4352030 func=169 file=136 line=408 + pc=4351996 func=170 file=70 line=317 +Stack id=89 nframes=8 + pc=4750130 func=90 file=30 line=1488 + pc=4811799 func=91 file=32 line=462 + pc=4811777 func=92 file=93 line=17 + pc=5047242 func=142 file=143 line=88 + pc=5048249 func=96 file=97 line=244 + pc=5051452 func=115 file=58 line=156 + pc=5048431 func=116 file=97 line=315 + pc=5071227 func=117 file=28 line=59 +Stack id=53 nframes=3 + pc=4700772 func=24 file=25 line=81 + pc=5071718 func=26 file=25 line=87 + pc=5071644 func=171 file=28 line=41 +Stack id=81 nframes=16 + pc=4749883 func=172 file=30 line=1478 + pc=4744812 func=173 file=32 line=313 + pc=4991029 func=174 file=162 line=149 + pc=5041979 func=175 file=54 line=124 + pc=5040762 func=53 file=54 line=70 + pc=5014167 func=55 file=56 line=154 + pc=5050219 func=98 file=58 line=78 + pc=5049860 func=99 file=58 line=68 + pc=5049861 func=100 file=58 line=64 + pc=4958364 func=101 file=61 line=651 + pc=4956653 func=102 file=61 line=616 + pc=4954291 func=103 file=61 line=517 + pc=4952889 func=104 file=61 line=508 + pc=4951126 func=105 file=61 line=434 + pc=4951127 func=106 file=61 line=401 + pc=5070980 func=63 file=28 line=68 +Stack id=23 nframes=1 + pc=4313376 func=80 file=81 line=1276 +Stack id=52 nframes=1 + pc=5071629 func=171 file=28 line=40 +Stack id=28 nframes=6 + pc=4637735 func=132 file=133 line=474 + pc=4307012 func=134 file=81 line=684 + pc=4255286 func=77 file=76 line=1292 + pc=4524282 func=139 file=79 line=246 + pc=5073584 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=12 nframes=1 + pc=5070234 func=63 file=28 line=27 +Stack id=76 nframes=1 + pc=5071200 func=117 file=28 line=58 +Stack id=60 nframes=5 + pc=4746660 func=150 file=30 line=432 + pc=4737232 func=151 file=152 line=118 + pc=4815748 func=176 file=146 line=218 + pc=4817144 func=177 file=178 line=21 + pc=5072014 func=89 file=28 line=82 +Stack id=64 nframes=1 + pc=5072608 func=88 file=28 line=89 +Stack id=47 nframes=11 + pc=4578453 func=67 file=68 line=352 + pc=4353540 func=69 file=70 line=521 + pc=4352604 func=179 file=70 line=389 + pc=4358543 func=180 file=70 line=926 + pc=4290148 func=71 file=72 line=84 + pc=4288626 func=73 file=74 line=182 + pc=4252996 func=75 file=76 line=948 + pc=4254486 func=77 file=76 line=1149 + pc=4522824 func=78 file=79 line=103 + pc=5073532 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=68 nframes=19 + pc=4745679 func=181 file=30 line=98 + pc=4814954 func=182 file=157 line=280 + pc=4814931 func=183 file=184 line=15 + pc=4816145 func=185 file=146 line=272 + pc=4814141 func=186 file=39 line=334 + pc=5034884 func=187 file=39 line=314 + pc=5034871 func=188 file=44 line=76 + pc=5039575 func=45 file=46 line=35 + pc=5060942 func=47 file=48 line=373 + pc=4696033 func=49 file=50 line=74 + pc=5026795 func=51 file=50 line=65 + pc=5026766 func=52 file=48 line=373 + pc=5040478 func=53 file=54 line=57 + pc=5014167 func=55 file=56 line=154 + pc=5051652 func=57 file=58 line=182 + pc=4960356 func=59 file=58 line=172 + pc=4960318 func=60 file=61 line=734 + pc=4961094 func=62 file=61 line=808 + pc=5070695 func=63 file=28 line=53 +Stack id=77 nframes=1 + pc=5070924 func=63 file=28 line=58 +Stack id=78 nframes=16 + pc=4749256 func=189 file=30 line=1442 + pc=4744549 func=190 file=32 line=298 + pc=4989295 func=174 file=162 line=59 + pc=5041979 func=175 file=54 line=124 + pc=5040762 func=53 file=54 line=70 + pc=5014167 func=55 file=56 line=154 + pc=5050219 func=98 file=58 line=78 + pc=5049860 func=99 file=58 line=68 + pc=5049861 func=100 file=58 line=64 + pc=4958364 func=101 file=61 line=651 + pc=4956653 func=102 file=61 line=616 + pc=4954291 func=103 file=61 line=517 + pc=4952889 func=104 file=61 line=508 + pc=4951126 func=105 file=61 line=434 + pc=4951127 func=106 file=61 line=401 + pc=5070980 func=63 file=28 line=68 +Stack id=54 nframes=1 + pc=5071968 func=89 file=28 line=81 +Stack id=32 nframes=2 + pc=4342189 func=191 file=192 line=425 + pc=4343672 func=193 file=192 line=658 +Stack id=57 nframes=5 + pc=4746660 func=150 file=30 line=432 + pc=4737158 func=151 file=152 line=106 + pc=4815748 func=176 file=146 line=218 + pc=4817109 func=177 file=178 line=21 + pc=5072014 func=89 file=28 line=82 +Stack id=74 nframes=10 + pc=4749032 func=194 file=30 line=1432 + pc=4744421 func=195 file=32 line=290 + pc=5044292 func=164 file=54 line=167 + pc=5040531 func=53 file=54 line=57 + pc=5014167 func=55 file=56 line=154 + pc=5051652 func=57 file=58 line=182 + pc=4960356 func=59 file=58 line=172 + pc=4960318 func=60 file=61 line=734 + pc=4961094 func=62 file=61 line=808 + pc=5070695 func=63 file=28 line=53 +Stack id=18 nframes=1 + pc=5069604 func=196 file=111 line=130 +Stack id=5 nframes=4 + pc=4570709 func=197 file=141 line=42 + pc=4561720 func=108 file=109 line=257 + pc=5069285 func=110 file=111 line=125 + pc=5070075 func=63 file=28 line=20 +Stack id=90 nframes=8 + pc=4750130 func=90 file=30 line=1488 + pc=4811799 func=91 file=32 line=462 + pc=4811777 func=92 file=93 line=17 + pc=5052347 func=94 file=95 line=18 + pc=5048264 func=96 file=97 line=245 + pc=5051452 func=115 file=58 line=156 + pc=5048431 func=116 file=97 line=315 + pc=5071227 func=117 file=28 line=59 +Stack id=33 nframes=7 + pc=4307927 func=82 file=81 line=807 + pc=4324210 func=198 file=199 line=564 + pc=4255603 func=200 file=76 line=1337 + pc=4253576 func=77 file=76 line=1025 + pc=4522824 func=78 file=79 line=103 + pc=5073532 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=70 nframes=19 + pc=4746660 func=150 file=30 line=432 + pc=4737232 func=151 file=152 line=118 + pc=4815748 func=176 file=146 line=218 + pc=4816367 func=185 file=146 line=301 + pc=4814141 func=186 file=39 line=334 + pc=5034884 func=187 file=39 line=314 + pc=5034871 func=188 file=44 line=76 + pc=5039575 func=45 file=46 line=35 + pc=5060942 func=47 file=48 line=373 + pc=4696033 func=49 file=50 line=74 + pc=5026795 func=51 file=50 line=65 + pc=5026766 func=52 file=48 line=373 + pc=5040478 func=53 file=54 line=57 + pc=5014167 func=55 file=56 line=154 + pc=5051652 func=57 file=58 line=182 + pc=4960356 func=59 file=58 line=172 + pc=4960318 func=60 file=61 line=734 + pc=4961094 func=62 file=61 line=808 + pc=5070695 func=63 file=28 line=53 +Stack id=8 nframes=1 + pc=5069536 func=196 file=111 line=128 +Stack id=15 nframes=2 + pc=4701031 func=201 file=25 line=116 + pc=5070313 func=63 file=28 line=29 +Stack id=86 nframes=7 + pc=4746903 func=29 file=30 line=736 + pc=4807597 func=31 file=32 line=181 + pc=4807573 func=33 file=34 line=736 + pc=4807216 func=35 file=34 line=160 + pc=4988612 func=167 file=130 line=55 + pc=5025316 func=168 file=48 line=179 + pc=5071115 func=63 file=28 line=73 +Stack id=67 nframes=1 + pc=0 func=0 file=0 line=0 +Stack id=80 nframes=15 + pc=4990958 func=202 file=34 line=683 + pc=4990987 func=174 file=162 line=141 + pc=5041979 func=175 file=54 line=124 + pc=5040762 func=53 file=54 line=70 + pc=5014167 func=55 file=56 line=154 + pc=5050219 func=98 file=58 line=78 + pc=5049860 func=99 file=58 line=68 + pc=5049861 func=100 file=58 line=64 + pc=4958364 func=101 file=61 line=651 + pc=4956653 func=102 file=61 line=616 + pc=4954291 func=103 file=61 line=517 + pc=4952889 func=104 file=61 line=508 + pc=4951126 func=105 file=61 line=434 + pc=4951127 func=106 file=61 line=401 + pc=5070980 func=63 file=28 line=68 +Stack id=93 nframes=7 + pc=4747354 func=83 file=30 line=964 + pc=4808839 func=84 file=32 line=209 + pc=4808831 func=33 file=34 line=736 + pc=4808384 func=85 file=34 line=380 + pc=4988868 func=203 file=130 line=96 + pc=5025764 func=204 file=48 line=191 + pc=5071301 func=117 file=28 line=65 +Stack id=46 nframes=1 + pc=5070323 func=63 file=28 line=32 +Stack id=25 nframes=5 + pc=4306780 func=134 file=81 line=663 + pc=4255286 func=77 file=76 line=1292 + pc=4524282 func=139 file=79 line=246 + pc=5073584 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=58 nframes=5 + pc=4746660 func=150 file=30 line=432 + pc=4737232 func=151 file=152 line=118 + pc=4815748 func=176 file=146 line=218 + pc=4817109 func=177 file=178 line=21 + pc=5072014 func=89 file=28 line=82 +Stack id=39 nframes=9 + pc=4365530 func=205 file=206 line=958 + pc=4291537 func=207 file=72 line=254 + pc=4291127 func=71 file=72 line=170 + pc=4288626 func=73 file=74 line=182 + pc=4252996 func=75 file=76 line=948 + pc=4254486 func=77 file=76 line=1149 + pc=4522824 func=78 file=79 line=103 + pc=5073532 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=2 nframes=3 + pc=4561444 func=108 file=109 line=238 + pc=5069285 func=110 file=111 line=125 + pc=5070075 func=63 file=28 line=20 +Stack id=50 nframes=1 + pc=5070361 func=63 file=28 line=38 +Stack id=10 nframes=1 + pc=5072672 func=208 file=28 line=97 +Stack id=41 nframes=4 + pc=4255286 func=77 file=76 line=1292 + pc=4522824 func=78 file=79 line=103 + pc=5073532 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=31 nframes=3 + pc=4522824 func=78 file=79 line=103 + pc=5073532 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=36 nframes=4 + pc=4637735 func=132 file=133 line=474 + pc=4309597 func=144 file=81 line=965 + pc=4308676 func=82 file=81 line=927 + pc=4314212 func=80 file=81 line=1446 +Stack id=69 nframes=19 + pc=4746660 func=150 file=30 line=432 + pc=4737158 func=151 file=152 line=106 + pc=4815748 func=176 file=146 line=218 + pc=4816367 func=185 file=146 line=301 + pc=4814141 func=186 file=39 line=334 + pc=5034884 func=187 file=39 line=314 + pc=5034871 func=188 file=44 line=76 + pc=5039575 func=45 file=46 line=35 + pc=5060942 func=47 file=48 line=373 + pc=4696033 func=49 file=50 line=74 + pc=5026795 func=51 file=50 line=65 + pc=5026766 func=52 file=48 line=373 + pc=5040478 func=53 file=54 line=57 + pc=5014167 func=55 file=56 line=154 + pc=5051652 func=57 file=58 line=182 + pc=4960356 func=59 file=58 line=172 + pc=4960318 func=60 file=61 line=734 + pc=4961094 func=62 file=61 line=808 + pc=5070695 func=63 file=28 line=53 +Stack id=59 nframes=5 + pc=4746660 func=150 file=30 line=432 + pc=4737158 func=151 file=152 line=106 + pc=4815748 func=176 file=146 line=218 + pc=4817144 func=177 file=178 line=21 + pc=5072014 func=89 file=28 line=82 +Stack id=30 nframes=7 + pc=4578913 func=209 file=68 line=378 + pc=4323996 func=198 file=199 line=536 + pc=4255603 func=200 file=76 line=1337 + pc=4253576 func=77 file=76 line=1025 + pc=4522824 func=78 file=79 line=103 + pc=5073532 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=51 nframes=2 + pc=4701031 func=201 file=25 line=116 + pc=5070481 func=63 file=28 line=43 +Stack id=49 nframes=1 + pc=5071552 func=171 file=28 line=38 +Stack id=29 nframes=5 + pc=4307322 func=134 file=81 line=746 + pc=4255286 func=77 file=76 line=1292 + pc=4524282 func=139 file=79 line=246 + pc=5073584 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=82 nframes=15 + pc=4750130 func=90 file=30 line=1488 + pc=4811799 func=91 file=32 line=462 + pc=4811777 func=92 file=93 line=17 + pc=5052074 func=113 file=114 line=15 + pc=5048202 func=96 file=97 line=239 + pc=5050832 func=98 file=58 line=114 + pc=5049860 func=99 file=58 line=68 + pc=5049861 func=100 file=58 line=64 + pc=4958364 func=101 file=61 line=651 + pc=4956653 func=102 file=61 line=616 + pc=4954291 func=103 file=61 line=517 + pc=4952889 func=104 file=61 line=508 + pc=4951126 func=105 file=61 line=434 + pc=4951127 func=106 file=61 line=401 + pc=5070980 func=63 file=28 line=68 +Stack id=27 nframes=4 + pc=4255286 func=77 file=76 line=1292 + pc=4524282 func=139 file=79 line=246 + pc=5073584 func=66 file=28 line=127 + pc=5070323 func=63 file=28 line=32 +Stack id=17 nframes=7 + pc=4747354 func=83 file=30 line=964 + pc=4808839 func=84 file=32 line=209 + pc=4808831 func=33 file=34 line=736 + pc=4808384 func=85 file=34 line=380 + pc=4813744 func=86 file=37 line=46 + pc=4813736 func=87 file=39 line=183 + pc=5069594 func=196 file=111 line=134 +EventBatch gen=1 m=18446744073709551615 time=420901448919 size=6914 +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="sync.(*WaitGroup).Add" +String id=25 + data="/usr/local/google/home/mknyszek/work/go-1/src/sync/waitgroup.go" +String id=26 + data="sync.(*WaitGroup).Done" +String id=27 + data="main.cpu20" +String id=28 + data="/usr/local/google/home/mknyszek/work/go-1/src/cmd/trace/v2/testdata/testprog/main.go" +String id=29 + data="syscall.read" +String id=30 + data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/zsyscall_linux_amd64.go" +String id=31 + data="syscall.Read" +String id=32 + data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/syscall_unix.go" +String id=33 + data="internal/poll.ignoringEINTRIO" +String id=34 + data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/fd_unix.go" +String id=35 + data="internal/poll.(*FD).Read" +String id=36 + data="os.(*File).read" +String id=37 + data="/usr/local/google/home/mknyszek/work/go-1/src/os/file_posix.go" +String id=38 + data="os.(*File).Read" +String id=39 + data="/usr/local/google/home/mknyszek/work/go-1/src/os/file.go" +String id=40 + data="io.ReadAtLeast" +String id=41 + data="/usr/local/google/home/mknyszek/work/go-1/src/io/io.go" +String id=42 + data="io.ReadFull" +String id=43 + data="net.(*file).readLine" +String id=44 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/parse.go" +String id=45 + data="net.maxListenerBacklog" +String id=46 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/sock_linux.go" +String id=47 + data="net.listenerBacklog.func1" +String id=48 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/net.go" +String id=49 + data="sync.(*Once).doSlow" +String id=50 + data="/usr/local/google/home/mknyszek/work/go-1/src/sync/once.go" +String id=51 + data="sync.(*Once).Do" +String id=52 + data="net.listenerBacklog" +String id=53 + data="net.socket" +String id=54 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/sock_posix.go" +String id=55 + data="net.internetSocket" +String id=56 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/ipsock_posix.go" +String id=57 + data="net.(*sysListener).listenTCPProto" +String id=58 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsock_posix.go" +String id=59 + data="net.(*sysListener).listenTCP" +String id=60 + data="net.(*ListenConfig).Listen" +String id=61 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/dial.go" +String id=62 + data="net.Listen" +String id=63 + data="main.main" +String id=64 + data="time.Sleep" +String id=65 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/time.go" +String id=66 + data="main.allocHog" +String id=67 + data="runtime.traceLocker.GCSweepSpan" +String id=68 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace2runtime.go" +String id=69 + data="runtime.(*sweepLocked).sweep" +String id=70 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgcsweep.go" +String id=71 + data="runtime.(*mcentral).cacheSpan" +String id=72 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mcentral.go" +String id=73 + data="runtime.(*mcache).refill" +String id=74 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mcache.go" +String id=75 + data="runtime.(*mcache).nextFree" +String id=76 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/malloc.go" +String id=77 + data="runtime.mallocgc" +String id=78 + data="runtime.makeslice" +String id=79 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/slice.go" +String id=80 + data="runtime.gcBgMarkWorker" +String id=81 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgc.go" +String id=82 + data="runtime.gcMarkDone" +String id=83 + data="syscall.write" +String id=84 + data="syscall.Write" +String id=85 + data="internal/poll.(*FD).Write" +String id=86 + data="os.(*File).write" +String id=87 + data="os.(*File).Write" +String id=88 + data="main.blockingSyscall.func1" +String id=89 + data="main.blockingSyscall" +String id=90 + data="syscall.setsockopt" +String id=91 + data="syscall.SetsockoptInt" +String id=92 + data="internal/poll.(*FD).SetsockoptInt" +String id=93 + data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/sockopt.go" +String id=94 + data="net.setKeepAlivePeriod" +String id=95 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsockopt_unix.go" +String id=96 + data="net.newTCPConn" +String id=97 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsock.go" +String id=98 + data="net.(*sysDialer).doDialTCPProto" +String id=99 + data="net.(*sysDialer).doDialTCP" +String id=100 + data="net.(*sysDialer).dialTCP" +String id=101 + data="net.(*sysDialer).dialSingle" +String id=102 + data="net.(*sysDialer).dialSerial" +String id=103 + data="net.(*sysDialer).dialParallel" +String id=104 + data="net.(*Dialer).DialContext" +String id=105 + data="net.(*Dialer).Dial" +String id=106 + data="net.Dial" +String id=107 + data="runtime.traceLocker.Gomaxprocs" +String id=108 + data="runtime.StartTrace" +String id=109 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace2.go" +String id=110 + data="runtime/trace.Start" +String id=111 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace/trace.go" +String id=112 + data="runtime.(*traceAdvancerState).start" +String id=113 + data="net.setNoDelay" +String id=114 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/tcpsockopt_posix.go" +String id=115 + data="net.(*TCPListener).accept" +String id=116 + data="net.(*TCPListener).Accept" +String id=117 + data="main.main.func2" +String id=118 + data="runtime.chanrecv1" +String id=119 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/chan.go" +String id=120 + data="runtime.(*wakeableSleep).sleep" +String id=121 + data="runtime.(*traceAdvancerState).start.func1" +String id=122 + data="syscall.Close" +String id=123 + data="internal/poll.(*SysFile).destroy" +String id=124 + data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/fd_unixjs.go" +String id=125 + data="internal/poll.(*FD).destroy" +String id=126 + data="internal/poll.(*FD).decref" +String id=127 + data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/fd_mutex.go" +String id=128 + data="internal/poll.(*FD).Close" +String id=129 + data="net.(*netFD).Close" +String id=130 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/fd_posix.go" +String id=131 + data="net.(*conn).Close" +String id=132 + data="runtime.systemstack_switch" +String id=133 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/asm_amd64.s" +String id=134 + data="runtime.gcStart" +String id=135 + data="runtime.gopark" +String id=136 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/proc.go" +String id=137 + data="runtime.chansend1" +String id=138 + data="runtime.gcBgMarkStartWorkers" +String id=139 + data="runtime.growslice" +String id=140 + data="runtime.traceStartReadCPU.func1" +String id=141 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/trace2cpu.go" +String id=142 + data="net.setKeepAlive" +String id=143 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/sockopt_posix.go" +String id=144 + data="runtime.gcMarkTermination" +String id=145 + data="os.(*file).close" +String id=146 + data="/usr/local/google/home/mknyszek/work/go-1/src/os/file_unix.go" +String id=147 + data="os.(*File).Close" +String id=148 + data="net.(*file).close" +String id=149 + data="runtime.startTheWorld" +String id=150 + data="syscall.fcntl" +String id=151 + data="syscall.SetNonblock" +String id=152 + data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/exec_unix.go" +String id=153 + data="internal/poll.(*FD).SetBlocking" +String id=154 + data="os.(*File).Fd" +String id=155 + data="syscall.accept4" +String id=156 + data="syscall.Accept4" +String id=157 + data="/usr/local/google/home/mknyszek/work/go-1/src/syscall/syscall_linux.go" +String id=158 + data="internal/poll.accept" +String id=159 + data="/usr/local/google/home/mknyszek/work/go-1/src/internal/poll/sock_cloexec.go" +String id=160 + data="internal/poll.(*FD).Accept" +String id=161 + data="net.(*netFD).accept" +String id=162 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/fd_unix.go" +String id=163 + data="syscall.Listen" +String id=164 + data="net.(*netFD).listenStream" +String id=165 + data="net.setDefaultListenerSockopts" +String id=166 + data="/usr/local/google/home/mknyszek/work/go-1/src/net/sockopt_linux.go" +String id=167 + data="net.(*netFD).Read" +String id=168 + data="net.(*conn).Read" +String id=169 + data="runtime.goparkunlock" +String id=170 + data="runtime.bgsweep" +String id=171 + data="main.main.func1" +String id=172 + data="syscall.getsockopt" +String id=173 + data="syscall.GetsockoptInt" +String id=174 + data="net.(*netFD).connect" +String id=175 + data="net.(*netFD).dial" +String id=176 + data="os.newFile" +String id=177 + data="os.Pipe" +String id=178 + data="/usr/local/google/home/mknyszek/work/go-1/src/os/pipe2_unix.go" +String id=179 + data="runtime.sweepone" +String id=180 + data="runtime.deductSweepCredit" +String id=181 + data="syscall.openat" +String id=182 + data="syscall.Open" +String id=183 + data="os.open" +String id=184 + data="/usr/local/google/home/mknyszek/work/go-1/src/os/file_open_unix.go" +String id=185 + data="os.openFileNolog" +String id=186 + data="os.OpenFile" +String id=187 + data="os.Open" +String id=188 + data="net.open" +String id=189 + data="syscall.connect" +String id=190 + data="syscall.Connect" +String id=191 + data="runtime.(*scavengerState).park" +String id=192 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgcscavenge.go" +String id=193 + data="runtime.bgscavenge" +String id=194 + data="syscall.bind" +String id=195 + data="syscall.Bind" +String id=196 + data="runtime/trace.Start.func1" +String id=197 + data="runtime.traceStartReadCPU" +String id=198 + data="runtime.gcAssistAlloc" +String id=199 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mgcmark.go" +String id=200 + data="runtime.deductAssistCredit" +String id=201 + data="sync.(*WaitGroup).Wait" +String id=202 + data="internal/poll.(*FD).WaitWrite" +String id=203 + data="net.(*netFD).Write" +String id=204 + data="net.(*conn).Write" +String id=205 + data="runtime.(*mheap).alloc" +String id=206 + data="/usr/local/google/home/mknyszek/work/go-1/src/runtime/mheap.go" +String id=207 + data="runtime.(*mcentral).grow" +String id=208 + data="main.cpu10" +String id=209 + data="runtime.traceLocker.GCMarkAssistStart" diff --git a/src/cmd/trace/v2/testdata/mktests.go b/src/cmd/trace/v2/testdata/mktests.go new file mode 100644 index 0000000000..143e8ece35 --- /dev/null +++ b/src/cmd/trace/v2/testdata/mktests.go @@ -0,0 +1,60 @@ +// 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") + // TODO(mknyszek): Remove if goexperiment.Exectracer2 becomes the default. + cmd.Env = append(os.Environ(), "GOEXPERIMENT=exectracer2") + 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 new file mode 100644 index 0000000000..fcf4dc156c --- /dev/null +++ b/src/cmd/trace/v2/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/v2/viewer.go b/src/cmd/trace/v2/viewer.go new file mode 100644 index 0000000000..de67fc4e0e --- /dev/null +++ b/src/cmd/trace/v2/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 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/go/build/deps_test.go b/src/go/build/deps_test.go index 3d54fc7aac..a6b1a613bb 100644 --- a/src/go/build/deps_test.go +++ b/src/go/build/deps_test.go @@ -45,6 +45,7 @@ var depsRules = ` internal/cpu, internal/goarch, internal/godebugs, internal/goexperiment, internal/goos, internal/goversion, internal/nettrace, internal/platform, + internal/trace/traceviewer/format, log/internal, unicode/utf8, unicode/utf16, unicode, unsafe; @@ -633,6 +634,16 @@ var depsRules = ` FMT, container/heap, math/rand, internal/trace/v2 < internal/trace; + # cmd/trace dependencies. + FMT, + embed, + encoding/json, + html/template, + internal/trace, + internal/trace/traceviewer/format, + net/http + < internal/trace/traceviewer; + # Coverage. FMT, crypto/md5, encoding/binary, regexp, sort, text/tabwriter, unsafe, internal/coverage, internal/coverage/uleb128 diff --git a/src/internal/trace/parser.go b/src/internal/trace/parser.go index 67fa60b8fb..3bbfbebab4 100644 --- a/src/internal/trace/parser.go +++ b/src/internal/trace/parser.go @@ -136,17 +136,23 @@ type rawEvent struct { sargs []string } -// readTrace does wire-format parsing and verification. -// It does not care about specific event types and argument meaning. -func readTrace(r io.Reader) (ver int, events []rawEvent, strings map[uint64]string, err error) { +func ReadVersion(r io.Reader) (ver int, off int, err error) { // Read and validate trace header. var buf [16]byte - off, err := io.ReadFull(r, buf[:]) + off, err = io.ReadFull(r, buf[:]) if err != nil { err = fmt.Errorf("failed to read header: read %v, err %v", off, err) return } ver, err = parseHeader(buf[:]) + return +} + +// readTrace does wire-format parsing and verification. +// It does not care about specific event types and argument meaning. +func readTrace(r io.Reader) (ver int, events []rawEvent, strings map[uint64]string, err error) { + var off int + ver, off, err = ReadVersion(r) if err != nil { return } @@ -161,6 +167,7 @@ func readTrace(r io.Reader) (ver int, events []rawEvent, strings map[uint64]stri } // Read events. + var buf [16]byte strings = make(map[uint64]string) for { // Read event type and number of arguments (1 byte). diff --git a/src/internal/trace/traceviewer/emitter.go b/src/internal/trace/traceviewer/emitter.go new file mode 100644 index 0000000000..95cb1f3271 --- /dev/null +++ b/src/internal/trace/traceviewer/emitter.go @@ -0,0 +1,666 @@ +// 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 traceviewer + +import ( + "encoding/json" + "fmt" + "internal/trace" + "internal/trace/traceviewer/format" + "io" + "strconv" + "time" +) + +type TraceConsumer struct { + ConsumeTimeUnit func(unit string) + ConsumeViewerEvent func(v *format.Event, required bool) + ConsumeViewerFrame func(key string, f format.Frame) + Flush func() +} + +// ViewerDataTraceConsumer returns a TraceConsumer that writes to w. The +// startIdx and endIdx are used for splitting large traces. They refer to +// indexes in the traceEvents output array, not the events in the trace input. +func ViewerDataTraceConsumer(w io.Writer, startIdx, endIdx int64) TraceConsumer { + allFrames := make(map[string]format.Frame) + requiredFrames := make(map[string]format.Frame) + enc := json.NewEncoder(w) + written := 0 + index := int64(-1) + + io.WriteString(w, "{") + return TraceConsumer{ + ConsumeTimeUnit: func(unit string) { + io.WriteString(w, `"displayTimeUnit":`) + enc.Encode(unit) + io.WriteString(w, ",") + }, + ConsumeViewerEvent: func(v *format.Event, required bool) { + index++ + if !required && (index < startIdx || index > endIdx) { + // not in the range. Skip! + return + } + WalkStackFrames(allFrames, v.Stack, func(id int) { + s := strconv.Itoa(id) + requiredFrames[s] = allFrames[s] + }) + WalkStackFrames(allFrames, v.EndStack, func(id int) { + s := strconv.Itoa(id) + requiredFrames[s] = allFrames[s] + }) + if written == 0 { + io.WriteString(w, `"traceEvents": [`) + } + if written > 0 { + io.WriteString(w, ",") + } + enc.Encode(v) + // TODO(mknyszek): get rid of the extra \n inserted by enc.Encode. + // Same should be applied to splittingTraceConsumer. + written++ + }, + ConsumeViewerFrame: func(k string, v format.Frame) { + allFrames[k] = v + }, + Flush: func() { + io.WriteString(w, `], "stackFrames":`) + enc.Encode(requiredFrames) + io.WriteString(w, `}`) + }, + } +} + +func SplittingTraceConsumer(max int) (*splitter, TraceConsumer) { + type eventSz struct { + Time float64 + Sz int + Frames []int + } + + var ( + // data.Frames contains only the frames for required events. + data = format.Data{Frames: make(map[string]format.Frame)} + + allFrames = make(map[string]format.Frame) + + sizes []eventSz + cw countingWriter + ) + + s := new(splitter) + + return s, TraceConsumer{ + ConsumeTimeUnit: func(unit string) { + data.TimeUnit = unit + }, + ConsumeViewerEvent: func(v *format.Event, required bool) { + if required { + // Store required events inside data so flush + // can include them in the required part of the + // trace. + data.Events = append(data.Events, v) + WalkStackFrames(allFrames, v.Stack, func(id int) { + s := strconv.Itoa(id) + data.Frames[s] = allFrames[s] + }) + WalkStackFrames(allFrames, v.EndStack, func(id int) { + s := strconv.Itoa(id) + data.Frames[s] = allFrames[s] + }) + return + } + enc := json.NewEncoder(&cw) + enc.Encode(v) + size := eventSz{Time: v.Time, Sz: cw.size + 1} // +1 for ",". + // Add referenced stack frames. Their size is computed + // in flush, where we can dedup across events. + WalkStackFrames(allFrames, v.Stack, func(id int) { + size.Frames = append(size.Frames, id) + }) + WalkStackFrames(allFrames, v.EndStack, func(id int) { + size.Frames = append(size.Frames, id) // This may add duplicates. We'll dedup later. + }) + sizes = append(sizes, size) + cw.size = 0 + }, + ConsumeViewerFrame: func(k string, v format.Frame) { + allFrames[k] = v + }, + Flush: func() { + // Calculate size of the mandatory part of the trace. + // This includes thread names and stack frames for + // required events. + cw.size = 0 + enc := json.NewEncoder(&cw) + enc.Encode(data) + requiredSize := cw.size + + // Then calculate size of each individual event and + // their stack frames, grouping them into ranges. We + // only include stack frames relevant to the events in + // the range to reduce overhead. + + var ( + start = 0 + + eventsSize = 0 + + frames = make(map[string]format.Frame) + framesSize = 0 + ) + for i, ev := range sizes { + eventsSize += ev.Sz + + // Add required stack frames. Note that they + // may already be in the map. + for _, id := range ev.Frames { + s := strconv.Itoa(id) + _, ok := frames[s] + if ok { + continue + } + f := allFrames[s] + frames[s] = f + framesSize += stackFrameEncodedSize(uint(id), f) + } + + total := requiredSize + framesSize + eventsSize + if total < max { + continue + } + + // Reached max size, commit this range and + // start a new range. + startTime := time.Duration(sizes[start].Time * 1000) + endTime := time.Duration(ev.Time * 1000) + s.Ranges = append(s.Ranges, Range{ + Name: fmt.Sprintf("%v-%v", startTime, endTime), + Start: start, + End: i + 1, + StartTime: int64(startTime), + EndTime: int64(endTime), + }) + start = i + 1 + frames = make(map[string]format.Frame) + framesSize = 0 + eventsSize = 0 + } + if len(s.Ranges) <= 1 { + s.Ranges = nil + return + } + + if end := len(sizes) - 1; start < end { + s.Ranges = append(s.Ranges, Range{ + Name: fmt.Sprintf("%v-%v", time.Duration(sizes[start].Time*1000), time.Duration(sizes[end].Time*1000)), + Start: start, + End: end, + StartTime: int64(sizes[start].Time * 1000), + EndTime: int64(sizes[end].Time * 1000), + }) + } + }, + } +} + +type splitter struct { + Ranges []Range +} + +type countingWriter struct { + size int +} + +func (cw *countingWriter) Write(data []byte) (int, error) { + cw.size += len(data) + return len(data), nil +} + +func stackFrameEncodedSize(id uint, f format.Frame) int { + // We want to know the marginal size of traceviewer.Data.Frames for + // each event. Running full JSON encoding of the map for each event is + // far too slow. + // + // Since the format is fixed, we can easily compute the size without + // encoding. + // + // A single entry looks like one of the following: + // + // "1":{"name":"main.main:30"}, + // "10":{"name":"pkg.NewSession:173","parent":9}, + // + // The parent is omitted if 0. The trailing comma is omitted from the + // last entry, but we don't need that much precision. + const ( + baseSize = len(`"`) + len(`":{"name":"`) + len(`"},`) + + // Don't count the trailing quote on the name, as that is + // counted in baseSize. + parentBaseSize = len(`,"parent":`) + ) + + size := baseSize + + size += len(f.Name) + + // Bytes for id (always positive). + for id > 0 { + size += 1 + id /= 10 + } + + if f.Parent > 0 { + size += parentBaseSize + // Bytes for parent (always positive). + for f.Parent > 0 { + size += 1 + f.Parent /= 10 + } + } + + return size +} + +// WalkStackFrames calls fn for id and all of its parent frames from allFrames. +func WalkStackFrames(allFrames map[string]format.Frame, id int, fn func(id int)) { + for id != 0 { + f, ok := allFrames[strconv.Itoa(id)] + if !ok { + break + } + fn(id) + id = f.Parent + } +} + +type Mode int + +const ( + ModeGoroutineOriented Mode = 1 << iota + ModeTaskOriented +) + +// NewEmitter returns a new Emitter that writes to c. The rangeStart and +// rangeEnd args are used for splitting large traces. +func NewEmitter(c TraceConsumer, mode Mode, rangeStart, rangeEnd time.Duration) *Emitter { + c.ConsumeTimeUnit("ns") + + return &Emitter{ + c: c, + mode: mode, + rangeStart: rangeStart, + rangeEnd: rangeEnd, + frameTree: frameNode{children: make(map[uint64]frameNode)}, + resources: make(map[uint64]string), + } +} + +type Emitter struct { + c TraceConsumer + mode Mode + rangeStart time.Duration + rangeEnd time.Duration + + heapStats, prevHeapStats heapStats + gstates, prevGstates [gStateCount]int64 + threadStats, prevThreadStats [threadStateCount]int64 + gomaxprocs uint64 + frameTree frameNode + frameSeq int + arrowSeq uint64 + filter func(uint64) bool + resourceType string + resources map[uint64]string + focusResource uint64 +} + +func (e *Emitter) Gomaxprocs(v uint64) { + if v > e.gomaxprocs { + e.gomaxprocs = v + } +} + +func (e *Emitter) Resource(id uint64, name string) { + if e.filter != nil && !e.filter(id) { + return + } + e.resources[id] = name +} + +func (e *Emitter) SetResourceType(name string) { + e.resourceType = name +} + +func (e *Emitter) SetResourceFilter(filter func(uint64) bool) { + e.filter = filter +} + +func (e *Emitter) Slice(s SliceEvent) { + if !e.tsWithinRange(s.Ts) && !e.tsWithinRange(s.Ts+s.Dur) { + return + } + if e.filter != nil && !e.filter(s.Resource) { + return + } + e.OptionalEvent(&format.Event{ + Name: s.Name, + Phase: "X", + Time: viewerTime(s.Ts), + Dur: viewerTime(s.Dur), + TID: s.Resource, + Stack: s.Stack, + EndStack: s.EndStack, + Arg: s.Arg, + }) +} + +type SliceEvent struct { + Name string + Ts time.Duration + Dur time.Duration + Resource uint64 + Stack int + EndStack int + Arg any +} + +func (e *Emitter) Instant(i InstantEvent) { + if !e.tsWithinRange(i.Ts) { + return + } + if e.filter != nil && !e.filter(i.Resource) { + return + } + // TODO(mknyszek): Handle ModeTaskOriented here. See cmd/trace.(*traceContext).emitInstant. + cname := "" + e.OptionalEvent(&format.Event{ + Name: i.Name, + Category: i.Category, + Phase: "I", + Scope: "t", + Time: viewerTime(i.Ts), + TID: i.Resource, + Stack: i.Stack, + Cname: cname, + Arg: i.Arg, + }) +} + +type InstantEvent struct { + Ts time.Duration + Name string + Category string + Resource uint64 + Stack int + Arg any +} + +func (e *Emitter) Arrow(a ArrowEvent) { + if !e.tsWithinRange(a.Start) || !e.tsWithinRange(a.End) { + return + } + if e.filter != nil && (!e.filter(a.FromResource) || !e.filter(a.ToResource)) { + return + } + // TODO(mknyszek): Handle ModeTaskOriented here. See cmd/trace.(*traceContext).emitArrow. + e.arrowSeq++ + e.OptionalEvent(&format.Event{ + Name: a.Name, + Phase: "s", + TID: a.FromResource, + ID: e.arrowSeq, + Time: viewerTime(a.Start), + Stack: a.FromStack, + }) + e.OptionalEvent(&format.Event{ + Name: a.Name, + Phase: "t", + TID: a.ToResource, + ID: e.arrowSeq, + Time: viewerTime(a.End), + }) +} + +type ArrowEvent struct { + Name string + Start time.Duration + End time.Duration + FromResource uint64 + FromStack int + ToResource uint64 +} + +func (e *Emitter) Event(ev *format.Event) { + e.c.ConsumeViewerEvent(ev, true) +} + +func (e *Emitter) HeapAlloc(ts time.Duration, v uint64) { + e.heapStats.heapAlloc = v + e.emitHeapCounters(ts) +} + +func (e *Emitter) Focus(id uint64) { + e.focusResource = id +} + +func (e *Emitter) GoroutineTransition(ts time.Duration, from, to GState) { + e.gstates[from]-- + e.gstates[to]++ + if e.prevGstates == e.gstates { + return + } + if e.tsWithinRange(ts) { + e.OptionalEvent(&format.Event{ + Name: "Goroutines", + Phase: "C", + Time: viewerTime(ts), + PID: 1, + Arg: &format.GoroutineCountersArg{ + Running: uint64(e.gstates[GRunning]), + Runnable: uint64(e.gstates[GRunnable]), + GCWaiting: uint64(e.gstates[GWaitingGC]), + }, + }) + } + e.prevGstates = e.gstates +} + +func (e *Emitter) IncThreadStateCount(ts time.Duration, state ThreadState, delta int64) { + e.threadStats[state] += delta + if e.prevThreadStats == e.threadStats { + return + } + if e.tsWithinRange(ts) { + e.OptionalEvent(&format.Event{ + Name: "Threads", + Phase: "C", + Time: viewerTime(ts), + PID: 1, + Arg: &format.ThreadCountersArg{ + Running: int64(e.threadStats[ThreadStateRunning]), + InSyscall: int64(e.threadStats[ThreadStateInSyscall]), + // TODO(mknyszek): Why is InSyscallRuntime not included here? + }, + }) + } + e.prevThreadStats = e.threadStats +} + +func (e *Emitter) HeapGoal(ts time.Duration, v uint64) { + // This cutoff at 1 PiB is a Workaround for https://github.com/golang/go/issues/63864. + // + // TODO(mknyszek): Remove this once the problem has been fixed. + const PB = 1 << 50 + if v > PB { + v = 0 + } + e.heapStats.nextGC = v + e.emitHeapCounters(ts) +} + +func (e *Emitter) emitHeapCounters(ts time.Duration) { + if e.prevHeapStats == e.heapStats { + return + } + diff := uint64(0) + if e.heapStats.nextGC > e.heapStats.heapAlloc { + diff = e.heapStats.nextGC - e.heapStats.heapAlloc + } + if e.tsWithinRange(ts) { + e.OptionalEvent(&format.Event{ + Name: "Heap", + Phase: "C", + Time: viewerTime(ts), + PID: 1, + Arg: &format.HeapCountersArg{Allocated: e.heapStats.heapAlloc, NextGC: diff}, + }) + } + e.prevHeapStats = e.heapStats +} + +// Err returns an error if the emitter is in an invalid state. +func (e *Emitter) Err() error { + if e.gstates[GRunnable] < 0 || e.gstates[GRunning] < 0 || e.threadStats[ThreadStateInSyscall] < 0 || e.threadStats[ThreadStateInSyscallRuntime] < 0 { + return fmt.Errorf( + "runnable=%d running=%d insyscall=%d insyscallRuntime=%d", + e.gstates[GRunnable], + e.gstates[GRunning], + e.threadStats[ThreadStateInSyscall], + e.threadStats[ThreadStateInSyscallRuntime], + ) + } + return nil +} + +func (e *Emitter) tsWithinRange(ts time.Duration) bool { + return e.rangeStart <= ts && ts <= e.rangeEnd +} + +// OptionalEvent emits ev if it's within the time range of of the consumer, i.e. +// the selected trace split range. +func (e *Emitter) OptionalEvent(ev *format.Event) { + e.c.ConsumeViewerEvent(ev, false) +} + +func (e *Emitter) Flush() { + e.processMeta(format.StatsSection, "STATS", 0) + if e.mode&ModeTaskOriented != 0 { + e.processMeta(format.TasksSection, "TASKS", 1) + } + + e.processMeta(format.ProcsSection, e.resourceType, 2) + + e.threadMeta(format.ProcsSection, trace.GCP, "GC", -6) + e.threadMeta(format.ProcsSection, trace.NetpollP, "Network", -5) + e.threadMeta(format.ProcsSection, trace.TimerP, "Timers", -4) + e.threadMeta(format.ProcsSection, trace.SyscallP, "Syscalls", -3) + + for id, name := range e.resources { + priority := int(id) + if e.focusResource != 0 && id == e.focusResource { + // Put the focus goroutine on top. + priority = -2 + } + e.threadMeta(format.ProcsSection, id, name, priority) + } + + e.c.Flush() +} + +func (e *Emitter) threadMeta(sectionID, tid uint64, name string, priority int) { + e.Event(&format.Event{ + Name: "thread_name", + Phase: "M", + PID: sectionID, + TID: tid, + Arg: &format.NameArg{Name: name}, + }) + e.Event(&format.Event{ + Name: "thread_sort_index", + Phase: "M", + PID: sectionID, + TID: tid, + Arg: &format.SortIndexArg{Index: priority}, + }) +} + +func (e *Emitter) processMeta(sectionID uint64, name string, priority int) { + e.Event(&format.Event{ + Name: "process_name", + Phase: "M", + PID: sectionID, + Arg: &format.NameArg{Name: name}, + }) + e.Event(&format.Event{ + Name: "process_sort_index", + Phase: "M", + PID: sectionID, + Arg: &format.SortIndexArg{Index: priority}, + }) +} + +// Stack emits the given frames and returns a unique id for the stack. No +// pointers to the given data are being retained beyond the call to Stack. +func (e *Emitter) Stack(stk []*trace.Frame) int { + return e.buildBranch(e.frameTree, stk) +} + +// buildBranch builds one branch in the prefix tree rooted at ctx.frameTree. +func (e *Emitter) buildBranch(parent frameNode, stk []*trace.Frame) int { + if len(stk) == 0 { + return parent.id + } + last := len(stk) - 1 + frame := stk[last] + stk = stk[:last] + + node, ok := parent.children[frame.PC] + if !ok { + e.frameSeq++ + node.id = e.frameSeq + node.children = make(map[uint64]frameNode) + parent.children[frame.PC] = node + e.c.ConsumeViewerFrame(strconv.Itoa(node.id), format.Frame{Name: fmt.Sprintf("%v:%v", frame.Fn, frame.Line), Parent: parent.id}) + } + return e.buildBranch(node, stk) +} + +type heapStats struct { + heapAlloc uint64 + nextGC uint64 +} + +func viewerTime(t time.Duration) float64 { + return float64(t) / float64(time.Microsecond) +} + +type GState int + +const ( + GDead GState = iota + GRunnable + GRunning + GWaiting + GWaitingGC + + gStateCount +) + +type ThreadState int + +const ( + ThreadStateInSyscall ThreadState = iota + ThreadStateInSyscallRuntime + ThreadStateRunning + + threadStateCount +) + +type frameNode struct { + id int + children map[uint64]frameNode +} diff --git a/src/cmd/internal/traceviewer/format.go b/src/internal/trace/traceviewer/format/format.go similarity index 60% rename from src/cmd/internal/traceviewer/format.go rename to src/internal/trace/traceviewer/format/format.go index 3636c1053d..83f3276704 100644 --- a/src/cmd/internal/traceviewer/format.go +++ b/src/internal/trace/traceviewer/format/format.go @@ -7,7 +7,10 @@ // // The official description of the format is in this file: // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview -package traceviewer +// +// Note: This can't be part of the parent traceviewer package as that would +// throw. go_bootstrap cannot depend on the cgo version of package net in ./make.bash. +package format type Data struct { Events []*Event `json:"traceEvents"` @@ -36,3 +39,41 @@ type Frame struct { Name string `json:"name"` Parent int `json:"parent,omitempty"` } + +type NameArg struct { + Name string `json:"name"` +} + +type BlockedArg struct { + Blocked string `json:"blocked"` +} + +type SortIndexArg struct { + Index int `json:"sort_index"` +} + +type HeapCountersArg struct { + Allocated uint64 + NextGC uint64 +} + +const ( + ProcsSection = 0 // where Goroutines or per-P timelines are presented. + StatsSection = 1 // where counters are presented. + TasksSection = 2 // where Task hierarchy & timeline is presented. +) + +type GoroutineCountersArg struct { + Running uint64 + Runnable uint64 + GCWaiting uint64 +} + +type ThreadCountersArg struct { + Running int64 + InSyscall int64 +} + +type ThreadIDArg struct { + ThreadID uint64 +} diff --git a/src/internal/trace/traceviewer/http.go b/src/internal/trace/traceviewer/http.go new file mode 100644 index 0000000000..0c58535a72 --- /dev/null +++ b/src/internal/trace/traceviewer/http.go @@ -0,0 +1,375 @@ +// 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 traceviewer + +import ( + "embed" + "fmt" + "html/template" + "net/http" + "strings" +) + +func MainHandler(ranges []Range) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + if err := templMain.Execute(w, ranges); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + }) +} + +var templMain = template.Must(template.New("").Parse(` + + + +

cmd/trace: the Go trace event viewer

+

+ This web server provides various visualizations of an event log gathered during + the execution of a Go program that uses the runtime/trace package. +

+ +

Event timelines for running goroutines

+{{if $}} +

+ Large traces are split into multiple sections of equal data size + (not duration) to avoid overwhelming the visualizer. +

+ +{{else}} + +{{end}} +

+ This view displays a timeline for each of the GOMAXPROCS logical + processors, showing which goroutine (if any) was running on that + logical processor at each moment. + + Each goroutine has an identifying number (e.g. G123), main function, + and color. + + A colored bar represents an uninterrupted span of execution. + + Execution of a goroutine may migrate from one logical processor to another, + causing a single colored bar to be horizontally continuous but + vertically displaced. +

+

+ Clicking on a span reveals information about it, such as its + duration, its causal predecessors and successors, and the stack trace + at the final moment when it yielded the logical processor, for example + because it made a system call or tried to acquire a mutex. + + Directly underneath each bar, a smaller bar or more commonly a fine + vertical line indicates an event occurring during its execution. + Some of these are related to garbage collection; most indicate that + a goroutine yielded its logical processor but then immediately resumed execution + on the same logical processor. Clicking on the event displays the stack trace + at the moment it occurred. +

+

+ The causal relationships between spans of goroutine execution + can be displayed by clicking the Flow Events button at the top. +

+

+ At the top ("STATS"), there are three additional timelines that + display statistical information. + + "Goroutines" is a time series of the count of existing goroutines; + clicking on it displays their breakdown by state at that moment: + running, runnable, or waiting. + + "Heap" is a time series of the amount of heap memory allocated (in orange) + and (in green) the allocation limit at which the next GC cycle will begin. + + "Threads" shows the number of kernel threads in existence: there is + always one kernel thread per logical processor, and additional threads + are created for calls to non-Go code such as a system call or a + function written in C. +

+

+ Above the event trace for the first logical processor are + traces for various runtime-internal events. + + The "GC" bar shows when the garbage collector is running, and in which stage. + Garbage collection may temporarily affect all the logical processors + and the other metrics. + + The "Network", "Timers", and "Syscalls" traces indicate events in + the runtime that cause goroutines to wake up. +

+

+ The visualization allows you to navigate events at scales ranging from several + seconds to a handful of nanoseconds. + + Consult the documentation for the Chromium Trace Event Profiling Tool + for help navigating the view. +

+ + +

+ This view displays information about each set of goroutines that + shares the same main function. + + Clicking on a main function shows links to the four types of + blocking profile (see below) applied to that subset of goroutines. + + It also shows a table of specific goroutine instances, with various + execution statistics and a link to the event timeline for each one. + + The timeline displays only the selected goroutine and any others it + interacts with via block/unblock events. (The timeline is + goroutine-oriented rather than logical processor-oriented.) +

+ +

Profiles

+

+ Each link below displays a global profile in zoomable graph form as + produced by pprof's "web" command. + + In addition there is a link to download the profile for offline + analysis with pprof. + + All four profiles represent causes of delay that prevent a goroutine + from running on a logical processor: because it was waiting for the network, + for a synchronization operation on a mutex or channel, for a system call, + or for a logical processor to become available. +

+ + +

User-defined tasks and regions

+

+ The trace API allows a target program to annotate a region of code + within a goroutine, such as a key function, so that its performance + can be analyzed. + + Log events may be + associated with a region to record progress and relevant values. + + The API also allows annotation of higher-level + tasks, + which may involve work across many goroutines. +

+

+ The links below display, for each region and task, a histogram of its execution times. + + Each histogram bucket contains a sample trace that records the + sequence of events such as goroutine creations, log events, and + subregion start/end times. + + For each task, you can click through to a logical-processor or + goroutine-oriented view showing the tasks and regions on the + timeline. + + Such information may help uncover which steps in a region are + unexpectedly slow, or reveal relationships between the data values + logged in a request and its running time. +

+ + +

Garbage collection metrics

+ +

+ This chart indicates the maximum GC pause time (the largest x value + for which y is zero), and more generally, the fraction of time that + the processors are available to application goroutines ("mutators"), + for any time window of a specified size, in the worst case. +

+ + +`)) + +type Range struct { + Name string + Start int + End int + StartTime int64 + EndTime int64 +} + +func (r Range) URL() string { + return fmt.Sprintf("/trace?start=%d&end=%d", r.Start, r.End) +} + +func TraceHandler() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if err := r.ParseForm(); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + html := strings.ReplaceAll(templTrace, "{{PARAMS}}", r.Form.Encode()) + w.Write([]byte(html)) + }) +} + +// https://chromium.googlesource.com/catapult/+/9508452e18f130c98499cb4c4f1e1efaedee8962/tracing/docs/embedding-trace-viewer.md +// This is almost verbatim copy of https://chromium-review.googlesource.com/c/catapult/+/2062938/2/tracing/bin/index.html +var templTrace = ` + + + + + + + + + + + + + +` + +//go:embed static/trace_viewer_full.html static/webcomponents.min.js +var staticContent embed.FS + +func StaticHandler() http.Handler { + return http.FileServer(http.FS(staticContent)) +} diff --git a/src/cmd/trace/static/README.md b/src/internal/trace/traceviewer/static/README.md similarity index 100% rename from src/cmd/trace/static/README.md rename to src/internal/trace/traceviewer/static/README.md diff --git a/src/cmd/trace/static/trace_viewer_full.html b/src/internal/trace/traceviewer/static/trace_viewer_full.html similarity index 100% rename from src/cmd/trace/static/trace_viewer_full.html rename to src/internal/trace/traceviewer/static/trace_viewer_full.html diff --git a/src/cmd/trace/static/webcomponents.min.js b/src/internal/trace/traceviewer/static/webcomponents.min.js similarity index 100% rename from src/cmd/trace/static/webcomponents.min.js rename to src/internal/trace/traceviewer/static/webcomponents.min.js diff --git a/src/internal/trace/v2/version/version.go b/src/internal/trace/v2/version/version.go index bb4df8469e..28189f80db 100644 --- a/src/internal/trace/v2/version/version.go +++ b/src/internal/trace/v2/version/version.go @@ -16,7 +16,8 @@ import ( type Version uint32 const ( - Go122 Version = 22 + Go122 Version = 22 + Current = Go122 ) var versions = map[Version][]event.Spec{ -- 2.48.1