internal/profile: return error from gzip.Writer.Close in Profile.Write

Profile.Write defers gzip.Writer.Close without checking its return
value. Close flushes buffered data and writes the gzip footer (CRC32
checksum and size). If the flush or footer write fails, the caller
receives a nil error despite the output being truncated or corrupt.

This is called by runtime/pprof and net/http/pprof to serialize
profiles. A write error during gzip finalization (e.g., broken pipe,
full disk) produces corrupt output reported as success.

Remove the defer and call Close explicitly after Write, returning
its error. On Write failure, Close is still called to release
resources, but the Write error is returned.

Fixes #79423

Change-Id: I1d93c20158010f45c72d57caf5d5b25b72ca7511
GitHub-Last-Rev: cd79f2a4cf
GitHub-Pull-Request: golang/go#79424
Reviewed-on: https://go-review.googlesource.com/c/go/+/778280
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Sebastien Tardif 2026-05-15 16:32:48 +00:00 committed by David Chase
parent c410b4944e
commit 8b672822b2

View file

@ -175,9 +175,11 @@ func (p *Profile) Write(w io.Writer) error {
p.preEncode()
b := marshal(p)
zw := gzip.NewWriter(w)
defer zw.Close()
_, err := zw.Write(b)
return err
if _, err := zw.Write(b); err != nil {
zw.Close()
return err
}
return zw.Close()
}
// CheckValid tests whether the profile is valid. Checks include, but are