Skip to content

Commit 2bcc4d2

Browse files
committed
gopls/internal/test/integration/web: kill "go tool trace" processes
Clearly our cleanup mechanism isn't good enough since it causes "go tool trace" processes to accumulate on builder machines, causing OOM on ppc. Explicitly kill traceviewers once the test finishes. This is a global hammer that won't play nicely with multiple concurrent tests of FlightRecorder. (Currently there is only a single test.) Fixes golang/go#74668 Updates golang/go#73988 Change-Id: Iea823619d188d0d4ae1157d27c90fc6a2fc34617 Reviewed-on: https://go-review.googlesource.com/c/tools/+/689195 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Michael Pratt <[email protected]>
1 parent 097b217 commit 2bcc4d2

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

gopls/internal/debug/flight.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,22 @@ import (
2020
"time"
2121
)
2222

23+
var (
24+
traceviewersMu sync.Mutex
25+
traceviewers []*os.Process
26+
)
27+
28+
// KillTraceViewers kills all "go tool trace" processes started by
29+
// /flightrecorder requests, for use in tests (see #74668).
30+
func KillTraceViewers() {
31+
traceviewersMu.Lock()
32+
for _, p := range traceviewers {
33+
p.Kill() // ignore error
34+
}
35+
traceviewers = nil
36+
traceviewersMu.Unlock()
37+
}
38+
2339
// The FlightRecorder is a global resource, so create at most one per process.
2440
var getRecorder = sync.OnceValues(func() (*trace.FlightRecorder, error) {
2541
fr := trace.NewFlightRecorder(trace.FlightRecorderConfig{
@@ -53,7 +69,7 @@ func startFlightRecorder() (http.HandlerFunc, error) {
5369
return
5470
}
5571
if _, err := fr.WriteTo(f); err != nil {
56-
f.Close()
72+
f.Close() // ignore error
5773
errorf("failed to write flight record: %s", err)
5874
return
5975
}
@@ -113,6 +129,11 @@ func startFlightRecorder() (http.HandlerFunc, error) {
113129
return
114130
}
115131

132+
// Save the process so we can kill it when tests finish.
133+
traceviewersMu.Lock()
134+
traceviewers = append(traceviewers, cmd.Process)
135+
traceviewersMu.Unlock()
136+
116137
// Some of the CI builders can be quite heavily loaded.
117138
// Give them an extra grace period.
118139
timeout := 10 * time.Second

gopls/internal/debug/flight_go124.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ import (
1414
func startFlightRecorder() (http.HandlerFunc, error) {
1515
return nil, errors.ErrUnsupported
1616
}
17+
18+
func KillTraceViewers() {}

gopls/internal/test/integration/web/flight_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"runtime"
1010
"testing"
1111

12+
"golang.org/x/tools/gopls/internal/debug"
1213
"golang.org/x/tools/gopls/internal/protocol"
1314
"golang.org/x/tools/gopls/internal/protocol/command"
1415
. "golang.org/x/tools/gopls/internal/test/integration"
@@ -28,6 +29,10 @@ func TestFlightRecorder(t *testing.T) {
2829
}
2930
testenv.NeedsGo1Point(t, 25)
3031

32+
// This is a global hammer; it won't play nicely with
33+
// multiple concurrent tests of Flight Recorder.
34+
t.Cleanup(debug.KillTraceViewers)
35+
3136
const files = `
3237
-- go.mod --
3338
module example.com

0 commit comments

Comments
 (0)