Add new symbol directory layout by build-id `/xx/xxxxxxxx.debug`. (#724)
This protocol is already supported by various tools and lldb.
e.g.: https://github.com/llvm-mirror/lldb/blob/d01083a850f577b85501a0902b52fd0930de72c7/source/Symbol/LocateSymbolFile.cpp#L311
Among others it is used by Fuchisa OS builds.
diff --git a/internal/driver/cli.go b/internal/driver/cli.go
index 237cc33..a9cae92 100644
--- a/internal/driver/cli.go
+++ b/internal/driver/cli.go
@@ -363,5 +363,6 @@
" 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 26fee83..9865583 100644
--- a/internal/driver/fetch.go
+++ b/internal/driver/fetch.go
@@ -409,6 +409,10 @@
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 289dc24..bbdb14e 100644
--- a/internal/driver/fetch_test.go
+++ b/internal/driver/fetch_test.go
@@ -59,6 +59,9 @@
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 @@
{"", "/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 @@
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)
}