diff --git a/doc/pprof.md b/doc/pprof.md index e5340f05..d2c7e26e 100644 --- a/doc/pprof.md +++ b/doc/pprof.md @@ -84,7 +84,7 @@ pprof text reports show the location hierarchy in text format. * **-text:** Prints the location entries, one per line, including the flat and cum values. -* **-tree:** Prints each location entry with its predecessors and successors. +* **-tree:** Prints each location entry with its predecessors and successors. * **-peek= _regex_:** Print the location entry with all its predecessors and successors, without trimming any entries. * **-traces:** Prints each sample with a location per line. @@ -120,9 +120,10 @@ profile must contain data with the appropriate level of detail. pprof will look for source files on its current working directory and all its ancestors. pprof will look for binaries on the directories specified in the -`$PPROF_BINARY_PATH` environment variable, by default `$HOME/pprof/binaries`. It -will look binaries up by name, and if the profile includes linker build ids, it -will also search for them in a directory named as the build id. +`$PPROF_BINARY_PATH` environment variable, by default `$HOME/pprof/binaries` +(`%USERPROFILE%\pprof\binaries` on Windows). It will look binaries up by name, +and if the profile includes linker build ids, it will also search for them in +a directory named as the build id. pprof uses the binutils tools to examine and disassemble the binaries. By default it will search for those tools in the current path, but it can also diff --git a/internal/driver/cli.go b/internal/driver/cli.go index 093cdbbe..0005ead7 100644 --- a/internal/driver/cli.go +++ b/internal/driver/cli.go @@ -268,4 +268,5 @@ var usageMsgVars = "\n\n" + " PPROF_TOOLS Search path for object-level tools\n" + " PPROF_BINARY_PATH Search path for local binary files\n" + " default: $HOME/pprof/binaries\n" + - " finds binaries by $name and $buildid/$name\n" + " finds binaries by $name and $buildid/$name\n" + + " * On Windows, %USERPROFILE% is used instead of $HOME" diff --git a/internal/driver/fetch.go b/internal/driver/fetch.go index 9c6acc0e..522a81e2 100644 --- a/internal/driver/fetch.go +++ b/internal/driver/fetch.go @@ -25,6 +25,7 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "strconv" "strings" "sync" @@ -214,13 +215,24 @@ type profileSource struct { err error } +func homeEnv() string { + switch runtime.GOOS { + case "windows": + return "USERPROFILE" + case "plan9": + return "home" + default: + return "HOME" + } +} + // setTmpDir prepares the directory to use to save profiles retrieved // remotely. It is selected from PPROF_TMPDIR, defaults to $HOME/pprof. func setTmpDir(ui plugin.UI) (string, error) { if profileDir := os.Getenv("PPROF_TMPDIR"); profileDir != "" { return profileDir, nil } - for _, tmpDir := range []string{os.Getenv("HOME") + "/pprof", os.TempDir()} { + for _, tmpDir := range []string{os.Getenv(homeEnv()) + "/pprof", os.TempDir()} { if err := os.MkdirAll(tmpDir, 0755); err != nil { ui.PrintErr("Could not use temp dir ", tmpDir, ": ", err.Error()) continue @@ -315,7 +327,7 @@ func locateBinaries(p *profile.Profile, s *source, obj plugin.ObjTool, ui plugin searchPath := os.Getenv("PPROF_BINARY_PATH") if searchPath == "" { // Use $HOME/pprof/binaries as default directory for local symbolization binaries - searchPath = filepath.Join(os.Getenv("HOME"), "pprof", "binaries") + searchPath = filepath.Join(os.Getenv(homeEnv()), "pprof", "binaries") } mapping: for _, m := range p.Mapping {