diff options
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/trace/annotation_test.go | 13 | ||||
| -rw-r--r-- | src/runtime/tracestring.go | 5 |
2 files changed, 18 insertions, 0 deletions
diff --git a/src/runtime/trace/annotation_test.go b/src/runtime/trace/annotation_test.go index ea10843230..63e01fab9c 100644 --- a/src/runtime/trace/annotation_test.go +++ b/src/runtime/trace/annotation_test.go @@ -8,9 +8,22 @@ import ( "context" "io" . "runtime/trace" + "strings" "testing" ) +func TestStartRegionLongString(t *testing.T) { + // Regression test: a region name longer than the trace region + // allocator's block size (~64KB) used to crash with + // "traceRegion: alloc too large" because traceStringTable.put + // inserted the full string into the trace map before truncation. + Start(io.Discard) + defer Stop() + + big := strings.Repeat("x", 70_000) + StartRegion(context.Background(), big).End() +} + func BenchmarkStartRegion(b *testing.B) { b.ReportAllocs() ctx, task := NewTask(context.Background(), "benchmark") diff --git a/src/runtime/tracestring.go b/src/runtime/tracestring.go index bd31f06a67..d85299441b 100644 --- a/src/runtime/tracestring.go +++ b/src/runtime/tracestring.go @@ -25,6 +25,11 @@ type traceStringTable struct { // put adds a string to the table, emits it, and returns a unique ID for it. func (t *traceStringTable) put(gen uintptr, s string) uint64 { + // Truncate the string now to avoid wasting space in the + // traceMap and to stay within traceRegionAlloc's block size limit. + if len(s) > tracev2.MaxEventTrailerDataSize { + s = s[:tracev2.MaxEventTrailerDataSize] + } // Put the string in the table. ss := stringStructOf(&s) id, added := t.tab.put(ss.str, uintptr(ss.len)) |
