Added --debug-syms-by-id option

This commit is contained in:
Deanna Gelbart 2021-05-11 19:02:33 -07:00 committed by David Goldblatt
parent 08089589f7
commit 11beab38bc

View File

@ -240,6 +240,7 @@ Miscellaneous:
--test Run unit tests --test Run unit tests
--help This message --help This message
--version Version information --version Version information
--debug-syms-by-id (Linux only) Find debug symbol files by build ID as well as by name
Environment Variables: Environment Variables:
JEPROF_TMPDIR Profiles directory. Defaults to \$HOME/jeprof JEPROF_TMPDIR Profiles directory. Defaults to \$HOME/jeprof
@ -365,6 +366,7 @@ sub Init() {
$main::opt_tools = ""; $main::opt_tools = "";
$main::opt_debug = 0; $main::opt_debug = 0;
$main::opt_test = 0; $main::opt_test = 0;
$main::opt_debug_syms_by_id = 0;
# These are undocumented flags used only by unittests. # These are undocumented flags used only by unittests.
$main::opt_test_stride = 0; $main::opt_test_stride = 0;
@ -433,6 +435,7 @@ sub Init() {
"tools=s" => \$main::opt_tools, "tools=s" => \$main::opt_tools,
"test!" => \$main::opt_test, "test!" => \$main::opt_test,
"debug!" => \$main::opt_debug, "debug!" => \$main::opt_debug,
"debug-syms-by-id!" => \$main::opt_debug_syms_by_id,
# Undocumented flags used only by unittests: # Undocumented flags used only by unittests:
"test_stride=i" => \$main::opt_test_stride, "test_stride=i" => \$main::opt_test_stride,
) || usage("Invalid option(s)"); ) || usage("Invalid option(s)");
@ -577,6 +580,11 @@ sub Init() {
foreach (@prefix_list) { foreach (@prefix_list) {
s|/+$||; 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 { sub FilterAndPrint {
@ -4492,16 +4500,54 @@ sub FindLibrary {
# For libc libraries, the copy in /usr/lib/debug contains debugging symbols # For libc libraries, the copy in /usr/lib/debug contains debugging symbols
sub DebuggingLibrary { sub DebuggingLibrary {
my $file = shift; my $file = shift;
if ($file =~ m|^/|) {
if (-f "/usr/lib/debug$file") { if ($file !~ m|^/|) {
return "/usr/lib/debug$file";
} elsif (-f "/usr/lib/debug$file.debug") {
return "/usr/lib/debug$file.debug";
}
}
return undef; 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 # Parse text section header of a library using objdump
sub ParseTextSectionHeaderFromObjdump { sub ParseTextSectionHeaderFromObjdump {
my $lib = shift; my $lib = shift;