kgmon.c revision 24428
11553Srgrimes/* 21553Srgrimes * Copyright (c) 1983, 1992, 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 3. All advertising materials mentioning features or use of this software 141553Srgrimes * must display the following acknowledgement: 151553Srgrimes * This product includes software developed by the University of 161553Srgrimes * California, Berkeley and its contributors. 171553Srgrimes * 4. Neither the name of the University nor the names of its contributors 181553Srgrimes * may be used to endorse or promote products derived from this software 191553Srgrimes * without specific prior written permission. 201553Srgrimes * 211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311553Srgrimes * SUCH DAMAGE. 321553Srgrimes */ 331553Srgrimes 341553Srgrimes#ifndef lint 351553Srgrimesstatic char copyright[] = 361553Srgrimes"@(#) Copyright (c) 1983, 1992, 1993\n\ 371553Srgrimes The Regents of the University of California. All rights reserved.\n"; 381553Srgrimes#endif /* not lint */ 391553Srgrimes 401553Srgrimes#ifndef lint 411553Srgrimesstatic char sccsid[] = "@(#)kgmon.c 8.1 (Berkeley) 6/6/93"; 421553Srgrimes#endif /* not lint */ 431553Srgrimes 441553Srgrimes#include <sys/param.h> 451553Srgrimes#include <sys/file.h> 4611937Sphk#include <sys/time.h> 471553Srgrimes#include <sys/sysctl.h> 481553Srgrimes#include <sys/gmon.h> 491553Srgrimes#include <errno.h> 501553Srgrimes#include <kvm.h> 511553Srgrimes#include <limits.h> 521553Srgrimes#include <stdio.h> 531553Srgrimes#include <stdlib.h> 541553Srgrimes#include <string.h> 551553Srgrimes#include <nlist.h> 561553Srgrimes#include <ctype.h> 571553Srgrimes#include <paths.h> 581553Srgrimes 591553Srgrimesstruct nlist nl[] = { 601553Srgrimes#define N_GMONPARAM 0 611553Srgrimes { "__gmonparam" }, 621553Srgrimes#define N_PROFHZ 1 631553Srgrimes { "_profhz" }, 641553Srgrimes 0, 651553Srgrimes}; 661553Srgrimes 671553Srgrimesstruct kvmvars { 681553Srgrimes kvm_t *kd; 691553Srgrimes struct gmonparam gpm; 701553Srgrimes}; 711553Srgrimes 7213107Sbdeint Bflag, bflag, hflag, kflag, rflag, pflag; 731553Srgrimesint debug = 0; 741553Srgrimesvoid setprof __P((struct kvmvars *kvp, int state)); 751553Srgrimesvoid dumpstate __P((struct kvmvars *kvp)); 761553Srgrimesvoid reset __P((struct kvmvars *kvp)); 771553Srgrimes 781553Srgrimesint 791553Srgrimesmain(int argc, char **argv) 801553Srgrimes{ 811553Srgrimes extern char *optarg; 821553Srgrimes extern int optind; 831553Srgrimes int ch, mode, disp, accessmode; 841553Srgrimes struct kvmvars kvmvars; 851553Srgrimes char *system, *kmemf; 861553Srgrimes 871553Srgrimes seteuid(getuid()); 881553Srgrimes kmemf = NULL; 891553Srgrimes system = NULL; 9024428Simp while ((ch = getopt(argc, argv, "M:N:Bbhpr")) != -1) { 911553Srgrimes switch((char)ch) { 921553Srgrimes 931553Srgrimes case 'M': 941553Srgrimes kmemf = optarg; 951553Srgrimes kflag = 1; 961553Srgrimes break; 971553Srgrimes 981553Srgrimes case 'N': 991553Srgrimes system = optarg; 1001553Srgrimes break; 1011553Srgrimes 10213107Sbde case 'B': 10313107Sbde Bflag = 1; 10413107Sbde break; 10513107Sbde 1061553Srgrimes case 'b': 1071553Srgrimes bflag = 1; 1081553Srgrimes break; 1091553Srgrimes 1101553Srgrimes case 'h': 1111553Srgrimes hflag = 1; 1121553Srgrimes break; 1131553Srgrimes 1141553Srgrimes case 'p': 1151553Srgrimes pflag = 1; 1161553Srgrimes break; 1171553Srgrimes 1181553Srgrimes case 'r': 1191553Srgrimes rflag = 1; 1201553Srgrimes break; 1211553Srgrimes 1221553Srgrimes default: 1231553Srgrimes (void)fprintf(stderr, 12413107Sbde "usage: kgmon [-Bbhrp] [-M core] [-N system]\n"); 1251553Srgrimes exit(1); 1261553Srgrimes } 1271553Srgrimes } 1281553Srgrimes argc -= optind; 1291553Srgrimes argv += optind; 1301553Srgrimes 1311553Srgrimes#define BACKWARD_COMPATIBILITY 1321553Srgrimes#ifdef BACKWARD_COMPATIBILITY 1331553Srgrimes if (*argv) { 1341553Srgrimes system = *argv; 1351553Srgrimes if (*++argv) { 1361553Srgrimes kmemf = *argv; 1371553Srgrimes ++kflag; 1381553Srgrimes } 1391553Srgrimes } 1401553Srgrimes#endif 1411553Srgrimes if (system == NULL) 1423041Swollman system = (char *)getbootfile(); 1431553Srgrimes accessmode = openfiles(system, kmemf, &kvmvars); 1441553Srgrimes mode = getprof(&kvmvars); 1451553Srgrimes if (hflag) 1461553Srgrimes disp = GMON_PROF_OFF; 14713107Sbde else if (Bflag) 14813107Sbde disp = GMON_PROF_HIRES; 1491553Srgrimes else if (bflag) 1501553Srgrimes disp = GMON_PROF_ON; 1511553Srgrimes else 1521553Srgrimes disp = mode; 1531553Srgrimes if (pflag) 1541553Srgrimes dumpstate(&kvmvars); 1551553Srgrimes if (rflag) 1561553Srgrimes reset(&kvmvars); 1571553Srgrimes if (accessmode == O_RDWR) 1581553Srgrimes setprof(&kvmvars, disp); 1591553Srgrimes (void)fprintf(stdout, "kgmon: kernel profiling is %s.\n", 16013107Sbde disp == GMON_PROF_OFF ? "off" : 16113107Sbde disp == GMON_PROF_HIRES ? "running (high resolution)" : 16213107Sbde disp == GMON_PROF_ON ? "running" : 16313107Sbde disp == GMON_PROF_BUSY ? "busy" : 16413107Sbde disp == GMON_PROF_ERROR ? "off (error)" : 16513107Sbde "in an unknown state"); 1661553Srgrimes return (0); 1671553Srgrimes} 1681553Srgrimes 1691553Srgrimes/* 1701553Srgrimes * Check that profiling is enabled and open any ncessary files. 1711553Srgrimes */ 1721553Srgrimesopenfiles(system, kmemf, kvp) 1731553Srgrimes char *system; 1741553Srgrimes char *kmemf; 1751553Srgrimes struct kvmvars *kvp; 1761553Srgrimes{ 1771553Srgrimes int mib[3], state, size, openmode; 1781553Srgrimes char errbuf[_POSIX2_LINE_MAX]; 1791553Srgrimes 1801553Srgrimes if (!kflag) { 1811553Srgrimes mib[0] = CTL_KERN; 1821553Srgrimes mib[1] = KERN_PROF; 1831553Srgrimes mib[2] = GPROF_STATE; 1841553Srgrimes size = sizeof state; 1851553Srgrimes if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) { 1861553Srgrimes (void)fprintf(stderr, 1871553Srgrimes "kgmon: profiling not defined in kernel.\n"); 1881553Srgrimes exit(20); 1891553Srgrimes } 19013107Sbde if (!(Bflag || bflag || hflag || rflag || 19113107Sbde (pflag && 19213107Sbde (state == GMON_PROF_HIRES || state == GMON_PROF_ON)))) 1931553Srgrimes return (O_RDONLY); 1941553Srgrimes (void)seteuid(0); 1951553Srgrimes if (sysctl(mib, 3, NULL, NULL, &state, size) >= 0) 1961553Srgrimes return (O_RDWR); 1971553Srgrimes (void)seteuid(getuid()); 1981553Srgrimes kern_readonly(state); 1991553Srgrimes return (O_RDONLY); 2001553Srgrimes } 20113107Sbde openmode = (Bflag || bflag || hflag || pflag || rflag) 20213107Sbde ? O_RDWR : O_RDONLY; 2031553Srgrimes kvp->kd = kvm_openfiles(system, kmemf, NULL, openmode, errbuf); 2041553Srgrimes if (kvp->kd == NULL) { 2051553Srgrimes if (openmode == O_RDWR) { 2061553Srgrimes openmode = O_RDONLY; 2071553Srgrimes kvp->kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY, 2081553Srgrimes errbuf); 2091553Srgrimes } 2101553Srgrimes if (kvp->kd == NULL) { 2111553Srgrimes (void)fprintf(stderr, "kgmon: kvm_openfiles: %s\n", 2121553Srgrimes errbuf); 2131553Srgrimes exit(2); 2141553Srgrimes } 2151553Srgrimes kern_readonly(GMON_PROF_ON); 2161553Srgrimes } 2171553Srgrimes if (kvm_nlist(kvp->kd, nl) < 0) { 2181553Srgrimes (void)fprintf(stderr, "kgmon: %s: no namelist\n", system); 2191553Srgrimes exit(3); 2201553Srgrimes } 2211553Srgrimes if (!nl[N_GMONPARAM].n_value) { 2221553Srgrimes (void)fprintf(stderr, 2231553Srgrimes "kgmon: profiling not defined in kernel.\n"); 2241553Srgrimes exit(20); 2251553Srgrimes } 2261553Srgrimes return (openmode); 2271553Srgrimes} 2281553Srgrimes 2291553Srgrimes/* 2301553Srgrimes * Suppress options that require a writable kernel. 2311553Srgrimes */ 2321553Srgrimeskern_readonly(mode) 2331553Srgrimes int mode; 2341553Srgrimes{ 2351553Srgrimes 2361553Srgrimes (void)fprintf(stderr, "kgmon: kernel read-only: "); 23713107Sbde if (pflag && (mode == GMON_PROF_HIRES || mode == GMON_PROF_ON)) 2381553Srgrimes (void)fprintf(stderr, "data may be inconsistent\n"); 2391553Srgrimes if (rflag) 2401553Srgrimes (void)fprintf(stderr, "-r supressed\n"); 24113107Sbde if (Bflag) 24213107Sbde (void)fprintf(stderr, "-B supressed\n"); 2431553Srgrimes if (bflag) 2441553Srgrimes (void)fprintf(stderr, "-b supressed\n"); 2451553Srgrimes if (hflag) 2461553Srgrimes (void)fprintf(stderr, "-h supressed\n"); 24713107Sbde rflag = Bflag = bflag = hflag = 0; 2481553Srgrimes} 2491553Srgrimes 2501553Srgrimes/* 2511553Srgrimes * Get the state of kernel profiling. 2521553Srgrimes */ 2531553Srgrimesgetprof(kvp) 2541553Srgrimes struct kvmvars *kvp; 2551553Srgrimes{ 2561553Srgrimes int mib[3], size; 2571553Srgrimes 2581553Srgrimes if (kflag) { 2591553Srgrimes size = kvm_read(kvp->kd, nl[N_GMONPARAM].n_value, &kvp->gpm, 2601553Srgrimes sizeof kvp->gpm); 2611553Srgrimes } else { 2621553Srgrimes mib[0] = CTL_KERN; 2631553Srgrimes mib[1] = KERN_PROF; 2641553Srgrimes mib[2] = GPROF_GMONPARAM; 2651553Srgrimes size = sizeof kvp->gpm; 2661553Srgrimes if (sysctl(mib, 3, &kvp->gpm, &size, NULL, 0) < 0) 2671553Srgrimes size = 0; 2681553Srgrimes } 2691553Srgrimes if (size != sizeof kvp->gpm) { 2701553Srgrimes (void)fprintf(stderr, "kgmon: cannot get gmonparam: %s\n", 2711553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 2721553Srgrimes exit (4); 2731553Srgrimes } 2741553Srgrimes return (kvp->gpm.state); 2751553Srgrimes} 2761553Srgrimes 2771553Srgrimes/* 2781553Srgrimes * Enable or disable kernel profiling according to the state variable. 2791553Srgrimes */ 2801553Srgrimesvoid 2811553Srgrimessetprof(kvp, state) 2821553Srgrimes struct kvmvars *kvp; 2831553Srgrimes int state; 2841553Srgrimes{ 2851553Srgrimes struct gmonparam *p = (struct gmonparam *)nl[N_GMONPARAM].n_value; 2861553Srgrimes int mib[3], sz, oldstate; 2871553Srgrimes 2881553Srgrimes sz = sizeof(state); 2891553Srgrimes if (!kflag) { 2901553Srgrimes mib[0] = CTL_KERN; 2911553Srgrimes mib[1] = KERN_PROF; 2921553Srgrimes mib[2] = GPROF_STATE; 2931553Srgrimes if (sysctl(mib, 3, &oldstate, &sz, NULL, 0) < 0) 2941553Srgrimes goto bad; 2951553Srgrimes if (oldstate == state) 2961553Srgrimes return; 2971553Srgrimes (void)seteuid(0); 2981553Srgrimes if (sysctl(mib, 3, NULL, NULL, &state, sz) >= 0) { 2991553Srgrimes (void)seteuid(getuid()); 3001553Srgrimes return; 3011553Srgrimes } 3021553Srgrimes (void)seteuid(getuid()); 3038857Srgrimes } else if (kvm_write(kvp->kd, (u_long)&p->state, (void *)&state, sz) 3041553Srgrimes == sz) 3051553Srgrimes return; 3061553Srgrimesbad: 3071553Srgrimes (void)fprintf(stderr, "kgmon: warning: cannot turn profiling %s\n", 3081553Srgrimes state == GMON_PROF_OFF ? "off" : "on"); 3091553Srgrimes} 3101553Srgrimes 3111553Srgrimes/* 3121553Srgrimes * Build the gmon.out file. 3131553Srgrimes */ 3141553Srgrimesvoid 3151553Srgrimesdumpstate(kvp) 3161553Srgrimes struct kvmvars *kvp; 3171553Srgrimes{ 3181553Srgrimes register FILE *fp; 3191553Srgrimes struct rawarc rawarc; 3201553Srgrimes struct tostruct *tos; 3211553Srgrimes u_long frompc, addr; 3221553Srgrimes u_short *froms, *tickbuf; 3231553Srgrimes int mib[3], i; 3241553Srgrimes struct gmonhdr h; 3251553Srgrimes int fromindex, endfrom, toindex; 3261553Srgrimes 3271553Srgrimes setprof(kvp, GMON_PROF_OFF); 3281553Srgrimes fp = fopen("gmon.out", "w"); 3291553Srgrimes if (fp == 0) { 3301553Srgrimes perror("gmon.out"); 3311553Srgrimes return; 3321553Srgrimes } 3331553Srgrimes 3341553Srgrimes /* 3351553Srgrimes * Build the gmon header and write it to a file. 3361553Srgrimes */ 3371553Srgrimes bzero(&h, sizeof(h)); 3381553Srgrimes h.lpc = kvp->gpm.lowpc; 3391553Srgrimes h.hpc = kvp->gpm.highpc; 3401553Srgrimes h.ncnt = kvp->gpm.kcountsize + sizeof(h); 3411553Srgrimes h.version = GMONVERSION; 34213107Sbde h.profrate = kvp->gpm.profrate; 34313107Sbde if (h.profrate == 0) 34413107Sbde h.profrate = getprofhz(kvp); /* ancient kernel */ 3451553Srgrimes fwrite((char *)&h, sizeof(h), 1, fp); 3461553Srgrimes 3471553Srgrimes /* 3481553Srgrimes * Write out the tick buffer. 3491553Srgrimes */ 3501553Srgrimes mib[0] = CTL_KERN; 3511553Srgrimes mib[1] = KERN_PROF; 3521553Srgrimes if ((tickbuf = (u_short *)malloc(kvp->gpm.kcountsize)) == NULL) { 3531553Srgrimes fprintf(stderr, "kgmon: cannot allocate kcount space\n"); 3541553Srgrimes exit (5); 3551553Srgrimes } 3561553Srgrimes if (kflag) { 3571553Srgrimes i = kvm_read(kvp->kd, (u_long)kvp->gpm.kcount, (void *)tickbuf, 3581553Srgrimes kvp->gpm.kcountsize); 3591553Srgrimes } else { 3601553Srgrimes mib[2] = GPROF_COUNT; 3611553Srgrimes i = kvp->gpm.kcountsize; 3621553Srgrimes if (sysctl(mib, 3, tickbuf, &i, NULL, 0) < 0) 3631553Srgrimes i = 0; 3641553Srgrimes } 3651553Srgrimes if (i != kvp->gpm.kcountsize) { 3661553Srgrimes (void)fprintf(stderr, "kgmon: read ticks: read %u, got %d: %s", 3671553Srgrimes kvp->gpm.kcountsize, i, 3681553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 3691553Srgrimes exit(6); 3701553Srgrimes } 3711553Srgrimes if ((fwrite(tickbuf, kvp->gpm.kcountsize, 1, fp)) != 1) { 3721553Srgrimes perror("kgmon: writing tocks to gmon.out"); 3731553Srgrimes exit(7); 3741553Srgrimes } 3751553Srgrimes free(tickbuf); 3761553Srgrimes 3771553Srgrimes /* 3781553Srgrimes * Write out the arc info. 3791553Srgrimes */ 3801553Srgrimes if ((froms = (u_short *)malloc(kvp->gpm.fromssize)) == NULL) { 3811553Srgrimes fprintf(stderr, "kgmon: cannot allocate froms space\n"); 3821553Srgrimes exit (8); 3831553Srgrimes } 3841553Srgrimes if (kflag) { 3851553Srgrimes i = kvm_read(kvp->kd, (u_long)kvp->gpm.froms, (void *)froms, 3861553Srgrimes kvp->gpm.fromssize); 3871553Srgrimes } else { 3881553Srgrimes mib[2] = GPROF_FROMS; 3891553Srgrimes i = kvp->gpm.fromssize; 3901553Srgrimes if (sysctl(mib, 3, froms, &i, NULL, 0) < 0) 3911553Srgrimes i = 0; 3921553Srgrimes } 3931553Srgrimes if (i != kvp->gpm.fromssize) { 3941553Srgrimes (void)fprintf(stderr, "kgmon: read froms: read %u, got %d: %s", 3951553Srgrimes kvp->gpm.fromssize, i, 3961553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 3971553Srgrimes exit(9); 3981553Srgrimes } 3991553Srgrimes if ((tos = (struct tostruct *)malloc(kvp->gpm.tossize)) == NULL) { 4001553Srgrimes fprintf(stderr, "kgmon: cannot allocate tos space\n"); 4011553Srgrimes exit(10); 4021553Srgrimes } 4031553Srgrimes if (kflag) { 4041553Srgrimes i = kvm_read(kvp->kd, (u_long)kvp->gpm.tos, (void *)tos, 4051553Srgrimes kvp->gpm.tossize); 4061553Srgrimes } else { 4071553Srgrimes mib[2] = GPROF_TOS; 4081553Srgrimes i = kvp->gpm.tossize; 4091553Srgrimes if (sysctl(mib, 3, tos, &i, NULL, 0) < 0) 4101553Srgrimes i = 0; 4111553Srgrimes } 4121553Srgrimes if (i != kvp->gpm.tossize) { 4131553Srgrimes (void)fprintf(stderr, "kgmon: read tos: read %u, got %d: %s", 4141553Srgrimes kvp->gpm.tossize, i, 4151553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 4161553Srgrimes exit(11); 4171553Srgrimes } 4181553Srgrimes if (debug) 4191553Srgrimes (void)fprintf(stderr, "kgmon: lowpc 0x%x, textsize 0x%x\n", 4201553Srgrimes kvp->gpm.lowpc, kvp->gpm.textsize); 4211553Srgrimes endfrom = kvp->gpm.fromssize / sizeof(*froms); 4221553Srgrimes for (fromindex = 0; fromindex < endfrom; ++fromindex) { 4231553Srgrimes if (froms[fromindex] == 0) 4241553Srgrimes continue; 4251553Srgrimes frompc = (u_long)kvp->gpm.lowpc + 4261553Srgrimes (fromindex * kvp->gpm.hashfraction * sizeof(*froms)); 4271553Srgrimes for (toindex = froms[fromindex]; toindex != 0; 4281553Srgrimes toindex = tos[toindex].link) { 4291553Srgrimes if (debug) 4301553Srgrimes (void)fprintf(stderr, 4311553Srgrimes "%s: [mcleanup] frompc 0x%x selfpc 0x%x count %d\n", 4321553Srgrimes "kgmon", frompc, tos[toindex].selfpc, 4331553Srgrimes tos[toindex].count); 4341553Srgrimes rawarc.raw_frompc = frompc; 4351553Srgrimes rawarc.raw_selfpc = (u_long)tos[toindex].selfpc; 4361553Srgrimes rawarc.raw_count = tos[toindex].count; 4371553Srgrimes fwrite((char *)&rawarc, sizeof(rawarc), 1, fp); 4381553Srgrimes } 4391553Srgrimes } 4401553Srgrimes fclose(fp); 4411553Srgrimes} 4421553Srgrimes 4431553Srgrimes/* 4441553Srgrimes * Get the profiling rate. 4451553Srgrimes */ 4461553Srgrimesint 4471553Srgrimesgetprofhz(kvp) 4481553Srgrimes struct kvmvars *kvp; 4491553Srgrimes{ 4501553Srgrimes int mib[2], size, profrate; 4511553Srgrimes struct clockinfo clockrate; 4521553Srgrimes 4531553Srgrimes if (kflag) { 4541553Srgrimes profrate = 1; 4551553Srgrimes if (kvm_read(kvp->kd, nl[N_PROFHZ].n_value, &profrate, 4561553Srgrimes sizeof profrate) != sizeof profrate) 4571553Srgrimes (void)fprintf(stderr, "kgmon: get clockrate: %s\n", 4581553Srgrimes kvm_geterr(kvp->kd)); 4591553Srgrimes return (profrate); 4601553Srgrimes } 4611553Srgrimes mib[0] = CTL_KERN; 4621553Srgrimes mib[1] = KERN_CLOCKRATE; 4631553Srgrimes clockrate.profhz = 1; 4641553Srgrimes size = sizeof clockrate; 4651553Srgrimes if (sysctl(mib, 2, &clockrate, &size, NULL, 0) < 0) 4661553Srgrimes (void)fprintf(stderr, "kgmon: get clockrate: %s\n", 4671553Srgrimes strerror(errno)); 4681553Srgrimes return (clockrate.profhz); 4691553Srgrimes} 4701553Srgrimes 4711553Srgrimes/* 4721553Srgrimes * Reset the kernel profiling date structures. 4731553Srgrimes */ 4741553Srgrimesvoid 4751553Srgrimesreset(kvp) 4761553Srgrimes struct kvmvars *kvp; 4771553Srgrimes{ 4781553Srgrimes char *zbuf; 4791553Srgrimes u_long biggest; 4801553Srgrimes int mib[3]; 4811553Srgrimes 4821553Srgrimes setprof(kvp, GMON_PROF_OFF); 4831553Srgrimes 4841553Srgrimes biggest = kvp->gpm.kcountsize; 4851553Srgrimes if (kvp->gpm.fromssize > biggest) 4861553Srgrimes biggest = kvp->gpm.fromssize; 4871553Srgrimes if (kvp->gpm.tossize > biggest) 4881553Srgrimes biggest = kvp->gpm.tossize; 4891553Srgrimes if ((zbuf = (char *)malloc(biggest)) == NULL) { 4901553Srgrimes fprintf(stderr, "kgmon: cannot allocate zbuf space\n"); 4911553Srgrimes exit(12); 4921553Srgrimes } 4931553Srgrimes bzero(zbuf, biggest); 4941553Srgrimes if (kflag) { 4951553Srgrimes if (kvm_write(kvp->kd, (u_long)kvp->gpm.kcount, zbuf, 4961553Srgrimes kvp->gpm.kcountsize) != kvp->gpm.kcountsize) { 4971553Srgrimes (void)fprintf(stderr, "kgmon: tickbuf zero: %s\n", 4981553Srgrimes kvm_geterr(kvp->kd)); 4991553Srgrimes exit(13); 5001553Srgrimes } 5011553Srgrimes if (kvm_write(kvp->kd, (u_long)kvp->gpm.froms, zbuf, 5021553Srgrimes kvp->gpm.fromssize) != kvp->gpm.fromssize) { 5031553Srgrimes (void)fprintf(stderr, "kgmon: froms zero: %s\n", 5041553Srgrimes kvm_geterr(kvp->kd)); 5051553Srgrimes exit(14); 5061553Srgrimes } 5071553Srgrimes if (kvm_write(kvp->kd, (u_long)kvp->gpm.tos, zbuf, 5081553Srgrimes kvp->gpm.tossize) != kvp->gpm.tossize) { 5091553Srgrimes (void)fprintf(stderr, "kgmon: tos zero: %s\n", 5101553Srgrimes kvm_geterr(kvp->kd)); 5111553Srgrimes exit(15); 5121553Srgrimes } 5131553Srgrimes return; 5141553Srgrimes } 5151553Srgrimes (void)seteuid(0); 5161553Srgrimes mib[0] = CTL_KERN; 5171553Srgrimes mib[1] = KERN_PROF; 5181553Srgrimes mib[2] = GPROF_COUNT; 5191553Srgrimes if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.kcountsize) < 0) { 5201553Srgrimes (void)fprintf(stderr, "kgmon: tickbuf zero: %s\n", 5211553Srgrimes strerror(errno)); 5221553Srgrimes exit(13); 5231553Srgrimes } 5241553Srgrimes mib[2] = GPROF_FROMS; 5251553Srgrimes if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.fromssize) < 0) { 5261553Srgrimes (void)fprintf(stderr, "kgmon: froms zero: %s\n", 5271553Srgrimes strerror(errno)); 5281553Srgrimes exit(14); 5291553Srgrimes } 5301553Srgrimes mib[2] = GPROF_TOS; 5311553Srgrimes if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.tossize) < 0) { 5321553Srgrimes (void)fprintf(stderr, "kgmon: tos zero: %s\n", 5331553Srgrimes strerror(errno)); 5341553Srgrimes exit(15); 5351553Srgrimes } 5361553Srgrimes (void)seteuid(getuid()); 5371553Srgrimes free(zbuf); 5381553Srgrimes} 539