Use err(3). Add usage() and prototypes.

This commit is contained in:
Philippe Charnier 1997-09-23 06:38:54 +00:00
parent ecdf56e7d9
commit fa6990870e
2 changed files with 75 additions and 108 deletions

View File

@ -46,7 +46,7 @@
.Nm Kgmon .Nm Kgmon
is a tool used when profiling the operating system. is a tool used when profiling the operating system.
When no arguments are supplied, When no arguments are supplied,
.Nm kgmon .Nm
indicates the state of operating system profiling as running, indicates the state of operating system profiling as running,
off, or not configured. off, or not configured.
(see (see
@ -54,7 +54,7 @@ off, or not configured.
If the If the
.Fl p .Fl p
flag is specified, flag is specified,
.Nm kgmon .Nm
extracts profile data from the operating system and produces a extracts profile data from the operating system and produces a
.Pa gmon.out .Pa gmon.out
file suitable for later analysis by file suitable for later analysis by

View File

@ -32,13 +32,17 @@
*/ */
#ifndef lint #ifndef lint
static char copyright[] = static const char copyright[] =
"@(#) Copyright (c) 1983, 1992, 1993\n\ "@(#) Copyright (c) 1983, 1992, 1993\n\
The Regents of the University of California. All rights reserved.\n"; The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#ifndef lint #ifndef lint
#if 0
static char sccsid[] = "@(#)kgmon.c 8.1 (Berkeley) 6/6/93"; static char sccsid[] = "@(#)kgmon.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$Id$";
#endif /* not lint */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
@ -46,22 +50,24 @@ static char sccsid[] = "@(#)kgmon.c 8.1 (Berkeley) 6/6/93";
#include <sys/time.h> #include <sys/time.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/gmon.h> #include <sys/gmon.h>
#include <ctype.h>
#include <err.h>
#include <errno.h> #include <errno.h>
#include <kvm.h> #include <kvm.h>
#include <limits.h> #include <limits.h>
#include <nlist.h>
#include <paths.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <nlist.h> #include <unistd.h>
#include <ctype.h>
#include <paths.h>
struct nlist nl[] = { struct nlist nl[] = {
#define N_GMONPARAM 0 #define N_GMONPARAM 0
{ "__gmonparam" }, { "__gmonparam" },
#define N_PROFHZ 1 #define N_PROFHZ 1
{ "_profhz" }, { "_profhz" },
0, { NULL },
}; };
struct kvmvars { struct kvmvars {
@ -71,15 +77,18 @@ struct kvmvars {
int Bflag, bflag, hflag, kflag, rflag, pflag; int Bflag, bflag, hflag, kflag, rflag, pflag;
int debug = 0; int debug = 0;
int getprof __P((struct kvmvars *));
int getprofhz __P((struct kvmvars *));
void kern_readonly __P((int));
int openfiles __P((char *, char *, struct kvmvars *));
void setprof __P((struct kvmvars *kvp, int state)); void setprof __P((struct kvmvars *kvp, int state));
void dumpstate __P((struct kvmvars *kvp)); void dumpstate __P((struct kvmvars *kvp));
void reset __P((struct kvmvars *kvp)); void reset __P((struct kvmvars *kvp));
static void usage __P((void));
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
extern char *optarg;
extern int optind;
int ch, mode, disp, accessmode; int ch, mode, disp, accessmode;
struct kvmvars kvmvars; struct kvmvars kvmvars;
char *system, *kmemf; char *system, *kmemf;
@ -120,9 +129,7 @@ main(int argc, char **argv)
break; break;
default: default:
(void)fprintf(stderr, usage();
"usage: kgmon [-Bbhrp] [-M core] [-N system]\n");
exit(1);
} }
} }
argc -= optind; argc -= optind;
@ -166,9 +173,17 @@ main(int argc, char **argv)
return (0); return (0);
} }
static void
usage()
{
fprintf(stderr, "usage: kgmon [-Bbhrp] [-M core] [-N system]\n");
exit(1);
}
/* /*
* Check that profiling is enabled and open any ncessary files. * Check that profiling is enabled and open any ncessary files.
*/ */
int
openfiles(system, kmemf, kvp) openfiles(system, kmemf, kvp)
char *system; char *system;
char *kmemf; char *kmemf;
@ -182,11 +197,8 @@ openfiles(system, kmemf, kvp)
mib[1] = KERN_PROF; mib[1] = KERN_PROF;
mib[2] = GPROF_STATE; mib[2] = GPROF_STATE;
size = sizeof state; size = sizeof state;
if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) { if (sysctl(mib, 3, &state, &size, NULL, 0) < 0)
(void)fprintf(stderr, errx(20, "profiling not defined in kernel");
"kgmon: profiling not defined in kernel.\n");
exit(20);
}
if (!(Bflag || bflag || hflag || rflag || if (!(Bflag || bflag || hflag || rflag ||
(pflag && (pflag &&
(state == GMON_PROF_HIRES || state == GMON_PROF_ON)))) (state == GMON_PROF_HIRES || state == GMON_PROF_ON))))
@ -207,28 +219,21 @@ openfiles(system, kmemf, kvp)
kvp->kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY, kvp->kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY,
errbuf); errbuf);
} }
if (kvp->kd == NULL) { if (kvp->kd == NULL)
(void)fprintf(stderr, "kgmon: kvm_openfiles: %s\n", errx(2, "kvm_openfiles: %s", errbuf);
errbuf);
exit(2);
}
kern_readonly(GMON_PROF_ON); kern_readonly(GMON_PROF_ON);
} }
if (kvm_nlist(kvp->kd, nl) < 0) { if (kvm_nlist(kvp->kd, nl) < 0)
(void)fprintf(stderr, "kgmon: %s: no namelist\n", system); errx(3, "%s: no namelist", system);
exit(3); if (!nl[N_GMONPARAM].n_value)
} errx(20, "profiling not defined in kernel");
if (!nl[N_GMONPARAM].n_value) {
(void)fprintf(stderr,
"kgmon: profiling not defined in kernel.\n");
exit(20);
}
return (openmode); return (openmode);
} }
/* /*
* Suppress options that require a writable kernel. * Suppress options that require a writable kernel.
*/ */
void
kern_readonly(mode) kern_readonly(mode)
int mode; int mode;
{ {
@ -250,6 +255,7 @@ kern_readonly(mode)
/* /*
* Get the state of kernel profiling. * Get the state of kernel profiling.
*/ */
int
getprof(kvp) getprof(kvp)
struct kvmvars *kvp; struct kvmvars *kvp;
{ {
@ -266,11 +272,9 @@ getprof(kvp)
if (sysctl(mib, 3, &kvp->gpm, &size, NULL, 0) < 0) if (sysctl(mib, 3, &kvp->gpm, &size, NULL, 0) < 0)
size = 0; size = 0;
} }
if (size != sizeof kvp->gpm) { if (size != sizeof kvp->gpm)
(void)fprintf(stderr, "kgmon: cannot get gmonparam: %s\n", errx(4, "cannot get gmonparam: %s",
kflag ? kvm_geterr(kvp->kd) : strerror(errno)); kflag ? kvm_geterr(kvp->kd) : strerror(errno));
exit (4);
}
return (kvp->gpm.state); return (kvp->gpm.state);
} }
@ -304,7 +308,7 @@ setprof(kvp, state)
== sz) == sz)
return; return;
bad: bad:
(void)fprintf(stderr, "kgmon: warning: cannot turn profiling %s\n", warnx("warning: cannot turn profiling %s",
state == GMON_PROF_OFF ? "off" : "on"); state == GMON_PROF_OFF ? "off" : "on");
} }
@ -318,7 +322,7 @@ dumpstate(kvp)
register FILE *fp; register FILE *fp;
struct rawarc rawarc; struct rawarc rawarc;
struct tostruct *tos; struct tostruct *tos;
u_long frompc, addr; u_long frompc;
u_short *froms, *tickbuf; u_short *froms, *tickbuf;
int mib[3], i; int mib[3], i;
struct gmonhdr h; struct gmonhdr h;
@ -327,7 +331,7 @@ dumpstate(kvp)
setprof(kvp, GMON_PROF_OFF); setprof(kvp, GMON_PROF_OFF);
fp = fopen("gmon.out", "w"); fp = fopen("gmon.out", "w");
if (fp == 0) { if (fp == 0) {
perror("gmon.out"); warn("gmon.out");
return; return;
} }
@ -349,10 +353,8 @@ dumpstate(kvp)
*/ */
mib[0] = CTL_KERN; mib[0] = CTL_KERN;
mib[1] = KERN_PROF; mib[1] = KERN_PROF;
if ((tickbuf = (u_short *)malloc(kvp->gpm.kcountsize)) == NULL) { if ((tickbuf = (u_short *)malloc(kvp->gpm.kcountsize)) == NULL)
fprintf(stderr, "kgmon: cannot allocate kcount space\n"); errx(5, "cannot allocate kcount space");
exit (5);
}
if (kflag) { if (kflag) {
i = kvm_read(kvp->kd, (u_long)kvp->gpm.kcount, (void *)tickbuf, i = kvm_read(kvp->kd, (u_long)kvp->gpm.kcount, (void *)tickbuf,
kvp->gpm.kcountsize); kvp->gpm.kcountsize);
@ -362,25 +364,19 @@ dumpstate(kvp)
if (sysctl(mib, 3, tickbuf, &i, NULL, 0) < 0) if (sysctl(mib, 3, tickbuf, &i, NULL, 0) < 0)
i = 0; i = 0;
} }
if (i != kvp->gpm.kcountsize) { if (i != kvp->gpm.kcountsize)
(void)fprintf(stderr, "kgmon: read ticks: read %u, got %d: %s", errx(6, "read ticks: read %u, got %d: %s",
kvp->gpm.kcountsize, i, kvp->gpm.kcountsize, i,
kflag ? kvm_geterr(kvp->kd) : strerror(errno)); kflag ? kvm_geterr(kvp->kd) : strerror(errno));
exit(6); if ((fwrite(tickbuf, kvp->gpm.kcountsize, 1, fp)) != 1)
} err(7, "writing tocks to gmon.out");
if ((fwrite(tickbuf, kvp->gpm.kcountsize, 1, fp)) != 1) {
perror("kgmon: writing tocks to gmon.out");
exit(7);
}
free(tickbuf); free(tickbuf);
/* /*
* Write out the arc info. * Write out the arc info.
*/ */
if ((froms = (u_short *)malloc(kvp->gpm.fromssize)) == NULL) { if ((froms = (u_short *)malloc(kvp->gpm.fromssize)) == NULL)
fprintf(stderr, "kgmon: cannot allocate froms space\n"); errx(8, "cannot allocate froms space");
exit (8);
}
if (kflag) { if (kflag) {
i = kvm_read(kvp->kd, (u_long)kvp->gpm.froms, (void *)froms, i = kvm_read(kvp->kd, (u_long)kvp->gpm.froms, (void *)froms,
kvp->gpm.fromssize); kvp->gpm.fromssize);
@ -390,16 +386,12 @@ dumpstate(kvp)
if (sysctl(mib, 3, froms, &i, NULL, 0) < 0) if (sysctl(mib, 3, froms, &i, NULL, 0) < 0)
i = 0; i = 0;
} }
if (i != kvp->gpm.fromssize) { if (i != kvp->gpm.fromssize)
(void)fprintf(stderr, "kgmon: read froms: read %u, got %d: %s", errx(9, "read froms: read %u, got %d: %s",
kvp->gpm.fromssize, i, kvp->gpm.fromssize, i,
kflag ? kvm_geterr(kvp->kd) : strerror(errno)); kflag ? kvm_geterr(kvp->kd) : strerror(errno));
exit(9); if ((tos = (struct tostruct *)malloc(kvp->gpm.tossize)) == NULL)
} errx(10, "cannot allocate tos space");
if ((tos = (struct tostruct *)malloc(kvp->gpm.tossize)) == NULL) {
fprintf(stderr, "kgmon: cannot allocate tos space\n");
exit(10);
}
if (kflag) { if (kflag) {
i = kvm_read(kvp->kd, (u_long)kvp->gpm.tos, (void *)tos, i = kvm_read(kvp->kd, (u_long)kvp->gpm.tos, (void *)tos,
kvp->gpm.tossize); kvp->gpm.tossize);
@ -409,14 +401,12 @@ dumpstate(kvp)
if (sysctl(mib, 3, tos, &i, NULL, 0) < 0) if (sysctl(mib, 3, tos, &i, NULL, 0) < 0)
i = 0; i = 0;
} }
if (i != kvp->gpm.tossize) { if (i != kvp->gpm.tossize)
(void)fprintf(stderr, "kgmon: read tos: read %u, got %d: %s", errx(11, "read tos: read %u, got %d: %s",
kvp->gpm.tossize, i, kvp->gpm.tossize, i,
kflag ? kvm_geterr(kvp->kd) : strerror(errno)); kflag ? kvm_geterr(kvp->kd) : strerror(errno));
exit(11);
}
if (debug) if (debug)
(void)fprintf(stderr, "kgmon: lowpc 0x%x, textsize 0x%x\n", warnx("lowpc 0x%x, textsize 0x%x",
kvp->gpm.lowpc, kvp->gpm.textsize); kvp->gpm.lowpc, kvp->gpm.textsize);
endfrom = kvp->gpm.fromssize / sizeof(*froms); endfrom = kvp->gpm.fromssize / sizeof(*froms);
for (fromindex = 0; fromindex < endfrom; ++fromindex) { for (fromindex = 0; fromindex < endfrom; ++fromindex) {
@ -427,9 +417,8 @@ dumpstate(kvp)
for (toindex = froms[fromindex]; toindex != 0; for (toindex = froms[fromindex]; toindex != 0;
toindex = tos[toindex].link) { toindex = tos[toindex].link) {
if (debug) if (debug)
(void)fprintf(stderr, warnx("[mcleanup] frompc 0x%x selfpc 0x%x count %d",
"%s: [mcleanup] frompc 0x%x selfpc 0x%x count %d\n", frompc, tos[toindex].selfpc,
"kgmon", frompc, tos[toindex].selfpc,
tos[toindex].count); tos[toindex].count);
rawarc.raw_frompc = frompc; rawarc.raw_frompc = frompc;
rawarc.raw_selfpc = (u_long)tos[toindex].selfpc; rawarc.raw_selfpc = (u_long)tos[toindex].selfpc;
@ -454,8 +443,7 @@ getprofhz(kvp)
profrate = 1; profrate = 1;
if (kvm_read(kvp->kd, nl[N_PROFHZ].n_value, &profrate, if (kvm_read(kvp->kd, nl[N_PROFHZ].n_value, &profrate,
sizeof profrate) != sizeof profrate) sizeof profrate) != sizeof profrate)
(void)fprintf(stderr, "kgmon: get clockrate: %s\n", warnx("get clockrate: %s", kvm_geterr(kvp->kd));
kvm_geterr(kvp->kd));
return (profrate); return (profrate);
} }
mib[0] = CTL_KERN; mib[0] = CTL_KERN;
@ -463,8 +451,7 @@ getprofhz(kvp)
clockrate.profhz = 1; clockrate.profhz = 1;
size = sizeof clockrate; size = sizeof clockrate;
if (sysctl(mib, 2, &clockrate, &size, NULL, 0) < 0) if (sysctl(mib, 2, &clockrate, &size, NULL, 0) < 0)
(void)fprintf(stderr, "kgmon: get clockrate: %s\n", warn("get clockrate");
strerror(errno));
return (clockrate.profhz); return (clockrate.profhz);
} }
@ -486,53 +473,33 @@ reset(kvp)
biggest = kvp->gpm.fromssize; biggest = kvp->gpm.fromssize;
if (kvp->gpm.tossize > biggest) if (kvp->gpm.tossize > biggest)
biggest = kvp->gpm.tossize; biggest = kvp->gpm.tossize;
if ((zbuf = (char *)malloc(biggest)) == NULL) { if ((zbuf = (char *)malloc(biggest)) == NULL)
fprintf(stderr, "kgmon: cannot allocate zbuf space\n"); errx(12, "cannot allocate zbuf space");
exit(12);
}
bzero(zbuf, biggest); bzero(zbuf, biggest);
if (kflag) { if (kflag) {
if (kvm_write(kvp->kd, (u_long)kvp->gpm.kcount, zbuf, if (kvm_write(kvp->kd, (u_long)kvp->gpm.kcount, zbuf,
kvp->gpm.kcountsize) != kvp->gpm.kcountsize) { kvp->gpm.kcountsize) != kvp->gpm.kcountsize)
(void)fprintf(stderr, "kgmon: tickbuf zero: %s\n", errx(13, "tickbuf zero: %s", kvm_geterr(kvp->kd));
kvm_geterr(kvp->kd));
exit(13);
}
if (kvm_write(kvp->kd, (u_long)kvp->gpm.froms, zbuf, if (kvm_write(kvp->kd, (u_long)kvp->gpm.froms, zbuf,
kvp->gpm.fromssize) != kvp->gpm.fromssize) { kvp->gpm.fromssize) != kvp->gpm.fromssize)
(void)fprintf(stderr, "kgmon: froms zero: %s\n", errx(14, "froms zero: %s", kvm_geterr(kvp->kd));
kvm_geterr(kvp->kd));
exit(14);
}
if (kvm_write(kvp->kd, (u_long)kvp->gpm.tos, zbuf, if (kvm_write(kvp->kd, (u_long)kvp->gpm.tos, zbuf,
kvp->gpm.tossize) != kvp->gpm.tossize) { kvp->gpm.tossize) != kvp->gpm.tossize)
(void)fprintf(stderr, "kgmon: tos zero: %s\n", errx(15, "tos zero: %s", kvm_geterr(kvp->kd));
kvm_geterr(kvp->kd));
exit(15);
}
return; return;
} }
(void)seteuid(0); (void)seteuid(0);
mib[0] = CTL_KERN; mib[0] = CTL_KERN;
mib[1] = KERN_PROF; mib[1] = KERN_PROF;
mib[2] = GPROF_COUNT; mib[2] = GPROF_COUNT;
if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.kcountsize) < 0) { if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.kcountsize) < 0)
(void)fprintf(stderr, "kgmon: tickbuf zero: %s\n", err(13, "tickbuf zero");
strerror(errno));
exit(13);
}
mib[2] = GPROF_FROMS; mib[2] = GPROF_FROMS;
if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.fromssize) < 0) { if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.fromssize) < 0)
(void)fprintf(stderr, "kgmon: froms zero: %s\n", err(14, "froms zero");
strerror(errno));
exit(14);
}
mib[2] = GPROF_TOS; mib[2] = GPROF_TOS;
if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.tossize) < 0) { if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.tossize) < 0)
(void)fprintf(stderr, "kgmon: tos zero: %s\n", err(15, "tos zero");
strerror(errno));
exit(15);
}
(void)seteuid(getuid()); (void)seteuid(getuid());
free(zbuf); free(zbuf);
} }