Rename pprof to jeprof.
This rename avoids installation collisions with the upstream gperftools. Additionally, jemalloc's per thread heap profile functionality introduced an incompatible file format, so it's now worthwhile to clearly distinguish jemalloc's version of this script from the upstream version. This resolves #229.
This commit is contained in:
parent
8e33c21d2d
commit
7041720ac2
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
||||
|
||||
/bin/jemalloc-config
|
||||
/bin/jemalloc.sh
|
||||
/bin/jeprof
|
||||
|
||||
/config.stamp
|
||||
/config.log
|
||||
|
@ -117,8 +117,9 @@ found in the git revision history:
|
||||
- Assure that the constness of malloc_usable_size()'s return type matches that
|
||||
of the system implementation.
|
||||
- Change the heap profile dump format to support per thread heap profiling,
|
||||
and enhance pprof with the --thread=<n> option. As a result, the bundled
|
||||
pprof must now be used rather than the upstream (gperftools) pprof.
|
||||
rename pprof to jeprof, and enhance it with the --thread=<n> option. As a
|
||||
result, the bundled jeprof must now be used rather than the upstream
|
||||
(gperftools) pprof.
|
||||
- Disable "opt.prof_final" by default, in order to avoid atexit(3), which can
|
||||
internally deadlock on some platforms.
|
||||
- Change the "arenas.nlruns" mallctl type from size_t to unsigned.
|
||||
|
@ -73,7 +73,7 @@ endif
|
||||
LIBJEMALLOC := $(LIBPREFIX)jemalloc$(install_suffix)
|
||||
|
||||
# Lists of files.
|
||||
BINS := $(srcroot)bin/pprof $(objroot)bin/jemalloc-config $(objroot)bin/jemalloc.sh
|
||||
BINS := $(objroot)bin/jemalloc-config $(objroot)bin/jemalloc.sh $(objroot)bin/jeprof
|
||||
C_HDRS := $(objroot)include/jemalloc/jemalloc$(install_suffix).h
|
||||
C_SRCS := $(srcroot)src/jemalloc.c $(srcroot)src/arena.c \
|
||||
$(srcroot)src/atomic.c $(srcroot)src/base.c $(srcroot)src/bitmap.c \
|
||||
|
114
bin/pprof → bin/jeprof.in
Executable file → Normal file
114
bin/pprof → bin/jeprof.in
Executable file → Normal file
@ -40,28 +40,28 @@
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# % tools/pprof "program" "profile"
|
||||
# % tools/jeprof "program" "profile"
|
||||
# Enters "interactive" mode
|
||||
#
|
||||
# % tools/pprof --text "program" "profile"
|
||||
# % tools/jeprof --text "program" "profile"
|
||||
# Generates one line per procedure
|
||||
#
|
||||
# % tools/pprof --gv "program" "profile"
|
||||
# % tools/jeprof --gv "program" "profile"
|
||||
# Generates annotated call-graph and displays via "gv"
|
||||
#
|
||||
# % tools/pprof --gv --focus=Mutex "program" "profile"
|
||||
# % tools/jeprof --gv --focus=Mutex "program" "profile"
|
||||
# Restrict to code paths that involve an entry that matches "Mutex"
|
||||
#
|
||||
# % tools/pprof --gv --focus=Mutex --ignore=string "program" "profile"
|
||||
# % tools/jeprof --gv --focus=Mutex --ignore=string "program" "profile"
|
||||
# Restrict to code paths that involve an entry that matches "Mutex"
|
||||
# and does not match "string"
|
||||
#
|
||||
# % tools/pprof --list=IBF_CheckDocid "program" "profile"
|
||||
# % tools/jeprof --list=IBF_CheckDocid "program" "profile"
|
||||
# Generates disassembly listing of all routines with at least one
|
||||
# sample that match the --list=<regexp> pattern. The listing is
|
||||
# annotated with the flat and cumulative sample counts at each line.
|
||||
#
|
||||
# % tools/pprof --disasm=IBF_CheckDocid "program" "profile"
|
||||
# % tools/jeprof --disasm=IBF_CheckDocid "program" "profile"
|
||||
# Generates disassembly listing of all routines with at least one
|
||||
# sample that match the --disasm=<regexp> pattern. The listing is
|
||||
# annotated with the flat and cumulative sample counts at each PC value.
|
||||
@ -72,10 +72,11 @@ use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
|
||||
my $JEPROF_VERSION = "@jemalloc_version@";
|
||||
my $PPROF_VERSION = "2.0";
|
||||
|
||||
# These are the object tools we use which can come from a
|
||||
# user-specified location using --tools, from the PPROF_TOOLS
|
||||
# user-specified location using --tools, from the JEPROF_TOOLS
|
||||
# environment variable, or from the environment.
|
||||
my %obj_tool_map = (
|
||||
"objdump" => "objdump",
|
||||
@ -144,13 +145,13 @@ my $sep_address = undef;
|
||||
sub usage_string {
|
||||
return <<EOF;
|
||||
Usage:
|
||||
pprof [options] <program> <profiles>
|
||||
jeprof [options] <program> <profiles>
|
||||
<profiles> is a space separated list of profile names.
|
||||
pprof [options] <symbolized-profiles>
|
||||
jeprof [options] <symbolized-profiles>
|
||||
<symbolized-profiles> is a list of profile files where each file contains
|
||||
the necessary symbol mappings as well as profile data (likely generated
|
||||
with --raw).
|
||||
pprof [options] <profile>
|
||||
jeprof [options] <profile>
|
||||
<profile> is a remote form. Symbols are obtained from host:port$SYMBOL_PAGE
|
||||
|
||||
Each name can be:
|
||||
@ -161,9 +162,9 @@ pprof [options] <profile>
|
||||
$GROWTH_PAGE, $CONTENTION_PAGE, /pprof/wall,
|
||||
$CENSUSPROFILE_PAGE, or /pprof/filteredprofile.
|
||||
For instance:
|
||||
pprof http://myserver.com:80$HEAP_PAGE
|
||||
jeprof http://myserver.com:80$HEAP_PAGE
|
||||
If /<service> is omitted, the service defaults to $PROFILE_PAGE (cpu profiling).
|
||||
pprof --symbols <program>
|
||||
jeprof --symbols <program>
|
||||
Maps addresses to symbol names. In this mode, stdin should be a
|
||||
list of library mappings, in the same format as is found in the heap-
|
||||
and cpu-profile files (this loosely matches that of /proc/self/maps
|
||||
@ -202,7 +203,7 @@ Output type:
|
||||
--pdf Generate PDF to stdout
|
||||
--svg Generate SVG to stdout
|
||||
--gif Generate GIF to stdout
|
||||
--raw Generate symbolized pprof data (useful with remote fetch)
|
||||
--raw Generate symbolized jeprof data (useful with remote fetch)
|
||||
|
||||
Heap-Profile Options:
|
||||
--inuse_space Display in-use (mega)bytes [default]
|
||||
@ -236,34 +237,34 @@ Miscellaneous:
|
||||
--version Version information
|
||||
|
||||
Environment Variables:
|
||||
PPROF_TMPDIR Profiles directory. Defaults to \$HOME/pprof
|
||||
PPROF_TOOLS Prefix for object tools pathnames
|
||||
JEPROF_TMPDIR Profiles directory. Defaults to \$HOME/jeprof
|
||||
JEPROF_TOOLS Prefix for object tools pathnames
|
||||
|
||||
Examples:
|
||||
|
||||
pprof /bin/ls ls.prof
|
||||
jeprof /bin/ls ls.prof
|
||||
Enters "interactive" mode
|
||||
pprof --text /bin/ls ls.prof
|
||||
jeprof --text /bin/ls ls.prof
|
||||
Outputs one line per procedure
|
||||
pprof --web /bin/ls ls.prof
|
||||
jeprof --web /bin/ls ls.prof
|
||||
Displays annotated call-graph in web browser
|
||||
pprof --gv /bin/ls ls.prof
|
||||
jeprof --gv /bin/ls ls.prof
|
||||
Displays annotated call-graph via 'gv'
|
||||
pprof --gv --focus=Mutex /bin/ls ls.prof
|
||||
jeprof --gv --focus=Mutex /bin/ls ls.prof
|
||||
Restricts to code paths including a .*Mutex.* entry
|
||||
pprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof
|
||||
jeprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof
|
||||
Code paths including Mutex but not string
|
||||
pprof --list=getdir /bin/ls ls.prof
|
||||
jeprof --list=getdir /bin/ls ls.prof
|
||||
(Per-line) annotated source listing for getdir()
|
||||
pprof --disasm=getdir /bin/ls ls.prof
|
||||
jeprof --disasm=getdir /bin/ls ls.prof
|
||||
(Per-PC) annotated disassembly for getdir()
|
||||
|
||||
pprof http://localhost:1234/
|
||||
jeprof http://localhost:1234/
|
||||
Enters "interactive" mode
|
||||
pprof --text localhost:1234
|
||||
jeprof --text localhost:1234
|
||||
Outputs one line per procedure for localhost:1234
|
||||
pprof --raw localhost:1234 > ./local.raw
|
||||
pprof --text ./local.raw
|
||||
jeprof --raw localhost:1234 > ./local.raw
|
||||
jeprof --text ./local.raw
|
||||
Fetches a remote profile for later analysis and then
|
||||
analyzes it in text mode.
|
||||
EOF
|
||||
@ -271,7 +272,8 @@ EOF
|
||||
|
||||
sub version_string {
|
||||
return <<EOF
|
||||
pprof (part of gperftools $PPROF_VERSION)
|
||||
jeprof (part of jemalloc $JEPROF_VERSION)
|
||||
based on pprof (part of gperftools $PPROF_VERSION)
|
||||
|
||||
Copyright 1998-2007 Google Inc.
|
||||
|
||||
@ -294,8 +296,8 @@ sub Init() {
|
||||
# Setup tmp-file name and handler to clean it up.
|
||||
# We do this in the very beginning so that we can use
|
||||
# error() and cleanup() function anytime here after.
|
||||
$main::tmpfile_sym = "/tmp/pprof$$.sym";
|
||||
$main::tmpfile_ps = "/tmp/pprof$$";
|
||||
$main::tmpfile_sym = "/tmp/jeprof$$.sym";
|
||||
$main::tmpfile_ps = "/tmp/jeprof$$";
|
||||
$main::next_tmpfile = 0;
|
||||
$SIG{'INT'} = \&sighandler;
|
||||
|
||||
@ -802,14 +804,14 @@ sub InteractiveMode {
|
||||
$| = 1; # Make output unbuffered for interactive mode
|
||||
my ($orig_profile, $symbols, $libs, $total) = @_;
|
||||
|
||||
print STDERR "Welcome to pprof! For help, type 'help'.\n";
|
||||
print STDERR "Welcome to jeprof! For help, type 'help'.\n";
|
||||
|
||||
# Use ReadLine if it's installed and input comes from a console.
|
||||
if ( -t STDIN &&
|
||||
!ReadlineMightFail() &&
|
||||
defined(eval {require Term::ReadLine}) ) {
|
||||
my $term = new Term::ReadLine 'pprof';
|
||||
while ( defined ($_ = $term->readline('(pprof) '))) {
|
||||
my $term = new Term::ReadLine 'jeprof';
|
||||
while ( defined ($_ = $term->readline('(jeprof) '))) {
|
||||
$term->addhistory($_) if /\S/;
|
||||
if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) {
|
||||
last; # exit when we get an interactive command to quit
|
||||
@ -817,7 +819,7 @@ sub InteractiveMode {
|
||||
}
|
||||
} else { # don't have readline
|
||||
while (1) {
|
||||
print STDERR "(pprof) ";
|
||||
print STDERR "(jeprof) ";
|
||||
$_ = <STDIN>;
|
||||
last if ! defined $_ ;
|
||||
s/\r//g; # turn windows-looking lines into unix-looking lines
|
||||
@ -1010,7 +1012,7 @@ sub ProcessProfile {
|
||||
|
||||
sub InteractiveHelpMessage {
|
||||
print STDERR <<ENDOFHELP;
|
||||
Interactive pprof mode
|
||||
Interactive jeprof mode
|
||||
|
||||
Commands:
|
||||
gv
|
||||
@ -1053,7 +1055,7 @@ Commands:
|
||||
Generates callgrind file. If no filename is given, kcachegrind is called.
|
||||
|
||||
help - This listing
|
||||
quit or ^D - End pprof
|
||||
quit or ^D - End jeprof
|
||||
|
||||
For commands that accept optional -ignore tags, samples where any routine in
|
||||
the stack trace matches the regular expression in any of the -ignore
|
||||
@ -1498,7 +1500,7 @@ h1 {
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function pprof_toggle_asm(e) {
|
||||
function jeprof_toggle_asm(e) {
|
||||
var target;
|
||||
if (!e) e = window.event;
|
||||
if (e.target) target = e.target;
|
||||
@ -1767,7 +1769,7 @@ sub PrintSource {
|
||||
|
||||
if ($html) {
|
||||
printf $output (
|
||||
"<h1>%s</h1>%s\n<pre onClick=\"pprof_toggle_asm()\">\n" .
|
||||
"<h1>%s</h1>%s\n<pre onClick=\"jeprof_toggle_asm()\">\n" .
|
||||
"Total:%6s %6s (flat / cumulative %s)\n",
|
||||
HtmlEscape(ShortFunctionName($routine)),
|
||||
HtmlEscape(CleanFileName($filename)),
|
||||
@ -3433,7 +3435,7 @@ sub FetchDynamicProfile {
|
||||
$profile_file .= $suffix;
|
||||
}
|
||||
|
||||
my $profile_dir = $ENV{"PPROF_TMPDIR"} || ($ENV{HOME} . "/pprof");
|
||||
my $profile_dir = $ENV{"JEPROF_TMPDIR"} || ($ENV{HOME} . "/jeprof");
|
||||
if (! -d $profile_dir) {
|
||||
mkdir($profile_dir)
|
||||
|| die("Unable to create profile directory $profile_dir: $!\n");
|
||||
@ -3649,7 +3651,7 @@ BEGIN {
|
||||
# Reads the top, 'header' section of a profile, and returns the last
|
||||
# line of the header, commonly called a 'header line'. The header
|
||||
# section of a profile consists of zero or more 'command' lines that
|
||||
# are instructions to pprof, which pprof executes when reading the
|
||||
# are instructions to jeprof, which jeprof executes when reading the
|
||||
# header. All 'command' lines start with a %. After the command
|
||||
# lines is the 'header line', which is a profile-specific line that
|
||||
# indicates what type of profile it is, and perhaps other global
|
||||
@ -4256,10 +4258,10 @@ sub ReadSynchProfile {
|
||||
} elsif ($variable eq "sampling period") {
|
||||
$sampling_period = $value;
|
||||
} elsif ($variable eq "ms since reset") {
|
||||
# Currently nothing is done with this value in pprof
|
||||
# Currently nothing is done with this value in jeprof
|
||||
# So we just silently ignore it for now
|
||||
} elsif ($variable eq "discarded samples") {
|
||||
# Currently nothing is done with this value in pprof
|
||||
# Currently nothing is done with this value in jeprof
|
||||
# So we just silently ignore it for now
|
||||
} else {
|
||||
printf STDERR ("Ignoring unnknown variable in /contention output: " .
|
||||
@ -4565,7 +4567,7 @@ sub ParseLibraries {
|
||||
}
|
||||
|
||||
# Add two hex addresses of length $address_length.
|
||||
# Run pprof --test for unit test if this is changed.
|
||||
# Run jeprof --test for unit test if this is changed.
|
||||
sub AddressAdd {
|
||||
my $addr1 = shift;
|
||||
my $addr2 = shift;
|
||||
@ -4619,7 +4621,7 @@ sub AddressAdd {
|
||||
|
||||
|
||||
# Subtract two hex addresses of length $address_length.
|
||||
# Run pprof --test for unit test if this is changed.
|
||||
# Run jeprof --test for unit test if this is changed.
|
||||
sub AddressSub {
|
||||
my $addr1 = shift;
|
||||
my $addr2 = shift;
|
||||
@ -4671,7 +4673,7 @@ sub AddressSub {
|
||||
}
|
||||
|
||||
# Increment a hex addresses of length $address_length.
|
||||
# Run pprof --test for unit test if this is changed.
|
||||
# Run jeprof --test for unit test if this is changed.
|
||||
sub AddressInc {
|
||||
my $addr = shift;
|
||||
my $sum;
|
||||
@ -4989,7 +4991,7 @@ sub UnparseAddress {
|
||||
# 32-bit or ELF 64-bit executable file. The location of the tools
|
||||
# is determined by considering the following options in this order:
|
||||
# 1) --tools option, if set
|
||||
# 2) PPROF_TOOLS environment variable, if set
|
||||
# 2) JEPROF_TOOLS environment variable, if set
|
||||
# 3) the environment
|
||||
sub ConfigureObjTools {
|
||||
my $prog_file = shift;
|
||||
@ -5022,7 +5024,7 @@ sub ConfigureObjTools {
|
||||
# For windows, we provide a version of nm and addr2line as part of
|
||||
# the opensource release, which is capable of parsing
|
||||
# Windows-style PDB executables. It should live in the path, or
|
||||
# in the same directory as pprof.
|
||||
# in the same directory as jeprof.
|
||||
$obj_tool_map{"nm_pdb"} = "nm-pdb";
|
||||
$obj_tool_map{"addr2line_pdb"} = "addr2line-pdb";
|
||||
}
|
||||
@ -5041,20 +5043,20 @@ sub ConfigureObjTools {
|
||||
}
|
||||
|
||||
# Returns the path of a caller-specified object tool. If --tools or
|
||||
# PPROF_TOOLS are specified, then returns the full path to the tool
|
||||
# JEPROF_TOOLS are specified, then returns the full path to the tool
|
||||
# with that prefix. Otherwise, returns the path unmodified (which
|
||||
# means we will look for it on PATH).
|
||||
sub ConfigureTool {
|
||||
my $tool = shift;
|
||||
my $path;
|
||||
|
||||
# --tools (or $PPROF_TOOLS) is a comma separated list, where each
|
||||
# --tools (or $JEPROF_TOOLS) is a comma separated list, where each
|
||||
# item is either a) a pathname prefix, or b) a map of the form
|
||||
# <tool>:<path>. First we look for an entry of type (b) for our
|
||||
# tool. If one is found, we use it. Otherwise, we consider all the
|
||||
# pathname prefixes in turn, until one yields an existing file. If
|
||||
# none does, we use a default path.
|
||||
my $tools = $main::opt_tools || $ENV{"PPROF_TOOLS"} || "";
|
||||
my $tools = $main::opt_tools || $ENV{"JEPROF_TOOLS"} || "";
|
||||
if ($tools =~ m/(,|^)\Q$tool\E:([^,]*)/) {
|
||||
$path = $2;
|
||||
# TODO(csilvers): sanity-check that $path exists? Hard if it's relative.
|
||||
@ -5068,11 +5070,11 @@ sub ConfigureTool {
|
||||
}
|
||||
if (!$path) {
|
||||
error("No '$tool' found with prefix specified by " .
|
||||
"--tools (or \$PPROF_TOOLS) '$tools'\n");
|
||||
"--tools (or \$JEPROF_TOOLS) '$tools'\n");
|
||||
}
|
||||
} else {
|
||||
# ... otherwise use the version that exists in the same directory as
|
||||
# pprof. If there's nothing there, use $PATH.
|
||||
# jeprof. If there's nothing there, use $PATH.
|
||||
$0 =~ m,[^/]*$,; # this is everything after the last slash
|
||||
my $dirname = $`; # this is everything up to and including the last slash
|
||||
if (-x "$dirname$tool") {
|
||||
@ -5102,7 +5104,7 @@ sub cleanup {
|
||||
unlink($main::tmpfile_sym);
|
||||
unlink(keys %main::tempnames);
|
||||
|
||||
# We leave any collected profiles in $HOME/pprof in case the user wants
|
||||
# We leave any collected profiles in $HOME/jeprof in case the user wants
|
||||
# to look at them later. We print a message informing them of this.
|
||||
if ((scalar(@main::profile_files) > 0) &&
|
||||
defined($main::collected_profile)) {
|
||||
@ -5111,7 +5113,7 @@ sub cleanup {
|
||||
}
|
||||
print STDERR "If you want to investigate this profile further, you can do:\n";
|
||||
print STDERR "\n";
|
||||
print STDERR " pprof \\\n";
|
||||
print STDERR " jeprof \\\n";
|
||||
print STDERR " $main::prog \\\n";
|
||||
print STDERR " $main::collected_profile\n";
|
||||
print STDERR "\n";
|
||||
@ -5296,7 +5298,7 @@ sub GetProcedureBoundaries {
|
||||
# The test vectors for AddressAdd/Sub/Inc are 8-16-nibble hex strings.
|
||||
# To make them more readable, we add underscores at interesting places.
|
||||
# This routine removes the underscores, producing the canonical representation
|
||||
# used by pprof to represent addresses, particularly in the tested routines.
|
||||
# used by jeprof to represent addresses, particularly in the tested routines.
|
||||
sub CanonicalHex {
|
||||
my $arg = shift;
|
||||
return join '', (split '_',$arg);
|
@ -1607,7 +1607,7 @@ AC_CONFIG_HEADERS([$cfghdrs_tup])
|
||||
dnl ============================================================================
|
||||
dnl Generate outputs.
|
||||
|
||||
AC_CONFIG_FILES([$cfgoutputs_tup config.stamp bin/jemalloc-config bin/jemalloc.sh])
|
||||
AC_CONFIG_FILES([$cfgoutputs_tup config.stamp bin/jemalloc-config bin/jemalloc.sh bin/jeprof])
|
||||
AC_SUBST([cfgoutputs_in])
|
||||
AC_SUBST([cfgoutputs_out])
|
||||
AC_OUTPUT
|
||||
|
@ -1132,8 +1132,9 @@ malloc_conf = "xmalloc:true";]]></programlisting>
|
||||
option for information on high-water-triggered profile dumping, and the
|
||||
<link linkend="opt.prof_final"><mallctl>opt.prof_final</mallctl></link>
|
||||
option for final profile dumping. Profile output is compatible with
|
||||
the included <command>pprof</command> Perl script, which originates
|
||||
from the <ulink url="http://code.google.com/p/gperftools/">gperftools
|
||||
the <command>jeprof</command> command, which is based on the
|
||||
<command>pprof</command> that is developed as part of the <ulink
|
||||
url="http://code.google.com/p/gperftools/">gperftools
|
||||
package</ulink>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -1418,7 +1418,7 @@ prof_leakcheck(const prof_cnt_t *cnt_all, size_t leak_ngctx,
|
||||
cnt_all->curobjs, (cnt_all->curobjs != 1) ? "s" : "",
|
||||
leak_ngctx, (leak_ngctx != 1) ? "s" : "");
|
||||
malloc_printf(
|
||||
"<jemalloc>: Run pprof on \"%s\" for leak detail\n",
|
||||
"<jemalloc>: Run jeprof on \"%s\" for leak detail\n",
|
||||
filename);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user