]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: modify -memprofile flag for multiple profiles in a directory
authorDavid Chase <drchase@google.com>
Tue, 24 Oct 2023 17:57:35 +0000 (13:57 -0400)
committerDavid Chase <drchase@google.com>
Wed, 15 Nov 2023 20:36:24 +0000 (20:36 +0000)
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>
src/cmd/compile/internal/gc/util.go

index dcac0ce79ae35a4fced71bf90b888145314b6398..5615d60b57f6b5f8b2f02c345681a81abfafadb2 100644 (file)
@@ -5,7 +5,9 @@
 package gc
 
 import (
+       "net/url"
        "os"
+       "path/filepath"
        "runtime"
        "runtime/pprof"
        tracepkg "runtime/trace"
@@ -28,18 +30,30 @@ func startProfile() {
                if base.Flag.MemProfileRate != 0 {
                        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 {
                        base.Fatalf("%v", err)
                }
                base.AtExit(func() {
                        // Profile all outstanding allocations.
                        runtime.GC()
-                       // compilebench parses the memory profile to extract memstats,
-                       // 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 {
+                       if err := pprof.Lookup("heap").WriteTo(f, format); err != nil {
                                base.Fatalf("%v", err)
                        }
                })