summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorDeanna Gelbart <deanna.gelbart@hootsuite.com>2021-05-11 19:02:33 -0700
committerDavid Goldblatt <davidtgoldblatt@gmail.com>2021-05-17 10:00:40 -0700
commit11beab38bc5ede45f06af3c513efd003c9d32088 (patch)
treeac608f7b6dc1960f7e2b7ee39019a452cee1ac7b /bin
parent08089589f74ac23268791be18742d031cc5dd041 (diff)
downloadjemalloc-11beab38bc5ede45f06af3c513efd003c9d32088.tar.gz
Added --debug-syms-by-id option
Diffstat (limited to 'bin')
-rw-r--r--bin/jeprof.in56
1 files changed, 51 insertions, 5 deletions
diff --git a/bin/jeprof.in b/bin/jeprof.in
index d47359cf..e0b212ae 100644
--- a/bin/jeprof.in
+++ b/bin/jeprof.in
@@ -240,6 +240,7 @@ Miscellaneous:
--test Run unit tests
--help This message
--version Version information
+ --debug-syms-by-id (Linux only) Find debug symbol files by build ID as well as by name
Environment Variables:
JEPROF_TMPDIR Profiles directory. Defaults to \$HOME/jeprof
@@ -365,6 +366,7 @@ sub Init() {
$main::opt_tools = "";
$main::opt_debug = 0;
$main::opt_test = 0;
+ $main::opt_debug_syms_by_id = 0;
# These are undocumented flags used only by unittests.
$main::opt_test_stride = 0;
@@ -433,6 +435,7 @@ sub Init() {
"tools=s" => \$main::opt_tools,
"test!" => \$main::opt_test,
"debug!" => \$main::opt_debug,
+ "debug-syms-by-id!" => \$main::opt_debug_syms_by_id,
# Undocumented flags used only by unittests:
"test_stride=i" => \$main::opt_test_stride,
) || usage("Invalid option(s)");
@@ -577,6 +580,11 @@ sub Init() {
foreach (@prefix_list) {
s|/+$||;
}
+
+ # Flag to prevent us from trying over and over to use
+ # elfutils if it's not installed (used only with
+ # --debug-syms-by-id option).
+ $main::gave_up_on_elfutils = 0;
}
sub FilterAndPrint {
@@ -4492,16 +4500,54 @@ sub FindLibrary {
# For libc libraries, the copy in /usr/lib/debug contains debugging symbols
sub DebuggingLibrary {
my $file = shift;
- if ($file =~ m|^/|) {
- if (-f "/usr/lib/debug$file") {
- return "/usr/lib/debug$file";
- } elsif (-f "/usr/lib/debug$file.debug") {
- return "/usr/lib/debug$file.debug";
+
+ if ($file !~ m|^/|) {
+ return undef;
+ }
+
+ # Find debug symbol file if it's named after the library's name.
+
+ if (-f "/usr/lib/debug$file") {
+ if($main::opt_debug) { print STDERR "found debug info for $file in /usr/lib/debug$file\n"; }
+ return "/usr/lib/debug$file";
+ } elsif (-f "/usr/lib/debug$file.debug") {
+ if($main::opt_debug) { print STDERR "found debug info for $file in /usr/lib/debug$file.debug\n"; }
+ return "/usr/lib/debug$file.debug";
+ }
+
+ if(!$main::opt_debug_syms_by_id) {
+ if($main::opt_debug) { print STDERR "no debug symbols found for $file\n" };
+ return undef;
+ }
+
+ # Find debug file if it's named after the library's build ID.
+
+ my $readelf = '';
+ if (!$main::gave_up_on_elfutils) {
+ $readelf = qx/eu-readelf -n ${file}/;
+ if ($?) {
+ print STDERR "Cannot run eu-readelf. To use --debug-syms-by-id you must be on Linux, with elfutils installed.\n";
+ $main::gave_up_on_elfutils = 1;
+ return undef;
+ }
+ my $buildID = $1 if $readelf =~ /Build ID: ([A-Fa-f0-9]+)/s;
+ if (defined $buildID && length $buildID > 0) {
+ my $symbolFile = '/usr/lib/debug/.build-id/' . substr($buildID, 0, 2) . '/' . substr($buildID, 2) . '.debug';
+ if (-e $symbolFile) {
+ if($main::opt_debug) { print STDERR "found debug symbol file $symbolFile for $file\n" };
+ return $symbolFile;
+ } else {
+ if($main::opt_debug) { print STDERR "no debug symbol file found for $file, build ID: $buildID\n" };
+ return undef;
}
+ }
}
+
+ if($main::opt_debug) { print STDERR "no debug symbols found for $file, build ID unknown\n" };
return undef;
}
+
# Parse text section header of a library using objdump
sub ParseTextSectionHeaderFromObjdump {
my $lib = shift;