kgmon.c revision 11937
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 721553Srgrimesint 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; 901553Srgrimes while ((ch = getopt(argc, argv, "M:N:bhpr")) != EOF) { 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 1021553Srgrimes case 'b': 1031553Srgrimes bflag = 1; 1041553Srgrimes break; 1051553Srgrimes 1061553Srgrimes case 'h': 1071553Srgrimes hflag = 1; 1081553Srgrimes break; 1091553Srgrimes 1101553Srgrimes case 'p': 1111553Srgrimes pflag = 1; 1121553Srgrimes break; 1131553Srgrimes 1141553Srgrimes case 'r': 1151553Srgrimes rflag = 1; 1161553Srgrimes break; 1171553Srgrimes 1181553Srgrimes default: 1191553Srgrimes (void)fprintf(stderr, 1201553Srgrimes "usage: kgmon [-bhrp] [-M core] [-N system]\n"); 1211553Srgrimes exit(1); 1221553Srgrimes } 1231553Srgrimes } 1241553Srgrimes argc -= optind; 1251553Srgrimes argv += optind; 1261553Srgrimes 1271553Srgrimes#define BACKWARD_COMPATIBILITY 1281553Srgrimes#ifdef BACKWARD_COMPATIBILITY 1291553Srgrimes if (*argv) { 1301553Srgrimes system = *argv; 1311553Srgrimes if (*++argv) { 1321553Srgrimes kmemf = *argv; 1331553Srgrimes ++kflag; 1341553Srgrimes } 1351553Srgrimes } 1361553Srgrimes#endif 1371553Srgrimes if (system == NULL) 1383041Swollman system = (char *)getbootfile(); 1391553Srgrimes accessmode = openfiles(system, kmemf, &kvmvars); 1401553Srgrimes mode = getprof(&kvmvars); 1411553Srgrimes if (hflag) 1421553Srgrimes disp = GMON_PROF_OFF; 1431553Srgrimes else if (bflag) 1441553Srgrimes disp = GMON_PROF_ON; 1451553Srgrimes else 1461553Srgrimes disp = mode; 1471553Srgrimes if (pflag) 1481553Srgrimes dumpstate(&kvmvars); 1491553Srgrimes if (rflag) 1501553Srgrimes reset(&kvmvars); 1511553Srgrimes if (accessmode == O_RDWR) 1521553Srgrimes setprof(&kvmvars, disp); 1531553Srgrimes (void)fprintf(stdout, "kgmon: kernel profiling is %s.\n", 1541553Srgrimes disp == GMON_PROF_OFF ? "off" : "running"); 1551553Srgrimes return (0); 1561553Srgrimes} 1571553Srgrimes 1581553Srgrimes/* 1591553Srgrimes * Check that profiling is enabled and open any ncessary files. 1601553Srgrimes */ 1611553Srgrimesopenfiles(system, kmemf, kvp) 1621553Srgrimes char *system; 1631553Srgrimes char *kmemf; 1641553Srgrimes struct kvmvars *kvp; 1651553Srgrimes{ 1661553Srgrimes int mib[3], state, size, openmode; 1671553Srgrimes char errbuf[_POSIX2_LINE_MAX]; 1681553Srgrimes 1691553Srgrimes if (!kflag) { 1701553Srgrimes mib[0] = CTL_KERN; 1711553Srgrimes mib[1] = KERN_PROF; 1721553Srgrimes mib[2] = GPROF_STATE; 1731553Srgrimes size = sizeof state; 1741553Srgrimes if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) { 1751553Srgrimes (void)fprintf(stderr, 1761553Srgrimes "kgmon: profiling not defined in kernel.\n"); 1771553Srgrimes exit(20); 1781553Srgrimes } 1791553Srgrimes if (!(bflag || hflag || rflag || 1801553Srgrimes (pflag && state == GMON_PROF_ON))) 1811553Srgrimes return (O_RDONLY); 1821553Srgrimes (void)seteuid(0); 1831553Srgrimes if (sysctl(mib, 3, NULL, NULL, &state, size) >= 0) 1841553Srgrimes return (O_RDWR); 1851553Srgrimes (void)seteuid(getuid()); 1861553Srgrimes kern_readonly(state); 1871553Srgrimes return (O_RDONLY); 1881553Srgrimes } 1891553Srgrimes openmode = (bflag || hflag || pflag || rflag) ? O_RDWR : O_RDONLY; 1901553Srgrimes kvp->kd = kvm_openfiles(system, kmemf, NULL, openmode, errbuf); 1911553Srgrimes if (kvp->kd == NULL) { 1921553Srgrimes if (openmode == O_RDWR) { 1931553Srgrimes openmode = O_RDONLY; 1941553Srgrimes kvp->kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY, 1951553Srgrimes errbuf); 1961553Srgrimes } 1971553Srgrimes if (kvp->kd == NULL) { 1981553Srgrimes (void)fprintf(stderr, "kgmon: kvm_openfiles: %s\n", 1991553Srgrimes errbuf); 2001553Srgrimes exit(2); 2011553Srgrimes } 2021553Srgrimes kern_readonly(GMON_PROF_ON); 2031553Srgrimes } 2041553Srgrimes if (kvm_nlist(kvp->kd, nl) < 0) { 2051553Srgrimes (void)fprintf(stderr, "kgmon: %s: no namelist\n", system); 2061553Srgrimes exit(3); 2071553Srgrimes } 2081553Srgrimes if (!nl[N_GMONPARAM].n_value) { 2091553Srgrimes (void)fprintf(stderr, 2101553Srgrimes "kgmon: profiling not defined in kernel.\n"); 2111553Srgrimes exit(20); 2121553Srgrimes } 2131553Srgrimes return (openmode); 2141553Srgrimes} 2151553Srgrimes 2161553Srgrimes/* 2171553Srgrimes * Suppress options that require a writable kernel. 2181553Srgrimes */ 2191553Srgrimeskern_readonly(mode) 2201553Srgrimes int mode; 2211553Srgrimes{ 2221553Srgrimes 2231553Srgrimes (void)fprintf(stderr, "kgmon: kernel read-only: "); 2241553Srgrimes if (pflag && mode == GMON_PROF_ON) 2251553Srgrimes (void)fprintf(stderr, "data may be inconsistent\n"); 2261553Srgrimes if (rflag) 2271553Srgrimes (void)fprintf(stderr, "-r supressed\n"); 2281553Srgrimes if (bflag) 2291553Srgrimes (void)fprintf(stderr, "-b supressed\n"); 2301553Srgrimes if (hflag) 2311553Srgrimes (void)fprintf(stderr, "-h supressed\n"); 2321553Srgrimes rflag = bflag = hflag = 0; 2331553Srgrimes} 2341553Srgrimes 2351553Srgrimes/* 2361553Srgrimes * Get the state of kernel profiling. 2371553Srgrimes */ 2381553Srgrimesgetprof(kvp) 2391553Srgrimes struct kvmvars *kvp; 2401553Srgrimes{ 2411553Srgrimes int mib[3], size; 2421553Srgrimes 2431553Srgrimes if (kflag) { 2441553Srgrimes size = kvm_read(kvp->kd, nl[N_GMONPARAM].n_value, &kvp->gpm, 2451553Srgrimes sizeof kvp->gpm); 2461553Srgrimes } else { 2471553Srgrimes mib[0] = CTL_KERN; 2481553Srgrimes mib[1] = KERN_PROF; 2491553Srgrimes mib[2] = GPROF_GMONPARAM; 2501553Srgrimes size = sizeof kvp->gpm; 2511553Srgrimes if (sysctl(mib, 3, &kvp->gpm, &size, NULL, 0) < 0) 2521553Srgrimes size = 0; 2531553Srgrimes } 2541553Srgrimes if (size != sizeof kvp->gpm) { 2551553Srgrimes (void)fprintf(stderr, "kgmon: cannot get gmonparam: %s\n", 2561553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 2571553Srgrimes exit (4); 2581553Srgrimes } 2591553Srgrimes return (kvp->gpm.state); 2601553Srgrimes} 2611553Srgrimes 2621553Srgrimes/* 2631553Srgrimes * Enable or disable kernel profiling according to the state variable. 2641553Srgrimes */ 2651553Srgrimesvoid 2661553Srgrimessetprof(kvp, state) 2671553Srgrimes struct kvmvars *kvp; 2681553Srgrimes int state; 2691553Srgrimes{ 2701553Srgrimes struct gmonparam *p = (struct gmonparam *)nl[N_GMONPARAM].n_value; 2711553Srgrimes int mib[3], sz, oldstate; 2721553Srgrimes 2731553Srgrimes sz = sizeof(state); 2741553Srgrimes if (!kflag) { 2751553Srgrimes mib[0] = CTL_KERN; 2761553Srgrimes mib[1] = KERN_PROF; 2771553Srgrimes mib[2] = GPROF_STATE; 2781553Srgrimes if (sysctl(mib, 3, &oldstate, &sz, NULL, 0) < 0) 2791553Srgrimes goto bad; 2801553Srgrimes if (oldstate == state) 2811553Srgrimes return; 2821553Srgrimes (void)seteuid(0); 2831553Srgrimes if (sysctl(mib, 3, NULL, NULL, &state, sz) >= 0) { 2841553Srgrimes (void)seteuid(getuid()); 2851553Srgrimes return; 2861553Srgrimes } 2871553Srgrimes (void)seteuid(getuid()); 2888857Srgrimes } else if (kvm_write(kvp->kd, (u_long)&p->state, (void *)&state, sz) 2891553Srgrimes == sz) 2901553Srgrimes return; 2911553Srgrimesbad: 2921553Srgrimes (void)fprintf(stderr, "kgmon: warning: cannot turn profiling %s\n", 2931553Srgrimes state == GMON_PROF_OFF ? "off" : "on"); 2941553Srgrimes} 2951553Srgrimes 2961553Srgrimes/* 2971553Srgrimes * Build the gmon.out file. 2981553Srgrimes */ 2991553Srgrimesvoid 3001553Srgrimesdumpstate(kvp) 3011553Srgrimes struct kvmvars *kvp; 3021553Srgrimes{ 3031553Srgrimes register FILE *fp; 3041553Srgrimes struct rawarc rawarc; 3051553Srgrimes struct tostruct *tos; 3061553Srgrimes u_long frompc, addr; 3071553Srgrimes u_short *froms, *tickbuf; 3081553Srgrimes int mib[3], i; 3091553Srgrimes struct gmonhdr h; 3101553Srgrimes int fromindex, endfrom, toindex; 3111553Srgrimes 3121553Srgrimes setprof(kvp, GMON_PROF_OFF); 3131553Srgrimes fp = fopen("gmon.out", "w"); 3141553Srgrimes if (fp == 0) { 3151553Srgrimes perror("gmon.out"); 3161553Srgrimes return; 3171553Srgrimes } 3181553Srgrimes 3191553Srgrimes /* 3201553Srgrimes * Build the gmon header and write it to a file. 3211553Srgrimes */ 3221553Srgrimes bzero(&h, sizeof(h)); 3231553Srgrimes h.lpc = kvp->gpm.lowpc; 3241553Srgrimes h.hpc = kvp->gpm.highpc; 3251553Srgrimes h.ncnt = kvp->gpm.kcountsize + sizeof(h); 3261553Srgrimes h.version = GMONVERSION; 3271553Srgrimes h.profrate = getprofhz(kvp); 3281553Srgrimes fwrite((char *)&h, sizeof(h), 1, fp); 3291553Srgrimes 3301553Srgrimes /* 3311553Srgrimes * Write out the tick buffer. 3321553Srgrimes */ 3331553Srgrimes mib[0] = CTL_KERN; 3341553Srgrimes mib[1] = KERN_PROF; 3351553Srgrimes if ((tickbuf = (u_short *)malloc(kvp->gpm.kcountsize)) == NULL) { 3361553Srgrimes fprintf(stderr, "kgmon: cannot allocate kcount space\n"); 3371553Srgrimes exit (5); 3381553Srgrimes } 3391553Srgrimes if (kflag) { 3401553Srgrimes i = kvm_read(kvp->kd, (u_long)kvp->gpm.kcount, (void *)tickbuf, 3411553Srgrimes kvp->gpm.kcountsize); 3421553Srgrimes } else { 3431553Srgrimes mib[2] = GPROF_COUNT; 3441553Srgrimes i = kvp->gpm.kcountsize; 3451553Srgrimes if (sysctl(mib, 3, tickbuf, &i, NULL, 0) < 0) 3461553Srgrimes i = 0; 3471553Srgrimes } 3481553Srgrimes if (i != kvp->gpm.kcountsize) { 3491553Srgrimes (void)fprintf(stderr, "kgmon: read ticks: read %u, got %d: %s", 3501553Srgrimes kvp->gpm.kcountsize, i, 3511553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 3521553Srgrimes exit(6); 3531553Srgrimes } 3541553Srgrimes if ((fwrite(tickbuf, kvp->gpm.kcountsize, 1, fp)) != 1) { 3551553Srgrimes perror("kgmon: writing tocks to gmon.out"); 3561553Srgrimes exit(7); 3571553Srgrimes } 3581553Srgrimes free(tickbuf); 3591553Srgrimes 3601553Srgrimes /* 3611553Srgrimes * Write out the arc info. 3621553Srgrimes */ 3631553Srgrimes if ((froms = (u_short *)malloc(kvp->gpm.fromssize)) == NULL) { 3641553Srgrimes fprintf(stderr, "kgmon: cannot allocate froms space\n"); 3651553Srgrimes exit (8); 3661553Srgrimes } 3671553Srgrimes if (kflag) { 3681553Srgrimes i = kvm_read(kvp->kd, (u_long)kvp->gpm.froms, (void *)froms, 3691553Srgrimes kvp->gpm.fromssize); 3701553Srgrimes } else { 3711553Srgrimes mib[2] = GPROF_FROMS; 3721553Srgrimes i = kvp->gpm.fromssize; 3731553Srgrimes if (sysctl(mib, 3, froms, &i, NULL, 0) < 0) 3741553Srgrimes i = 0; 3751553Srgrimes } 3761553Srgrimes if (i != kvp->gpm.fromssize) { 3771553Srgrimes (void)fprintf(stderr, "kgmon: read froms: read %u, got %d: %s", 3781553Srgrimes kvp->gpm.fromssize, i, 3791553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 3801553Srgrimes exit(9); 3811553Srgrimes } 3821553Srgrimes if ((tos = (struct tostruct *)malloc(kvp->gpm.tossize)) == NULL) { 3831553Srgrimes fprintf(stderr, "kgmon: cannot allocate tos space\n"); 3841553Srgrimes exit(10); 3851553Srgrimes } 3861553Srgrimes if (kflag) { 3871553Srgrimes i = kvm_read(kvp->kd, (u_long)kvp->gpm.tos, (void *)tos, 3881553Srgrimes kvp->gpm.tossize); 3891553Srgrimes } else { 3901553Srgrimes mib[2] = GPROF_TOS; 3911553Srgrimes i = kvp->gpm.tossize; 3921553Srgrimes if (sysctl(mib, 3, tos, &i, NULL, 0) < 0) 3931553Srgrimes i = 0; 3941553Srgrimes } 3951553Srgrimes if (i != kvp->gpm.tossize) { 3961553Srgrimes (void)fprintf(stderr, "kgmon: read tos: read %u, got %d: %s", 3971553Srgrimes kvp->gpm.tossize, i, 3981553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 3991553Srgrimes exit(11); 4001553Srgrimes } 4011553Srgrimes if (debug) 4021553Srgrimes (void)fprintf(stderr, "kgmon: lowpc 0x%x, textsize 0x%x\n", 4031553Srgrimes kvp->gpm.lowpc, kvp->gpm.textsize); 4041553Srgrimes endfrom = kvp->gpm.fromssize / sizeof(*froms); 4051553Srgrimes for (fromindex = 0; fromindex < endfrom; ++fromindex) { 4061553Srgrimes if (froms[fromindex] == 0) 4071553Srgrimes continue; 4081553Srgrimes frompc = (u_long)kvp->gpm.lowpc + 4091553Srgrimes (fromindex * kvp->gpm.hashfraction * sizeof(*froms)); 4101553Srgrimes for (toindex = froms[fromindex]; toindex != 0; 4111553Srgrimes toindex = tos[toindex].link) { 4121553Srgrimes if (debug) 4131553Srgrimes (void)fprintf(stderr, 4141553Srgrimes "%s: [mcleanup] frompc 0x%x selfpc 0x%x count %d\n", 4151553Srgrimes "kgmon", frompc, tos[toindex].selfpc, 4161553Srgrimes tos[toindex].count); 4171553Srgrimes rawarc.raw_frompc = frompc; 4181553Srgrimes rawarc.raw_selfpc = (u_long)tos[toindex].selfpc; 4191553Srgrimes rawarc.raw_count = tos[toindex].count; 4201553Srgrimes fwrite((char *)&rawarc, sizeof(rawarc), 1, fp); 4211553Srgrimes } 4221553Srgrimes } 4231553Srgrimes fclose(fp); 4241553Srgrimes} 4251553Srgrimes 4261553Srgrimes/* 4271553Srgrimes * Get the profiling rate. 4281553Srgrimes */ 4291553Srgrimesint 4301553Srgrimesgetprofhz(kvp) 4311553Srgrimes struct kvmvars *kvp; 4321553Srgrimes{ 4331553Srgrimes int mib[2], size, profrate; 4341553Srgrimes struct clockinfo clockrate; 4351553Srgrimes 4361553Srgrimes if (kflag) { 4371553Srgrimes profrate = 1; 4381553Srgrimes if (kvm_read(kvp->kd, nl[N_PROFHZ].n_value, &profrate, 4391553Srgrimes sizeof profrate) != sizeof profrate) 4401553Srgrimes (void)fprintf(stderr, "kgmon: get clockrate: %s\n", 4411553Srgrimes kvm_geterr(kvp->kd)); 4421553Srgrimes return (profrate); 4431553Srgrimes } 4441553Srgrimes mib[0] = CTL_KERN; 4451553Srgrimes mib[1] = KERN_CLOCKRATE; 4461553Srgrimes clockrate.profhz = 1; 4471553Srgrimes size = sizeof clockrate; 4481553Srgrimes if (sysctl(mib, 2, &clockrate, &size, NULL, 0) < 0) 4491553Srgrimes (void)fprintf(stderr, "kgmon: get clockrate: %s\n", 4501553Srgrimes strerror(errno)); 4511553Srgrimes return (clockrate.profhz); 4521553Srgrimes} 4531553Srgrimes 4541553Srgrimes/* 4551553Srgrimes * Reset the kernel profiling date structures. 4561553Srgrimes */ 4571553Srgrimesvoid 4581553Srgrimesreset(kvp) 4591553Srgrimes struct kvmvars *kvp; 4601553Srgrimes{ 4611553Srgrimes char *zbuf; 4621553Srgrimes u_long biggest; 4631553Srgrimes int mib[3]; 4641553Srgrimes 4651553Srgrimes setprof(kvp, GMON_PROF_OFF); 4661553Srgrimes 4671553Srgrimes biggest = kvp->gpm.kcountsize; 4681553Srgrimes if (kvp->gpm.fromssize > biggest) 4691553Srgrimes biggest = kvp->gpm.fromssize; 4701553Srgrimes if (kvp->gpm.tossize > biggest) 4711553Srgrimes biggest = kvp->gpm.tossize; 4721553Srgrimes if ((zbuf = (char *)malloc(biggest)) == NULL) { 4731553Srgrimes fprintf(stderr, "kgmon: cannot allocate zbuf space\n"); 4741553Srgrimes exit(12); 4751553Srgrimes } 4761553Srgrimes bzero(zbuf, biggest); 4771553Srgrimes if (kflag) { 4781553Srgrimes if (kvm_write(kvp->kd, (u_long)kvp->gpm.kcount, zbuf, 4791553Srgrimes kvp->gpm.kcountsize) != kvp->gpm.kcountsize) { 4801553Srgrimes (void)fprintf(stderr, "kgmon: tickbuf zero: %s\n", 4811553Srgrimes kvm_geterr(kvp->kd)); 4821553Srgrimes exit(13); 4831553Srgrimes } 4841553Srgrimes if (kvm_write(kvp->kd, (u_long)kvp->gpm.froms, zbuf, 4851553Srgrimes kvp->gpm.fromssize) != kvp->gpm.fromssize) { 4861553Srgrimes (void)fprintf(stderr, "kgmon: froms zero: %s\n", 4871553Srgrimes kvm_geterr(kvp->kd)); 4881553Srgrimes exit(14); 4891553Srgrimes } 4901553Srgrimes if (kvm_write(kvp->kd, (u_long)kvp->gpm.tos, zbuf, 4911553Srgrimes kvp->gpm.tossize) != kvp->gpm.tossize) { 4921553Srgrimes (void)fprintf(stderr, "kgmon: tos zero: %s\n", 4931553Srgrimes kvm_geterr(kvp->kd)); 4941553Srgrimes exit(15); 4951553Srgrimes } 4961553Srgrimes return; 4971553Srgrimes } 4981553Srgrimes (void)seteuid(0); 4991553Srgrimes mib[0] = CTL_KERN; 5001553Srgrimes mib[1] = KERN_PROF; 5011553Srgrimes mib[2] = GPROF_COUNT; 5021553Srgrimes if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.kcountsize) < 0) { 5031553Srgrimes (void)fprintf(stderr, "kgmon: tickbuf zero: %s\n", 5041553Srgrimes strerror(errno)); 5051553Srgrimes exit(13); 5061553Srgrimes } 5071553Srgrimes mib[2] = GPROF_FROMS; 5081553Srgrimes if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.fromssize) < 0) { 5091553Srgrimes (void)fprintf(stderr, "kgmon: froms zero: %s\n", 5101553Srgrimes strerror(errno)); 5111553Srgrimes exit(14); 5121553Srgrimes } 5131553Srgrimes mib[2] = GPROF_TOS; 5141553Srgrimes if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.tossize) < 0) { 5151553Srgrimes (void)fprintf(stderr, "kgmon: tos zero: %s\n", 5161553Srgrimes strerror(errno)); 5171553Srgrimes exit(15); 5181553Srgrimes } 5191553Srgrimes (void)seteuid(getuid()); 5201553Srgrimes free(zbuf); 5211553Srgrimes} 522