summaryrefslogtreecommitdiffstats
path: root/sys-utils/readprofile.c
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:46 +0100
committerKarel Zak2006-12-07 00:25:46 +0100
commitc07ebfa1e02d208ab12430e6791ea147bcfaf9c0 (patch)
treed44a755098286f5d553c7aea1a73d98c2995d6ec /sys-utils/readprofile.c
parentImported from util-linux-2.10s tarball. (diff)
downloadkernel-qcow2-util-linux-c07ebfa1e02d208ab12430e6791ea147bcfaf9c0.tar.gz
kernel-qcow2-util-linux-c07ebfa1e02d208ab12430e6791ea147bcfaf9c0.tar.xz
kernel-qcow2-util-linux-c07ebfa1e02d208ab12430e6791ea147bcfaf9c0.zip
Imported from util-linux-2.11b tarball.
Diffstat (limited to 'sys-utils/readprofile.c')
-rw-r--r--sys-utils/readprofile.c335
1 files changed, 174 insertions, 161 deletions
diff --git a/sys-utils/readprofile.c b/sys-utils/readprofile.c
index b531fa90a..189322623 100644
--- a/sys-utils/readprofile.c
+++ b/sys-utils/readprofile.c
@@ -19,10 +19,12 @@
*/
/*
- * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
+ * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
* - added Native Language Support
* 1999-09-01 Stephane Eranian <eranian@cello.hpl.hp.com>
* - 64bit clean patch
+ * 3Feb2001 Andrew Morton <andrewm@uow.edu.au>
+ * - -M option to write profile multiplier.
*/
#include <errno.h>
@@ -44,7 +46,7 @@ static char *prgname;
/* These are the defaults */
static char defaultmap[]="/usr/src/linux/System.map";
static char defaultpro[]="/proc/profile";
-static char optstring[]="m:p:itvarV";
+static char optstring[]="M:m:p:itvarV";
static void
usage(void) {
@@ -52,6 +54,7 @@ usage(void) {
_("%s: Usage: \"%s [options]\n"
"\t -m <mapfile> (default = \"%s\")\n"
"\t -p <pro-file> (default = \"%s\")\n"
+ "\t -M <mult> set the profiling multiplier to <mult>\n"
"\t -i print only info about the sampling step\n"
"\t -v print verbose data\n"
"\t -a print all symbols, even if count is 0\n"
@@ -63,171 +66,181 @@ usage(void) {
static FILE *
myopen(char *name, char *mode, int *flag) {
- static char cmdline[S_LEN];
-
- if (!strcmp(name+strlen(name)-3,".gz"))
- {
- *flag=1;
- sprintf(cmdline,"zcat %s", name);
- return popen(cmdline,mode);
- }
- *flag=0;
- return fopen(name,mode);
+ static char cmdline[S_LEN];
+
+ if (!strcmp(name+strlen(name)-3,".gz")) {
+ *flag=1;
+ sprintf(cmdline,"zcat %s", name);
+ return popen(cmdline,mode);
+ }
+ *flag=0;
+ return fopen(name,mode);
}
int
main (int argc, char **argv) {
- FILE *pro;
- FILE *map;
- int proFd;
- char *mapFile, *proFile;
- unsigned long len=0, add0=0, indx=0;
- unsigned int step;
- unsigned int *buf, total, fn_len;
- unsigned long fn_add, next_add; /* current and next address */
- char fn_name[S_LEN], next_name[S_LEN]; /* current and next name */
- char mode[8];
- int c;
- int optAll=0, optInfo=0, optReset=0, optVerbose=0;
- char mapline[S_LEN];
- int maplineno=1;
- int popenMap; /* flag to tell if popen() has been used */
+ FILE *map;
+ int proFd;
+ char *mapFile, *proFile, *mult=0;
+ unsigned long len=0, add0=0, indx=0;
+ unsigned int step;
+ unsigned int *buf, total, fn_len;
+ unsigned long fn_add, next_add; /* current and next address */
+ char fn_name[S_LEN], next_name[S_LEN]; /* current and next name */
+ char mode[8];
+ int c;
+ int optAll=0, optInfo=0, optReset=0, optVerbose=0;
+ char mapline[S_LEN];
+ int maplineno=1;
+ int popenMap; /* flag to tell if popen() has been used */
#define next (current^1)
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-
- prgname=argv[0];
- proFile=defaultpro;
- mapFile=defaultmap;
-
- while ((c=getopt(argc,argv,optstring))!=-1)
- {
- switch(c)
- {
- case 'm': mapFile=optarg; break;
- case 'p': proFile=optarg; break;
- case 'a': optAll++; break;
- case 'i': optInfo++; break;
- case 'r': optReset++; break;
- case 'v': optVerbose++; break;
- case 'V': printf(_("%s Version %s\n"),prgname,RELEASE); exit(0);
- default: usage();
- }
- }
-
- if (optReset)
- {
- /* try to become root, just in case */
- setuid(0);
- pro=fopen(defaultpro,"w");
- if (!pro)
- {perror(proFile); exit(1);}
- fprintf(pro,_("anything\n"));
- fclose(pro);
- exit(0);
- }
-
- /*
- * Use an fd for the profiling buffer, to skip stdio overhead
- */
- if ( ((proFd=open(proFile,O_RDONLY)) < 0)
- || ((int)(len=lseek(proFd,0,SEEK_END)) < 0)
- || (lseek(proFd,0,SEEK_SET)<0) )
- {
- fprintf(stderr,"%s: %s: %s\n",prgname,proFile,strerror(errno));
- exit(1);
- }
-
- if ( !(buf=malloc(len)) )
- { fprintf(stderr,"%s: malloc(): %s\n",prgname, strerror(errno)); exit(1); }
-
- if (read(proFd,buf,len) != len)
- {
- fprintf(stderr,"%s: %s: %s\n",prgname,proFile,strerror(errno));
- exit(1);
- }
- close(proFd);
-
- step=buf[0];
- if (optInfo)
- {
- printf(_("Sampling_step: %i\n"),step);
- exit(0);
- }
-
- total=0;
-
- if (!(map=myopen(mapFile,"r",&popenMap)))
- {fprintf(stderr,"%s: ",prgname);perror(mapFile);exit(1);}
-
- while(fgets(mapline,S_LEN,map))
- {
- if (sscanf(mapline,"%lx %s %s",&fn_add,mode,fn_name)!=3)
- {
- fprintf(stderr,_("%s: %s(%i): wrong map line\n"),
- prgname,mapFile, maplineno);
- exit(1);
- }
- if (!strcmp(fn_name,"_stext")) /* only elf works like this */
- {
- add0=fn_add;
- break;
- }
- }
-
- if (!add0)
- {
- fprintf(stderr,_("%s: can't find \"_stext\" in %s\n"),prgname, mapFile);
- exit(1);
- }
-
- /*
- * Main loop.
- */
- while(fgets(mapline,S_LEN,map))
- {
- unsigned int this=0;
-
- if (sscanf(mapline,"%lx %s %s",&next_add,mode,next_name)!=3)
- {
- fprintf(stderr,_("%s: %s(%i): wrong map line\n"),
- prgname,mapFile, maplineno);
- exit(1);
- }
- /* ignore any LEADING (before a '[tT]' symbol is found) Absolute symbols */
- if (*mode == 'A' && total == 0) continue;
- if (*mode!='T' && *mode!='t') break; /* only text is profiled */
-
- while (indx < (next_add-add0)/step)
- this += buf[indx++];
- total += this;
-
- fn_len = next_add-fn_add;
- if (fn_len && (this || optAll))
- {
- if (optVerbose)
- printf("%08lx %-40s %6i %8.4f\n",
- fn_add,fn_name,this,this/(double)fn_len);
- else
- printf("%6i %-40s %8.4f\n",
- this,fn_name,this/(double)fn_len);
- }
- fn_add=next_add; strcpy(fn_name,next_name);
- }
- /* trailer */
- if (optVerbose)
- printf("%08x %-40s %6i %8.4f\n",
- 0,"total",total,total/(double)(fn_add-add0));
- else
- printf("%6i %-40s %8.4f\n",
- total,_("total"),total/(double)(fn_add-add0));
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ prgname=argv[0];
+ proFile=defaultpro;
+ mapFile=defaultmap;
+
+ while ((c=getopt(argc,argv,optstring))!=-1) {
+ switch(c) {
+ case 'm': mapFile=optarg; break;
+ case 'p': proFile=optarg; break;
+ case 'a': optAll++; break;
+ case 'i': optInfo++; break;
+ case 'M': mult=optarg; break;
+ case 'r': optReset++; break;
+ case 'v': optVerbose++; break;
+ case 'V': printf(_("%s Version %s\n"),prgname,RELEASE);
+ exit(0);
+ default: usage();
+ }
+ }
+
+ if (optReset || mult) {
+ int multiplier, fd, to_write;
+
+ /*
+ * When writing the multiplier, if the length of the write is
+ * not sizeof(int), the multiplier is not changed
+ */
+ if (mult) {
+ multiplier = strtoul(mult, 0, 10);
+ to_write = sizeof(int);
+ } else {
+ multiplier = 0;
+ to_write = 1; /* sth different from sizeof(int) */
+ }
+ /* try to become root, just in case */
+ setuid(0);
+ fd = open(defaultpro,O_WRONLY);
+ if (fd < 0) {
+ perror(defaultpro);
+ exit(1);
+ }
+ if (write(fd, &multiplier, to_write) != to_write) {
+ fprintf(stderr, "readprofile: error writing %s: %s\n",
+ defaultpro, strerror(errno));
+ exit(1);
+ }
+ close(fd);
+ exit(0);
+ }
+
+ /*
+ * Use an fd for the profiling buffer, to skip stdio overhead
+ */
+ if ( ((proFd=open(proFile,O_RDONLY)) < 0)
+ || ((int)(len=lseek(proFd,0,SEEK_END)) < 0)
+ || (lseek(proFd,0,SEEK_SET)<0) ) {
+ fprintf(stderr,"%s: %s: %s\n",prgname,proFile,strerror(errno));
+ exit(1);
+ }
+
+ if ( !(buf=malloc(len)) ) {
+ fprintf(stderr,"%s: malloc(): %s\n",prgname, strerror(errno));
+ exit(1);
+ }
+
+ if (read(proFd,buf,len) != len) {
+ fprintf(stderr,"%s: %s: %s\n",prgname,proFile,strerror(errno));
+ exit(1);
+ }
+ close(proFd);
+
+ step=buf[0];
+ if (optInfo) {
+ printf(_("Sampling_step: %i\n"),step);
+ exit(0);
+ }
+
+ total=0;
+
+ if (!(map=myopen(mapFile,"r",&popenMap))) {
+ fprintf(stderr,"%s: ",prgname);perror(mapFile);
+ exit(1);
+ }
+
+ while(fgets(mapline,S_LEN,map)) {
+ if (sscanf(mapline,"%lx %s %s",&fn_add,mode,fn_name)!=3) {
+ fprintf(stderr,_("%s: %s(%i): wrong map line\n"),
+ prgname,mapFile, maplineno);
+ exit(1);
+ }
+ if (!strcmp(fn_name,"_stext")) /* only elf works like this */ {
+ add0=fn_add;
+ break;
+ }
+ }
+
+ if (!add0) {
+ fprintf(stderr,_("%s: can't find \"_stext\" in %s\n"),
+ prgname, mapFile);
+ exit(1);
+ }
+
+ /*
+ * Main loop.
+ */
+ while(fgets(mapline,S_LEN,map)) {
+ unsigned int this=0;
+
+ if (sscanf(mapline,"%lx %s %s",&next_add,mode,next_name)!=3) {
+ fprintf(stderr,_("%s: %s(%i): wrong map line\n"),
+ prgname,mapFile, maplineno);
+ exit(1);
+ }
+
+ /* ignore any LEADING (before a '[tT]' symbol is found)
+ Absolute symbols */
+ if (*mode == 'A' && total == 0) continue;
+ if (*mode!='T' && *mode!='t') break;/* only text is profiled */
+
+ while (indx < (next_add-add0)/step)
+ this += buf[indx++];
+ total += this;
+
+ fn_len = next_add-fn_add;
+ if (fn_len && (this || optAll)) {
+ if (optVerbose)
+ printf("%08lx %-40s %6i %8.4f\n", fn_add,
+ fn_name,this,this/(double)fn_len);
+ else
+ printf("%6i %-40s %8.4f\n",
+ this,fn_name,this/(double)fn_len);
+ }
+ fn_add=next_add; strcpy(fn_name,next_name);
+ }
+ /* trailer */
+ if (optVerbose)
+ printf("%08x %-40s %6i %8.4f\n",
+ 0,"total",total,total/(double)(fn_add-add0));
+ else
+ printf("%6i %-40s %8.4f\n",
+ total,_("total"),total/(double)(fn_add-add0));
- popenMap ? pclose(map) : fclose(map);
- exit(0);
+ popenMap ? pclose(map) : fclose(map);
+ exit(0);
}
-
-
-