1
0
mirror of https://github.com/golang/go synced 2024-11-12 08:20:22 -07:00

misc/pprof: pprof on windows does not provide demangled names

Fixes #6034.

R=golang-dev, bradfitz, alex.brainman, dan.kortschak
CC=golang-dev
https://golang.org/cl/12311044
This commit is contained in:
Shivakumar GN 2013-08-09 13:42:24 +10:00 committed by Alex Brainman
parent b7eb0e5990
commit 88d544e01d

View File

@ -78,6 +78,7 @@
use strict; use strict;
use warnings; use warnings;
use Getopt::Long; use Getopt::Long;
use File::Temp;
my $PPROF_VERSION = "1.5"; my $PPROF_VERSION = "1.5";
@ -134,6 +135,13 @@ my @prefix_list = ();
my $sep_symbol = '_fini'; my $sep_symbol = '_fini';
my $sep_address = undef; my $sep_address = undef;
my $OS = $^O;
my $DEVNULL = "/dev/null";
if ($^O =~ /MSWin32|cygwin|msys/) {
$OS = "windows";
$DEVNULL = "NUL";
}
##### Argument parsing ##### ##### Argument parsing #####
sub usage_string { sub usage_string {
@ -286,8 +294,9 @@ sub Init() {
# Setup tmp-file name and handler to clean it up. # Setup tmp-file name and handler to clean it up.
# We do this in the very beginning so that we can use # We do this in the very beginning so that we can use
# error() and cleanup() function anytime here after. # error() and cleanup() function anytime here after.
$main::tmpfile_sym = "/tmp/pprof$$.sym"; $main::tmpfile_sym = File::Temp->new()->filename;
$main::tmpfile_ps = "/tmp/pprof$$"; $main::tmpfile_ps = File::Temp->new()->filename;
$main::next_tmpfile = 0; $main::next_tmpfile = 0;
$SIG{'INT'} = \&sighandler; $SIG{'INT'} = \&sighandler;
@ -696,7 +705,7 @@ sub ReadlineMightFail {
sub RunGV { sub RunGV {
my $fname = shift; my $fname = shift;
my $bg = shift; # "" or " &" if we should run in background my $bg = shift; # "" or " &" if we should run in background
if (!system("$GV --version >/dev/null 2>&1")) { if (!system("$GV --version >$DEVNULL 2>&1")) {
# Options using double dash are supported by this gv version. # Options using double dash are supported by this gv version.
# Also, turn on noantialias to better handle bug in gv for # Also, turn on noantialias to better handle bug in gv for
# postscript files with large dimensions. # postscript files with large dimensions.
@ -1246,7 +1255,7 @@ sub Disassemble {
"--start-address=0x$start_addr " . "--start-address=0x$start_addr " .
"--stop-address=0x$end_addr $prog"); "--stop-address=0x$end_addr $prog");
if (system("$objdump --help >/dev/null 2>&1") != 0) { if (system("$objdump --help >$DEVNULL 2>&1") != 0) {
# objdump must not exist. Fall back to go tool objdump. # objdump must not exist. Fall back to go tool objdump.
$objdump = "go tool objdump"; $objdump = "go tool objdump";
$cmd = "$objdump $prog 0x$start_addr 0x$end_addr"; $cmd = "$objdump $prog 0x$start_addr 0x$end_addr";
@ -4426,7 +4435,7 @@ sub MapToSymbols {
# If "addr2line" isn't installed on the system at all, just use # If "addr2line" isn't installed on the system at all, just use
# nm to get what info we can (function names, but not line numbers). # nm to get what info we can (function names, but not line numbers).
if (system("$addr2line --help >/dev/null 2>&1") != 0) { if (system("$addr2line --help >$DEVNULL 2>&1") != 0) {
MapSymbolsWithNM($image, $offset, $pclist, $symbols); MapSymbolsWithNM($image, $offset, $pclist, $symbols);
return; return;
} }
@ -4444,7 +4453,7 @@ sub MapToSymbols {
if (defined($sep_address)) { if (defined($sep_address)) {
# Only add " -i" to addr2line if the binary supports it. # Only add " -i" to addr2line if the binary supports it.
# addr2line --help returns 0, but not if it sees an unknown flag first. # addr2line --help returns 0, but not if it sees an unknown flag first.
if (system("$cmd -i --help >/dev/null 2>&1") == 0) { if (system("$cmd -i --help >$DEVNULL 2>&1") == 0) {
$cmd .= " -i"; $cmd .= " -i";
} else { } else {
$sep_address = undef; # no need for sep_address if we don't support -i $sep_address = undef; # no need for sep_address if we don't support -i
@ -4599,7 +4608,12 @@ sub ConfigureObjTools {
(-e $prog_file) || error("$prog_file does not exist.\n"); (-e $prog_file) || error("$prog_file does not exist.\n");
# Follow symlinks (at least for systems where "file" supports that) # Follow symlinks (at least for systems where "file" supports that)
my $file_type = `/usr/bin/file -L $prog_file 2>/dev/null || /usr/bin/file $prog_file`; my $file_cmd = "/usr/bin/file -L $prog_file 2>$DEVNULL || /usr/bin/file $prog_file 2>$DEVNULL";
if ($^O eq "MSWin32") {
$file_cmd = "file -L $prog_file 2>NUL || file $prog_file 2>NUL";
}
my $file_type = `$file_cmd`;
if ($file_type =~ /64-bit/) { if ($file_type =~ /64-bit/) {
# Change $address_length to 16 if the program file is ELF 64-bit. # Change $address_length to 16 if the program file is ELF 64-bit.
# We can't detect this from many (most?) heap or lock contention # We can't detect this from many (most?) heap or lock contention
@ -4608,14 +4622,13 @@ sub ConfigureObjTools {
$address_length = 16; $address_length = 16;
} }
if ($file_type =~ /MS Windows/) { if (($file_type =~ /MS Windows/) || ($OS eq "windows")) {
# For windows, we provide a version of nm and addr2line as part of # For windows, we provide a version of nm and addr2line as part of
# the opensource release, which is capable of parsing # the opensource release, which is capable of parsing
# Windows-style PDB executables. It should live in the path, or # Windows-style PDB executables. It should live in the path, or
# in the same directory as pprof. # in the same directory as pprof.
$obj_tool_map{"nm_pdb"} = "nm-pdb"; $obj_tool_map{"nm_pdb"} = "nm-pdb";
$obj_tool_map{"addr2line_pdb"} = "addr2line-pdb"; $obj_tool_map{"addr2line_pdb"} = "addr2line-pdb";
$obj_tool_map{"is_windows"} = "true";
} }
if ($file_type =~ /Mach-O/) { if ($file_type =~ /Mach-O/) {
@ -4801,29 +4814,23 @@ sub GetProcedureBoundaries {
# in an incompatible way. So first we test whether our nm supports # in an incompatible way. So first we test whether our nm supports
# --demangle and -f. # --demangle and -f.
my $demangle_flag = ""; my $demangle_flag = "";
if (system("$nm --demangle $image >/dev/null 2>&1") == 0) { if (system("$nm --demangle $image >$DEVNULL 2>&1") == 0) {
# In this mode, we do "nm --demangle <foo>" # In this mode, we do "nm --demangle <foo>"
$demangle_flag = "--demangle"; $demangle_flag = "--demangle";
} }
my $flatten_flag = ""; my $flatten_flag = "";
if (system("$nm -f $image >/dev/null 2>&1") == 0) { if (system("$nm -f $image >$DEVNULL 2>&1") == 0) {
$flatten_flag = "-f"; $flatten_flag = "-f";
} }
# Finally, in the case $image isn't a debug library, we try again with # Finally, in the case $image isn't a debug library, we try again with
# -D to at least get *exported* symbols. If we can't use --demangle, too bad. # -D to at least get *exported* symbols. If we can't use --demangle, too bad.
my @nm_commands = ("$nm -n $flatten_flag $demangle_flag" . my @nm_commands = ("$nm -n $flatten_flag $demangle_flag" .
" $image 2>/dev/null", " $image 2>$DEVNULL",
"$nm -D -n $flatten_flag $demangle_flag" . "$nm -D -n $flatten_flag $demangle_flag" .
" $image 2>/dev/null", " $image 2>$DEVNULL",
# go tool nm is for Go binaries # go tool nm is for Go binaries
"go tool nm $image 2>/dev/null | sort"); "go tool nm $image 2>$DEVNULL | sort");
# If the executable is an MS Windows Go executable, we'll
# have set up obj_tool_map("is_windows").
if (exists $obj_tool_map{"is_windows"}) {
@nm_commands = ("go tool nm $image 2>/dev/null | sort");
}
foreach my $nm_command (@nm_commands) { foreach my $nm_command (@nm_commands) {
my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp); my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp);