mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-04-06 14:21:43 +08:00
* gprof.h, gprof.c, printfgprof.c: Add support for two
output styles: The default is similar to the old FSF gprof, while -T sets the variable bsd_style_output, which causes output matching Berkeley's gprof. The biggest differences are that with the FSF style output, the flat profile comes before the call graph; numbers come before explanations; and there is less gratuitous white space. * gprof.h, gprof.c, printfgprof.c: New discard_underscores variable causes discarding of initial underscores when printing symbol names. It is set unless there is a "main" symbol (without an underscore). * printfgprof.c: New function printnameonly(), called by printname(). It handles stripping of initial '_', as well as C++ name-demangling. * gprof.callg, gprof.flat, make-c-prog.awk: Removed. It is just as convenient to edit blurbs.c directly. * Makefile.in: Removed rule for making blurbs.c. * blurbs.c: This is now a true source file (as opposed to being generated from gprof.callg and gprof.flat). Change style to use one long string literal, instead of one literal per output line. Add FSF-style blurb for call graph.
This commit is contained in:
parent
3402b1cff2
commit
dc1d1ca5e8
@ -36,14 +36,11 @@ dummy.h
|
||||
gmon.h
|
||||
gprof.1
|
||||
gprof.c
|
||||
gprof.callg
|
||||
gprof.flat
|
||||
gprof.h
|
||||
hertz.c
|
||||
i386.c
|
||||
i386.h
|
||||
lookup.c
|
||||
make-c-prog.awk
|
||||
printgprof.c
|
||||
printlist.c
|
||||
sparc.c
|
||||
|
@ -1,3 +1,27 @@
|
||||
Sun Aug 30 19:54:53 1992 Per Bothner (bothner@rtl.cygnus.com)
|
||||
|
||||
* gprof.h, gprof.c, printfgprof.c: Add support for two
|
||||
output styles: The default is similar to the old FSF gprof,
|
||||
while -T sets the variable bsd_style_output, which causes
|
||||
output matching Berkeley's gprof. The biggest differences
|
||||
are that with the FSF style output, the flat profile comes
|
||||
before the call graph; numbers come before explanations;
|
||||
and there is less gratuitous white space.
|
||||
* gprof.h, gprof.c, printfgprof.c: New discard_underscores
|
||||
variable causes discarding of initial underscores when
|
||||
printing symbol names. It is set unless there is a "main"
|
||||
symbol (without an underscore).
|
||||
* printfgprof.c: New function printnameonly(), called
|
||||
by printname(). It handles stripping of initial '_',
|
||||
as well as C++ name-demangling.
|
||||
* gprof.callg, gprof.flat, make-c-prog.awk: Removed.
|
||||
It is just as convenient to edit blurbs.c directly.
|
||||
* Makefile.in: Removed rule for making blurbs.c.
|
||||
* blurbs.c: This is now a true source file (as opposed
|
||||
to being generated from gprof.callg and gprof.flat).
|
||||
Change style to use one long string literal, instead of
|
||||
one literal per output line. Add FSF-style blurb for call graph.
|
||||
|
||||
Wed Aug 19 14:36:39 1992 Ian Lance Taylor (ian@cygnus.com)
|
||||
|
||||
* Makefile.in: always create installation directories.
|
||||
|
@ -53,12 +53,6 @@ install: all
|
||||
$(PROG): $(OBJS)
|
||||
$(CC) $(CFLAGS) $(OBJS) -o $(PROG) $(LIBS)
|
||||
|
||||
# Make blurbs.c from gprof.callg and gprof.flat
|
||||
blurbs.c: $(srcdir)/gprof.callg $(srcdir)/gprof.flat $(srcdir)/make-c-prog.awk
|
||||
awk -f $(srcdir)/make-c-prog.awk > ./blurbs.c \
|
||||
FUNCTION=flat_blurb $(srcdir)/gprof.flat \
|
||||
FUNCTION=callg_blurb $(srcdir)/gprof.callg \
|
||||
|
||||
clean:
|
||||
-rm -f $(OBJS) core gprof nohup.out
|
||||
|
||||
|
349
gprof/blurbs.c
349
gprof/blurbs.c
@ -1,156 +1,219 @@
|
||||
/* ==> Do not modify this file!! It is created automatically
|
||||
by make-c-prog.awk; modify make-c-prog.awk instead. <== */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "gprof.h"
|
||||
|
||||
void
|
||||
flat_blurb (file)
|
||||
FILE *file;
|
||||
{
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("flat profile:\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs (" % the percentage of the total running time of the\n", file);
|
||||
fputs ("time program used by this function.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("cumulative a running sum of the number of seconds accounted\n", file);
|
||||
fputs (" seconds for by this function and those listed above it.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs (" self the number of seconds accounted for by this\n", file);
|
||||
fputs ("seconds function alone. This is the major sort for this\n", file);
|
||||
fputs (" listing.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("calls the number of times this function was invoked, if\n", file);
|
||||
fputs (" this function is profiled, else blank.\n", file);
|
||||
fputs (" \n", file);
|
||||
fputs (" self the average number of milliseconds spent in this\n", file);
|
||||
fputs ("ms/call function per call, if this function is profiled,\n", file);
|
||||
fputs (" else blank.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs (" total the average number of milliseconds spent in this\n", file);
|
||||
fputs ("ms/call function and its descendents per call, if this \n", file);
|
||||
fputs (" function is profiled, else blank.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("name the name of the function. This is the minor sort\n", file);
|
||||
fputs (" for this listing. The index shows the location of\n", file);
|
||||
fputs (" the function in the gprof listing. If the index is\n", file);
|
||||
fputs (" in parenthesis it shows where it would appear in\n", file);
|
||||
fputs (" the gprof listing if it were to be printed.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs("\n\
|
||||
% the percentage of the total running time of the\n\
|
||||
time program used by this function.\n\
|
||||
\n\
|
||||
cumulative a running sum of the number of seconds accounted\n\
|
||||
seconds for by this function and those listed above it.\n\
|
||||
\n\
|
||||
self the number of seconds accounted for by this\n\
|
||||
seconds function alone. This is the major sort for this\n\
|
||||
listing.\n\
|
||||
\n\
|
||||
calls the number of times this function was invoked, if\n\
|
||||
this function is profiled, else blank.\n\
|
||||
\n\
|
||||
self the average number of milliseconds spent in this\n\
|
||||
ms/call function per call, if this function is profiled,\n\
|
||||
else blank.\n\
|
||||
\n\
|
||||
total the average number of milliseconds spent in this\n\
|
||||
ms/call function and its descendents per call, if this \n\
|
||||
function is profiled, else blank.\n\
|
||||
\n\
|
||||
name the name of the function. This is the minor sort\n\
|
||||
for this listing. The index shows the location of\n\
|
||||
the function in the gprof listing. If the index is\n\
|
||||
in parenthesis it shows where it would appear in\n\
|
||||
the gprof listing if it were to be printed.\n\
|
||||
\n", file);
|
||||
}
|
||||
|
||||
static char *callg_blurb_bsd = "\n\
|
||||
\n\
|
||||
\n\
|
||||
call graph profile:\n\
|
||||
The sum of self and descendents is the major sort\n\
|
||||
for this listing.\n\
|
||||
\n\
|
||||
function entries:\n\
|
||||
\n\
|
||||
index the index of the function in the call graph\n\
|
||||
listing, as an aid to locating it (see below).\n\
|
||||
\n\
|
||||
%time the percentage of the total time of the program\n\
|
||||
accounted for by this function and its\n\
|
||||
descendents.\n\
|
||||
\n\
|
||||
self the number of seconds spent in this function\n\
|
||||
itself.\n\
|
||||
\n\
|
||||
descendents\n\
|
||||
the number of seconds spent in the descendents of\n\
|
||||
this function on behalf of this function.\n\
|
||||
\n\
|
||||
called the number of times this function is called (other\n\
|
||||
than recursive calls).\n\
|
||||
\n\
|
||||
self the number of times this function calls itself\n\
|
||||
recursively.\n\
|
||||
\n\
|
||||
name the name of the function, with an indication of\n\
|
||||
its membership in a cycle, if any.\n\
|
||||
\n\
|
||||
index the index of the function in the call graph\n\
|
||||
listing, as an aid to locating it.\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
parent listings:\n\
|
||||
\n\
|
||||
self* the number of seconds of this function's self time\n\
|
||||
which is due to calls from this parent.\n\
|
||||
\n\
|
||||
descendents*\n\
|
||||
the number of seconds of this function's\n\
|
||||
descendent time which is due to calls from this\n\
|
||||
parent.\n\
|
||||
\n\
|
||||
called** the number of times this function is called by\n\
|
||||
this parent. This is the numerator of the\n\
|
||||
fraction which divides up the function's time to\n\
|
||||
its parents.\n\
|
||||
\n\
|
||||
total* the number of times this function was called by\n\
|
||||
all of its parents. This is the denominator of\n\
|
||||
the propagation fraction.\n\
|
||||
\n\
|
||||
parents the name of this parent, with an indication of the\n\
|
||||
parent's membership in a cycle, if any.\n\
|
||||
\n\
|
||||
index the index of this parent in the call graph\n\
|
||||
listing, as an aid in locating it.\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
children listings:\n\
|
||||
\n\
|
||||
self* the number of seconds of this child's self time\n\
|
||||
which is due to being called by this function.\n\
|
||||
\n\
|
||||
descendent*\n\
|
||||
the number of seconds of this child's descendent's\n\
|
||||
time which is due to being called by this\n\
|
||||
function.\n\
|
||||
\n\
|
||||
called** the number of times this child is called by this\n\
|
||||
function. This is the numerator of the\n\
|
||||
propagation fraction for this child.\n\
|
||||
\n\
|
||||
total* the number of times this child is called by all\n\
|
||||
functions. This is the denominator of the\n\
|
||||
propagation fraction.\n\
|
||||
\n\
|
||||
children the name of this child, and an indication of its\n\
|
||||
membership in a cycle, if any.\n\
|
||||
\n\
|
||||
index the index of this child in the call graph listing,\n\
|
||||
as an aid to locating it.\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
* these fields are omitted for parents (or\n\
|
||||
children) in the same cycle as the function. If\n\
|
||||
the function (or child) is a member of a cycle,\n\
|
||||
the propagated times and propagation denominator\n\
|
||||
represent the self time and descendent time of the\n\
|
||||
cycle as a whole.\n\
|
||||
\n\
|
||||
** static-only parents and children are indicated\n\
|
||||
by a call count of 0.\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
cycle listings:\n\
|
||||
the cycle as a whole is listed with the same\n\
|
||||
fields as a function entry. Below it are listed\n\
|
||||
the members of the cycle, and their contributions\n\
|
||||
to the time and call counts of the cycle.\n\
|
||||
\n";
|
||||
|
||||
static char *callg_blurb_fsf = "\n\
|
||||
This table describes the call tree of the program, and was sorted by\n\
|
||||
the total amount of time spent in each function and its children.\n\n\
|
||||
Each entry in this table consists of several lines. The line with the\n\
|
||||
index number at the left hand margin lists the current function.\n\
|
||||
The lines above it list the functions that called this function,\n\
|
||||
and the lines below it list the functions this one called.\n\
|
||||
This line lists:\n\
|
||||
index A unique number given to each element of the table.\n\
|
||||
Index numbers are sorted numerically.\n\
|
||||
The index number is printed next to every function name so\n\
|
||||
it is easier to look up where the function in the table.\n\n\
|
||||
% time This is the percentage of the `total' time that was spent\n\
|
||||
in this function and its children. Note that due to\n\
|
||||
different viewpoints, functions excluded by options, etc,\n\
|
||||
these numbers will NOT add up to 100%.\n\n\
|
||||
self This is the total amount of time spent in this function.\n\n\
|
||||
children This is the total amount of time propagated into this\n\
|
||||
function by its children.\n\n\
|
||||
called This is the number of times the function was called.\n\
|
||||
If the function called itself recursively, the number\n\
|
||||
only includes non-recursive calls, and is followed by\n\
|
||||
a `+' and the number of recursive calls.\n\n\
|
||||
name The name of the current function. The index number is\n\
|
||||
printed after it. If the function is a member of a\n\
|
||||
cycle, the cycle number is printed between the\n\
|
||||
function's name and the index number.\n\n\n\
|
||||
For the function's parents, the fields have the following meanings:\n\n\
|
||||
self This is the amount of time that was propagated directly\n\
|
||||
from the function into this parent.\n\n\
|
||||
children This is the amount of time that was propagated from\n\
|
||||
the function's children into this parent.\n\n\
|
||||
called This is the number of times this parent called the\n\
|
||||
function `/' the total number of times the function\n\
|
||||
was called. Recursive calls to the function are not\n\
|
||||
included in the number after the `/'.\n\n\
|
||||
name This is the name of the parent. The parent's index\n\
|
||||
number is printed after it. If the parent is a\n\
|
||||
member of a cycle, the cycle number is printed between\n\
|
||||
the name and the index number.\n\n\
|
||||
If the parents of the function cannot be determined, the word\n\
|
||||
`<spontaneous>' is printed in the `name' field, and all the other\n\
|
||||
fields are blank.\n\n\
|
||||
For the function's children, the fields have the following meanings:\n\n\
|
||||
self This is the amount of time that was propagated directly\n\
|
||||
from the child into the function.\n\n\
|
||||
children This is the amount of time that was propagated from the\n\
|
||||
child's children to the function.\n\n\
|
||||
called This is the number of times the function called\n\
|
||||
this child `/' the total number of times the child\n\
|
||||
was called. Recursive calls by the child are not\n\
|
||||
listed in the number after the `/'.\n\n\
|
||||
name This is the name of the child. The child's index\n\
|
||||
number is printed after it. If the child is a\n\
|
||||
member of a cycle, the cycle number is printed\n\
|
||||
between the name and the index number.\n\n\
|
||||
If there are any cycles (circles) in the call graph, there is an\n\
|
||||
entry for the cycle-as-a-whole. This entry shows who called the\n\
|
||||
cycle (as parents) and the members of the cycle (as children.)\n\
|
||||
The `+' recursive calls entry shows the number of function calls that\n\
|
||||
were internal to the cycle, and the calls entry for each member shows,\n\
|
||||
for that member, how many times it was called from other members of\n\
|
||||
the cycle.\n\n";
|
||||
|
||||
void
|
||||
callg_blurb (file)
|
||||
FILE *file;
|
||||
{
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("call graph profile:\n", file);
|
||||
fputs (" The sum of self and descendents is the major sort\n", file);
|
||||
fputs (" for this listing.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs (" function entries:\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("index the index of the function in the call graph\n", file);
|
||||
fputs (" listing, as an aid to locating it (see below).\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("%time the percentage of the total time of the program\n", file);
|
||||
fputs (" accounted for by this function and its\n", file);
|
||||
fputs (" descendents.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("self the number of seconds spent in this function\n", file);
|
||||
fputs (" itself.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("descendents\n", file);
|
||||
fputs (" the number of seconds spent in the descendents of\n", file);
|
||||
fputs (" this function on behalf of this function.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("called the number of times this function is called (other\n", file);
|
||||
fputs (" than recursive calls).\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("self the number of times this function calls itself\n", file);
|
||||
fputs (" recursively.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("name the name of the function, with an indication of\n", file);
|
||||
fputs (" its membership in a cycle, if any.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("index the index of the function in the call graph\n", file);
|
||||
fputs (" listing, as an aid to locating it.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs (" parent listings:\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("self* the number of seconds of this function's self time\n", file);
|
||||
fputs (" which is due to calls from this parent.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("descendents*\n", file);
|
||||
fputs (" the number of seconds of this function's\n", file);
|
||||
fputs (" descendent time which is due to calls from this\n", file);
|
||||
fputs (" parent.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("called** the number of times this function is called by\n", file);
|
||||
fputs (" this parent. This is the numerator of the\n", file);
|
||||
fputs (" fraction which divides up the function's time to\n", file);
|
||||
fputs (" its parents.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("total* the number of times this function was called by\n", file);
|
||||
fputs (" all of its parents. This is the denominator of\n", file);
|
||||
fputs (" the propagation fraction.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("parents the name of this parent, with an indication of the\n", file);
|
||||
fputs (" parent's membership in a cycle, if any.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("index the index of this parent in the call graph\n", file);
|
||||
fputs (" listing, as an aid in locating it.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs (" children listings:\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("self* the number of seconds of this child's self time\n", file);
|
||||
fputs (" which is due to being called by this function.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("descendent*\n", file);
|
||||
fputs (" the number of seconds of this child's descendent's\n", file);
|
||||
fputs (" time which is due to being called by this\n", file);
|
||||
fputs (" function.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("called** the number of times this child is called by this\n", file);
|
||||
fputs (" function. This is the numerator of the\n", file);
|
||||
fputs (" propagation fraction for this child.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("total* the number of times this child is called by all\n", file);
|
||||
fputs (" functions. This is the denominator of the\n", file);
|
||||
fputs (" propagation fraction.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("children the name of this child, and an indication of its\n", file);
|
||||
fputs (" membership in a cycle, if any.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("index the index of this child in the call graph listing,\n", file);
|
||||
fputs (" as an aid to locating it.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs (" * these fields are omitted for parents (or\n", file);
|
||||
fputs (" children) in the same cycle as the function. If\n", file);
|
||||
fputs (" the function (or child) is a member of a cycle,\n", file);
|
||||
fputs (" the propagated times and propagation denominator\n", file);
|
||||
fputs (" represent the self time and descendent time of the\n", file);
|
||||
fputs (" cycle as a whole.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs (" ** static-only parents and children are indicated\n", file);
|
||||
fputs (" by a call count of 0.\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs ("\n", file);
|
||||
fputs (" cycle listings:\n", file);
|
||||
fputs (" the cycle as a whole is listed with the same\n", file);
|
||||
fputs (" fields as a function entry. Below it are listed\n", file);
|
||||
fputs (" the members of the cycle, and their contributions\n", file);
|
||||
fputs (" to the time and call counts of the cycle.\n", file);
|
||||
fputs ("\n", file);
|
||||
if (bsd_style_output)
|
||||
fputs(callg_blurb_bsd, file);
|
||||
else
|
||||
fputs(callg_blurb_fsf, file);
|
||||
}
|
||||
|
@ -38,6 +38,9 @@ char *whoami = "gprof";
|
||||
*/
|
||||
char *defaultEs[] = { "mcount" , "__mcleanup" , 0 };
|
||||
|
||||
int discard_underscores = 1; /* Should we discard initial underscores? */
|
||||
int bsd_style_output = 0; /* As opposed to FSF style output */
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
@ -102,6 +105,9 @@ main(argc, argv)
|
||||
case 's':
|
||||
sflag = TRUE;
|
||||
break;
|
||||
case 'T': /* "Traditional" output format */
|
||||
bsd_style_output = 1;
|
||||
break;
|
||||
case 'z':
|
||||
zflag = TRUE;
|
||||
break;
|
||||
@ -165,14 +171,14 @@ main(argc, argv)
|
||||
* assemble the dynamic profile
|
||||
*/
|
||||
timesortnlp = doarcs();
|
||||
/*
|
||||
* print the dynamic profile
|
||||
*/
|
||||
printgprof( timesortnlp );
|
||||
/*
|
||||
* print the flat profile
|
||||
*/
|
||||
printprof();
|
||||
|
||||
if (bsd_style_output) {
|
||||
printgprof( timesortnlp ); /* print the dynamic profile */
|
||||
printprof(); /* print the flat profile */
|
||||
} else {
|
||||
printprof(); /* print the flat profile */
|
||||
printgprof( timesortnlp ); /* print the dynamic profile */
|
||||
}
|
||||
/*
|
||||
* print the index
|
||||
*/
|
||||
@ -230,7 +236,7 @@ bfd *abfd;
|
||||
i = get_symtab_upper_bound (abfd); /* This will probably give us more
|
||||
* than we need, but that's ok.
|
||||
*/
|
||||
syms = (asymbol**)malloc (i);
|
||||
syms = (asymbol**)xmalloc (i);
|
||||
nosyms = bfd_canonicalize_symtab (abfd, syms);
|
||||
|
||||
nname = 0;
|
||||
@ -265,8 +271,16 @@ bfd *abfd;
|
||||
# endif DEBUG
|
||||
continue;
|
||||
}
|
||||
/* Symbol offsets are always section-relative. */
|
||||
npe->value = syms[i]->value + syms[i]->section->vma;
|
||||
npe->name = syms[i]->name;
|
||||
|
||||
/* If we see "main" without an initial '_', we assume
|
||||
names are *not* prefixed by '_'. */
|
||||
if (npe->name[0] == 'm' && discard_underscores
|
||||
&& strcmp(npe->name, "main") == 0)
|
||||
discard_underscores = 0;
|
||||
|
||||
# ifdef DEBUG
|
||||
if ( debug & AOUTDEBUG ) {
|
||||
printf( "[getsymtab] %d %s 0x%08x\n" ,
|
||||
|
@ -68,6 +68,9 @@ char *gmonname;
|
||||
#define GMONNAME "gmon.out"
|
||||
#define GMONSUM "gmon.sum"
|
||||
|
||||
extern int bsd_style_output;
|
||||
extern int discard_underscores;
|
||||
|
||||
/*
|
||||
* a constructed arc,
|
||||
* with pointers to the namelist entry of the parent and the child,
|
||||
@ -92,7 +95,7 @@ typedef struct arcstruct arctype;
|
||||
* its address, the number of calls and compute its share of cpu time.
|
||||
*/
|
||||
struct nl {
|
||||
char *name; /* the name */
|
||||
CONST char *name; /* the name */
|
||||
unsigned long value; /* the pc entry point */
|
||||
unsigned long svalue; /* entry point aligned to histograms */
|
||||
double time; /* ticks in this routine */
|
||||
@ -255,6 +258,7 @@ FILE *openpfile();
|
||||
printprof();
|
||||
readsamples();
|
||||
*/
|
||||
int printnameonly();
|
||||
unsigned long reladdr();
|
||||
/*
|
||||
sortchildren();
|
||||
|
@ -22,6 +22,7 @@ static char sccsid[] = "@(#)printgprof.c 5.7 (Berkeley) 6/1/90";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "gprof.h"
|
||||
#include <demangle.h>
|
||||
|
||||
printprof()
|
||||
{
|
||||
@ -30,7 +31,15 @@ printprof()
|
||||
int index, timecmp();
|
||||
|
||||
actime = 0.0;
|
||||
printf( "\f\n" );
|
||||
if ( bsd_style_output ) {
|
||||
printf( "\f\n" );
|
||||
if ( bflag) {
|
||||
printf( "\n\n\nflat profile:\n" );
|
||||
flat_blurb(stdout);
|
||||
}
|
||||
}
|
||||
else
|
||||
printf ("Flat profile:\n");
|
||||
flatprofheader();
|
||||
/*
|
||||
* Sort the symbol table in by time
|
||||
@ -49,6 +58,9 @@ printprof()
|
||||
}
|
||||
actime = 0.0;
|
||||
cfree( sortednlp );
|
||||
if ( bflag && !bsd_style_output ) {
|
||||
flat_blurb(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
timecmp( npp1 , npp2 )
|
||||
@ -76,20 +88,23 @@ timecmp( npp1 , npp2 )
|
||||
flatprofheader()
|
||||
{
|
||||
|
||||
if ( bflag ) {
|
||||
flat_blurb(stdout);
|
||||
}
|
||||
printf( "\ngranularity: each sample hit covers %d byte(s)" ,
|
||||
(long) scale * sizeof(UNIT) );
|
||||
if ( totime > 0.0 ) {
|
||||
printf( " for %.2f%% of %.2f seconds\n\n" ,
|
||||
100.0/totime , totime / hz );
|
||||
} else {
|
||||
printf( " no time accumulated\n\n" );
|
||||
if (bsd_style_output) {
|
||||
printf( "\ngranularity: each sample hit covers %d byte(s)" ,
|
||||
(long) scale * sizeof(UNIT) );
|
||||
if ( totime > 0.0 ) {
|
||||
printf( " for %.2f%% of %.2f seconds\n\n" ,
|
||||
100.0/totime , totime / hz );
|
||||
} else {
|
||||
printf( " no time accumulated\n\n" );
|
||||
/*
|
||||
* this doesn't hurt since all the numerators will be zero.
|
||||
*/
|
||||
totime = 1.0;
|
||||
totime = 1.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf( "\nEach sample counts as %g seconds.\n",
|
||||
1.0 / hz);
|
||||
}
|
||||
printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" ,
|
||||
"% " , "cumulative" , "self " , "" , "self " , "total " , "" );
|
||||
@ -106,8 +121,12 @@ flatprofline( np )
|
||||
return;
|
||||
}
|
||||
actime += np -> time;
|
||||
printf( "%5.1f %10.2f %8.2f" ,
|
||||
100 * np -> time / totime , actime / hz , np -> time / hz );
|
||||
if (bsd_style_output)
|
||||
printf( "%5.1f %10.2f %8.2f" ,
|
||||
100 * np -> time / totime , actime / hz , np -> time / hz );
|
||||
else
|
||||
printf( "%6.2f %9.2f %8.2f" ,
|
||||
100 * np -> time / totime , actime / hz , np -> time / hz );
|
||||
if ( np -> ncall != 0 ) {
|
||||
printf( " %8d %8.2f %8.2f " , np -> ncall ,
|
||||
1000 * np -> time / hz / np -> ncall ,
|
||||
@ -115,16 +134,21 @@ flatprofline( np )
|
||||
} else {
|
||||
printf( " %8.8s %8.8s %8.8s " , "" , "" , "" );
|
||||
}
|
||||
printname( np );
|
||||
if (bsd_style_output)
|
||||
printname( np );
|
||||
else
|
||||
printnameonly( np );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
gprofheader()
|
||||
{
|
||||
|
||||
if ( bflag ) {
|
||||
callg_blurb(stdout);
|
||||
}
|
||||
if (!bsd_style_output)
|
||||
if (bflag)
|
||||
printf ("\t\t Call graph (explanation follows)\n\n");
|
||||
else
|
||||
printf ("\t\t\tCall graph\n\n");
|
||||
printf( "\ngranularity: each sample hit covers %d byte(s)" ,
|
||||
(long) scale * sizeof(UNIT) );
|
||||
if ( printtime > 0.0 ) {
|
||||
@ -137,14 +161,18 @@ gprofheader()
|
||||
*/
|
||||
printtime = 1.0;
|
||||
}
|
||||
printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
|
||||
"" , "" , "" , "" , "called" , "total" , "parents");
|
||||
printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
|
||||
"index" , "%time" , "self" , "descendents" ,
|
||||
"called" , "self" , "name" , "index" );
|
||||
printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
|
||||
"" , "" , "" , "" , "called" , "total" , "children");
|
||||
printf( "\n" );
|
||||
if (bsd_style_output) {
|
||||
printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
|
||||
"" , "" , "" , "" , "called" , "total" , "parents");
|
||||
printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
|
||||
"index" , "%time" , "self" , "descendents" ,
|
||||
"called" , "self" , "name" , "index" );
|
||||
printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
|
||||
"" , "" , "" , "" , "called" , "total" , "children");
|
||||
printf( "\n" );
|
||||
} else {
|
||||
printf( "index %% time self children called name\n" );
|
||||
}
|
||||
}
|
||||
|
||||
gprofline( np )
|
||||
@ -153,11 +181,13 @@ gprofline( np )
|
||||
char kirkbuffer[ BUFSIZ ];
|
||||
|
||||
sprintf( kirkbuffer , "[%d]" , np -> index );
|
||||
printf( "%-6.6s %5.1f %7.2f %11.2f" ,
|
||||
kirkbuffer ,
|
||||
100 * ( np -> propself + np -> propchild ) / printtime ,
|
||||
np -> propself / hz ,
|
||||
np -> propchild / hz );
|
||||
printf(bsd_style_output
|
||||
? "%-6.6s %5.1f %7.2f %11.2f"
|
||||
: "%-6.6s %5.1f %7.2f %7.2f" ,
|
||||
kirkbuffer ,
|
||||
100 * ( np -> propself + np -> propchild ) / printtime ,
|
||||
np -> propself / hz ,
|
||||
np -> propchild / hz );
|
||||
if ( ( np -> ncall + np -> selfcalls ) != 0 ) {
|
||||
printf( " %7d" , np -> ncall );
|
||||
if ( np -> selfcalls != 0 ) {
|
||||
@ -181,6 +211,9 @@ printgprof(timesortnlp)
|
||||
/*
|
||||
* Print out the structured profiling list
|
||||
*/
|
||||
if ( bflag && bsd_style_output ) {
|
||||
callg_blurb(stdout);
|
||||
}
|
||||
gprofheader();
|
||||
for ( index = 0 ; index < nname + ncycle ; index ++ ) {
|
||||
parentp = timesortnlp[ index ];
|
||||
@ -205,11 +238,16 @@ printgprof(timesortnlp)
|
||||
gprofline( parentp );
|
||||
printchildren( parentp );
|
||||
}
|
||||
printf( "\n" );
|
||||
if (bsd_style_output)
|
||||
printf( "\n" );
|
||||
printf( "-----------------------------------------------\n" );
|
||||
printf( "\n" );
|
||||
if (bsd_style_output)
|
||||
printf( "\n" );
|
||||
}
|
||||
cfree( timesortnlp );
|
||||
if ( bflag && !bsd_style_output) {
|
||||
callg_blurb(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -267,7 +305,9 @@ printparents( childp )
|
||||
cycleheadp = childp;
|
||||
}
|
||||
if ( childp -> parents == 0 ) {
|
||||
printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" ,
|
||||
printf(bsd_style_output
|
||||
? "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n"
|
||||
: "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" ,
|
||||
"" , "" , "" , "" , "" , "" );
|
||||
return;
|
||||
}
|
||||
@ -279,7 +319,9 @@ printparents( childp )
|
||||
/*
|
||||
* selfcall or call among siblings
|
||||
*/
|
||||
printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " ,
|
||||
printf(bsd_style_output
|
||||
? "%6.6s %5.5s %7.7s %11.11s %7d %7.7s "
|
||||
: "%6.6s %5.5s %7.7s %7.7s %7d %7.7s " ,
|
||||
"" , "" , "" , "" ,
|
||||
arcp -> arc_count , "" );
|
||||
printname( parentp );
|
||||
@ -288,7 +330,9 @@ printparents( childp )
|
||||
/*
|
||||
* regular parent of child
|
||||
*/
|
||||
printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " ,
|
||||
printf(bsd_style_output
|
||||
? "%6.6s %5.5s %7.2f %11.2f %7d/%-7d "
|
||||
: "%6.6s %5.5s %7.2f %7.2f %7d/%-7d ",
|
||||
"" , "" ,
|
||||
arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
|
||||
arcp -> arc_count , cycleheadp -> ncall );
|
||||
@ -313,39 +357,66 @@ printchildren( parentp )
|
||||
/*
|
||||
* self call or call to sibling
|
||||
*/
|
||||
printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " ,
|
||||
"" , "" , "" , "" , arcp -> arc_count , "" );
|
||||
printf(bsd_style_output
|
||||
? "%6.6s %5.5s %7.7s %11.11s %7d %7.7s "
|
||||
: "%6.6s %5.5s %7.7s %7.7s %7d %7.7s " ,
|
||||
"" , "" , "" , "" , arcp -> arc_count , "" );
|
||||
printname( childp );
|
||||
printf( "\n" );
|
||||
} else {
|
||||
/*
|
||||
* regular child of parent
|
||||
*/
|
||||
printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " ,
|
||||
"" , "" ,
|
||||
arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
|
||||
arcp -> arc_count , childp -> cyclehead -> ncall );
|
||||
printf(bsd_style_output
|
||||
? "%6.6s %5.5s %7.2f %11.2f %7d/%-7d "
|
||||
: "%6.6s %5.5s %7.2f %7.2f %7d/%-7d " ,
|
||||
"" , "" ,
|
||||
arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
|
||||
arcp -> arc_count , childp -> cyclehead -> ncall );
|
||||
printname( childp );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Print name of symbol. Return number of characters printed. */
|
||||
|
||||
int
|
||||
printnameonly ( selfp )
|
||||
nltype *selfp;
|
||||
{
|
||||
int size = 0;
|
||||
CONST char *name = selfp->name;
|
||||
if (name != NULL) {
|
||||
char *demangled = NULL;
|
||||
if (!bsd_style_output) {
|
||||
if (name[0] == '_' && name[1] && discard_underscores)
|
||||
name++;
|
||||
demangled = cplus_demangle (name, DMGL_ANSI|DMGL_PARAMS);
|
||||
if (demangled)
|
||||
name = demangled;
|
||||
}
|
||||
printf( "%s" , name );
|
||||
size = strlen (name);
|
||||
if (demangled)
|
||||
free (demangled);
|
||||
#ifdef DEBUG
|
||||
if ( debug & DFNDEBUG ) {
|
||||
printf( "{%d} " , selfp -> toporder );
|
||||
}
|
||||
if ( debug & PROPDEBUG ) {
|
||||
printf( "%5.2f%% " , selfp -> propfraction );
|
||||
}
|
||||
#endif DEBUG
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
printname( selfp )
|
||||
nltype *selfp;
|
||||
{
|
||||
printnameonly (selfp);
|
||||
|
||||
if ( selfp -> name != 0 ) {
|
||||
printf( "%s" , selfp -> name );
|
||||
# ifdef DEBUG
|
||||
if ( debug & DFNDEBUG ) {
|
||||
printf( "{%d} " , selfp -> toporder );
|
||||
}
|
||||
if ( debug & PROPDEBUG ) {
|
||||
printf( "%5.2f%% " , selfp -> propfraction );
|
||||
}
|
||||
# endif DEBUG
|
||||
}
|
||||
if ( selfp -> cycleno != 0 ) {
|
||||
printf( " <cycle %d>" , selfp -> cycleno );
|
||||
}
|
||||
@ -643,7 +714,7 @@ printindex()
|
||||
nltype **namesortnlp;
|
||||
register nltype *nlp;
|
||||
int index, nnames, todo, i, j;
|
||||
char peterbuffer[ BUFSIZ ];
|
||||
char peterbuffer[20];
|
||||
|
||||
/*
|
||||
* Now, sort regular function name alphbetically
|
||||
@ -673,7 +744,13 @@ printindex()
|
||||
sprintf( peterbuffer , "(%d)" , nlp -> index );
|
||||
}
|
||||
if ( j < nnames ) {
|
||||
printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name );
|
||||
printf( "%6.6s " , peterbuffer );
|
||||
if (bsd_style_output)
|
||||
printf ("%-19.19s" , nlp->name);
|
||||
else {
|
||||
int size = printnameonly(nlp);
|
||||
for ( ; size < 19; size++) putchar(' ');
|
||||
}
|
||||
} else {
|
||||
printf( "%6.6s " , peterbuffer );
|
||||
sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno );
|
||||
@ -684,3 +761,29 @@ printindex()
|
||||
}
|
||||
cfree( namesortnlp );
|
||||
}
|
||||
|
||||
PTR
|
||||
xmalloc (size)
|
||||
long size;
|
||||
{
|
||||
PTR val = malloc (size);
|
||||
if (val == NULL) {
|
||||
fprintf (stderr, "virtual memory exhaused\n");
|
||||
exit (1);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
PTR
|
||||
xrealloc (oldval, size)
|
||||
PTR oldval;
|
||||
long size;
|
||||
{
|
||||
PTR val = realloc (oldval, size);
|
||||
if (val == NULL) {
|
||||
fprintf (stderr, "virtual memory exhaused\n");
|
||||
exit (1);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user