1
0
mirror of https://github.com/golang/go synced 2024-09-28 22:24:29 -06:00

cmd/compile: modify -memprofile flag for multiple profiles in a directory

This permits collection of multiple profiles in a build
(instead of just the last compilation).  If a -memprofile
specifies an existing directory instead of a file, it will
create "<url.PathEscape(pkgpath)>.mprof" in that directory.

The PathEscaped package names are ugly, but this puts all
the files in a single directory with no risk of name clashs,
which simplies the usual case for using these files, which
is something like
```
go tool pprof profiles/*.mprof
```

Creating a directory tree mimicking the package structure
requires something along the lines of
```
go tool pprof `find profiles -name "*.mprof" -print`
```

In addition, this turns off "legacy format" because that
is only useful for a benchcompile, which does not use this
new feature (and people actually interested in memory
profiles probably prefer the new ones).

Change-Id: Ic1d9da53af22ecdda17663e0d4bce7cdbcb54527
Reviewed-on: https://go-review.googlesource.com/c/go/+/539316
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
David Chase 2023-10-24 13:57:35 -04:00
parent 2380862c7c
commit 0ce94d79bc

View File

@ -5,7 +5,9 @@
package gc package gc
import ( import (
"net/url"
"os" "os"
"path/filepath"
"runtime" "runtime"
"runtime/pprof" "runtime/pprof"
tracepkg "runtime/trace" tracepkg "runtime/trace"
@ -28,18 +30,30 @@ func startProfile() {
if base.Flag.MemProfileRate != 0 { if base.Flag.MemProfileRate != 0 {
runtime.MemProfileRate = base.Flag.MemProfileRate runtime.MemProfileRate = base.Flag.MemProfileRate
} }
f, err := os.Create(base.Flag.MemProfile) const (
gzipFormat = 0
textFormat = 1
)
// compilebench parses the memory profile to extract memstats,
// which are only written in the legacy (text) pprof format.
// See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap.
// gzipFormat is what most people want, otherwise
var format = textFormat
fn := base.Flag.MemProfile
if fi, statErr := os.Stat(fn); statErr == nil && fi.IsDir() {
fn = filepath.Join(fn, url.PathEscape(base.Ctxt.Pkgpath)+".mprof")
format = gzipFormat
}
f, err := os.Create(fn)
if err != nil { if err != nil {
base.Fatalf("%v", err) base.Fatalf("%v", err)
} }
base.AtExit(func() { base.AtExit(func() {
// Profile all outstanding allocations. // Profile all outstanding allocations.
runtime.GC() runtime.GC()
// compilebench parses the memory profile to extract memstats, if err := pprof.Lookup("heap").WriteTo(f, format); err != nil {
// which are only written in the legacy pprof format.
// See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap.
const writeLegacyFormat = 1
if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
base.Fatalf("%v", err) base.Fatalf("%v", err)
} }
}) })