]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - sys-utils/readprofile.c
2 * readprofile.c - used to read /proc/profile
4 * Copyright (C) 1994,1996 Alessandro Rubini (rubini@ipvvis.unipv.it)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
23 * - added Native Language Support
24 * 1999-09-01 Stephane Eranian <eranian@cello.hpl.hp.com>
26 * 3Feb2001 Andrew Morton <andrewm@uow.edu.au>
27 * - -M option to write profile multiplier.
35 #include <sys/types.h>
40 #define RELEASE "2.0, May 1996"
46 /* These are the defaults */
47 static char defaultmap
[]="/usr/src/linux/System.map";
48 static char defaultpro
[]="/proc/profile";
49 static char optstring
[]="M:m:p:itvarV";
54 _("%s: Usage: \"%s [options]\n"
55 "\t -m <mapfile> (default = \"%s\")\n"
56 "\t -p <pro-file> (default = \"%s\")\n"
57 "\t -M <mult> set the profiling multiplier to <mult>\n"
58 "\t -i print only info about the sampling step\n"
59 "\t -v print verbose data\n"
60 "\t -a print all symbols, even if count is 0\n"
61 "\t -r reset all the counters (root only)\n"
62 "\t -V print version and exit\n")
63 ,prgname
,prgname
,defaultmap
,defaultpro
);
68 myopen(char *name
, char *mode
, int *flag
) {
69 static char cmdline
[S_LEN
];
71 if (!strcmp(name
+strlen(name
)-3,".gz")) {
73 sprintf(cmdline
,"zcat %s", name
);
74 return popen(cmdline
,mode
);
77 return fopen(name
,mode
);
81 main (int argc
, char **argv
) {
84 char *mapFile
, *proFile
, *mult
=0;
85 unsigned long len
=0, add0
=0, indx
=0;
87 unsigned int *buf
, total
, fn_len
;
88 unsigned long fn_add
, next_add
; /* current and next address */
89 char fn_name
[S_LEN
], next_name
[S_LEN
]; /* current and next name */
92 int optAll
=0, optInfo
=0, optReset
=0, optVerbose
=0;
95 int popenMap
; /* flag to tell if popen() has been used */
97 #define next (current^1)
99 setlocale(LC_ALL
, "");
100 bindtextdomain(PACKAGE
, LOCALEDIR
);
107 while ((c
=getopt(argc
,argv
,optstring
))!=-1) {
109 case 'm': mapFile
=optarg
; break;
110 case 'p': proFile
=optarg
; break;
111 case 'a': optAll
++; break;
112 case 'i': optInfo
++; break;
113 case 'M': mult
=optarg
; break;
114 case 'r': optReset
++; break;
115 case 'v': optVerbose
++; break;
116 case 'V': printf(_("%s Version %s\n"),prgname
,RELEASE
);
122 if (optReset
|| mult
) {
123 int multiplier
, fd
, to_write
;
126 * When writing the multiplier, if the length of the write is
127 * not sizeof(int), the multiplier is not changed
130 multiplier
= strtoul(mult
, 0, 10);
131 to_write
= sizeof(int);
134 to_write
= 1; /* sth different from sizeof(int) */
136 /* try to become root, just in case */
138 fd
= open(defaultpro
,O_WRONLY
);
143 if (write(fd
, &multiplier
, to_write
) != to_write
) {
144 fprintf(stderr
, "readprofile: error writing %s: %s\n",
145 defaultpro
, strerror(errno
));
153 * Use an fd for the profiling buffer, to skip stdio overhead
155 if ( ((proFd
=open(proFile
,O_RDONLY
)) < 0)
156 || ((int)(len
=lseek(proFd
,0,SEEK_END
)) < 0)
157 || (lseek(proFd
,0,SEEK_SET
)<0) ) {
158 fprintf(stderr
,"%s: %s: %s\n",prgname
,proFile
,strerror(errno
));
162 if ( !(buf
=malloc(len
)) ) {
163 fprintf(stderr
,"%s: malloc(): %s\n",prgname
, strerror(errno
));
167 if (read(proFd
,buf
,len
) != len
) {
168 fprintf(stderr
,"%s: %s: %s\n",prgname
,proFile
,strerror(errno
));
175 printf(_("Sampling_step: %i\n"),step
);
181 if (!(map
=myopen(mapFile
,"r",&popenMap
))) {
182 fprintf(stderr
,"%s: ",prgname
);perror(mapFile
);
186 while(fgets(mapline
,S_LEN
,map
)) {
187 if (sscanf(mapline
,"%lx %s %s",&fn_add
,mode
,fn_name
)!=3) {
188 fprintf(stderr
,_("%s: %s(%i): wrong map line\n"),
189 prgname
,mapFile
, maplineno
);
192 if (!strcmp(fn_name
,"_stext")) /* only elf works like this */ {
199 fprintf(stderr
,_("%s: can't find \"_stext\" in %s\n"),
207 while(fgets(mapline
,S_LEN
,map
)) {
210 if (sscanf(mapline
,"%lx %s %s",&next_add
,mode
,next_name
)!=3) {
211 fprintf(stderr
,_("%s: %s(%i): wrong map line\n"),
212 prgname
,mapFile
, maplineno
);
216 /* ignore any LEADING (before a '[tT]' symbol is found)
218 if (*mode
== 'A' && total
== 0) continue;
219 if (*mode
!='T' && *mode
!='t') break;/* only text is profiled */
221 while (indx
< (next_add
-add0
)/step
)
225 fn_len
= next_add
-fn_add
;
226 if (fn_len
&& (this || optAll
)) {
228 printf("%08lx %-40s %6i %8.4f\n", fn_add
,
229 fn_name
,this,this/(double)fn_len
);
231 printf("%6i %-40s %8.4f\n",
232 this,fn_name
,this/(double)fn_len
);
234 fn_add
=next_add
; strcpy(fn_name
,next_name
);
238 printf("%08x %-40s %6i %8.4f\n",
239 0,"total",total
,total
/(double)(fn_add
-add0
));
241 printf("%6i %-40s %8.4f\n",
242 total
,_("total"),total
/(double)(fn_add
-add0
));
244 popenMap
? pclose(map
) : fclose(map
);