diff --git a/internal/driver/cli.go b/internal/driver/cli.go index 237cc332..a9cae92d 100644 --- a/internal/driver/cli.go +++ b/internal/driver/cli.go @@ -363,5 +363,6 @@ 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" + - " searches $name, $path, $buildid/$name, $path/$buildid\n" + + " searches $buildid/$name, $buildid/*, $path/$buildid,\n" + + " ${buildid:0:2}/${buildid:2}.debug, $name, $path\n" + " * On Windows, %USERPROFILE% is used instead of $HOME" diff --git a/internal/driver/fetch.go b/internal/driver/fetch.go index 26fee83c..98655836 100644 --- a/internal/driver/fetch.go +++ b/internal/driver/fetch.go @@ -409,6 +409,10 @@ mapping: fileNames = append(fileNames, matches...) } fileNames = append(fileNames, filepath.Join(path, m.File, m.BuildID)) // perf path format + // Llvm buildid protocol: the first two characters of the build id + // are used as directory, and the remaining part is in the filename. + // e.g. `/ab/cdef0123456.debug` + fileNames = append(fileNames, filepath.Join(path, m.BuildID[:2], m.BuildID[2:]+".debug")) } if m.File != "" { // Try both the basename and the full path, to support the same directory diff --git a/internal/driver/fetch_test.go b/internal/driver/fetch_test.go index 289dc24d..bbdb14e2 100644 --- a/internal/driver/fetch_test.go +++ b/internal/driver/fetch_test.go @@ -59,6 +59,9 @@ func TestSymbolizationPath(t *testing.T) { os.MkdirAll(filepath.Join(tempdir, "pprof", "binaries", "abcde10001"), 0700) os.Create(filepath.Join(tempdir, "pprof", "binaries", "abcde10001", "binary")) + os.MkdirAll(filepath.Join(tempdir, "pprof", "binaries", "fg"), 0700) + os.Create(filepath.Join(tempdir, "pprof", "binaries", "fg", "hij10001.debug")) + obj := testObj{tempdir} os.Setenv(homeEnv(), tempdir) for _, tc := range []struct { @@ -71,6 +74,7 @@ func TestSymbolizationPath(t *testing.T) { {"", "/prod/path/binary", "abcde10001", filepath.Join(tempdir, "pprof/binaries/abcde10001/binary"), 0}, {"/alternate/architecture", "/usr/bin/binary", "", "/alternate/architecture/binary", 0}, {"/alternate/architecture", "/usr/bin/binary", "abcde10001", "/alternate/architecture/binary", 0}, + {"", "", "fghij10001", filepath.Join(tempdir, "pprof/binaries/fg/hij10001.debug"), 0}, {"/nowhere:/alternate/architecture", "/usr/bin/binary", "fedcb10000", "/usr/bin/binary", 1}, {"/nowhere:/alternate/architecture", "/usr/bin/binary", "abcde10002", "/usr/bin/binary", 1}, } { @@ -154,6 +158,8 @@ func (o testObj) Open(file string, start, limit, offset uint64, relocationSymbol return testFile{file, "fedcb10000"}, nil case filepath.Join(o.home, "pprof/binaries/abcde10001/binary"): return testFile{file, "abcde10001"}, nil + case filepath.Join(o.home, "pprof/binaries/fg/hij10001.debug"): + return testFile{file, "fghij10001"}, nil } return nil, fmt.Errorf("not found: %s", file) }