From: Per Bothner Date: Mon, 31 Aug 1992 03:34:15 +0000 (+0000) Subject: * gprof.h, gprof.c, printfgprof.c: Add support for two X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=dc1d1ca5e89e49f1d0b5bfd417769fc0fcc170a6;hp=3402b1cff22f615e896aa8d0dd2792e910479b78;p=deliverable%2Fbinutils-gdb.git * 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. --- diff --git a/gprof/.Sanitize b/gprof/.Sanitize index 2ee9399171..2afc0bbd25 100644 --- a/gprof/.Sanitize +++ b/gprof/.Sanitize @@ -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 diff --git a/gprof/ChangeLog b/gprof/ChangeLog index c84cf6946a..4277dfcc9e 100644 --- a/gprof/ChangeLog +++ b/gprof/ChangeLog @@ -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. diff --git a/gprof/Makefile.in b/gprof/Makefile.in index caf20773fc..26ef25abe6 100644 --- a/gprof/Makefile.in +++ b/gprof/Makefile.in @@ -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 diff --git a/gprof/blurbs.c b/gprof/blurbs.c index 1a2d3a956d..e586fa2d43 100644 --- a/gprof/blurbs.c +++ b/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 +#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\ + `' 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); } diff --git a/gprof/gprof.c b/gprof/gprof.c index 5061efa56e..6994d8f5cb 100644 --- a/gprof/gprof.c +++ b/gprof/gprof.c @@ -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" , diff --git a/gprof/gprof.h b/gprof/gprof.h index 52cf896567..28813a3011 100644 --- a/gprof/gprof.h +++ b/gprof/gprof.h @@ -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(); diff --git a/gprof/printgprof.c b/gprof/printgprof.c index 5ef0c87b8c..868d647c3a 100644 --- a/gprof/printgprof.c +++ b/gprof/printgprof.c @@ -22,6 +22,7 @@ static char sccsid[] = "@(#)printgprof.c 5.7 (Berkeley) 6/1/90"; #endif /* not lint */ #include "gprof.h" +#include 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 \n" , + printf(bsd_style_output + ? "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s \n" + : "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s \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( " " , 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 , "" , 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; +} +