kgmon.c revision 29736
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 3529736Scharnierstatic const 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 4129736Scharnier#if 0 421553Srgrimesstatic char sccsid[] = "@(#)kgmon.c 8.1 (Berkeley) 6/6/93"; 4329736Scharnier#endif 4429736Scharnierstatic const char rcsid[] = 4529736Scharnier "$Id$"; 461553Srgrimes#endif /* not lint */ 471553Srgrimes 481553Srgrimes#include <sys/param.h> 491553Srgrimes#include <sys/file.h> 5011937Sphk#include <sys/time.h> 511553Srgrimes#include <sys/sysctl.h> 521553Srgrimes#include <sys/gmon.h> 5329736Scharnier#include <ctype.h> 5429736Scharnier#include <err.h> 551553Srgrimes#include <errno.h> 561553Srgrimes#include <kvm.h> 571553Srgrimes#include <limits.h> 5829736Scharnier#include <nlist.h> 5929736Scharnier#include <paths.h> 601553Srgrimes#include <stdio.h> 611553Srgrimes#include <stdlib.h> 621553Srgrimes#include <string.h> 6329736Scharnier#include <unistd.h> 641553Srgrimes 651553Srgrimesstruct nlist nl[] = { 661553Srgrimes#define N_GMONPARAM 0 671553Srgrimes { "__gmonparam" }, 681553Srgrimes#define N_PROFHZ 1 691553Srgrimes { "_profhz" }, 7029736Scharnier { NULL }, 711553Srgrimes}; 721553Srgrimes 731553Srgrimesstruct kvmvars { 741553Srgrimes kvm_t *kd; 751553Srgrimes struct gmonparam gpm; 761553Srgrimes}; 771553Srgrimes 7813107Sbdeint Bflag, bflag, hflag, kflag, rflag, pflag; 791553Srgrimesint debug = 0; 8029736Scharnierint getprof __P((struct kvmvars *)); 8129736Scharnierint getprofhz __P((struct kvmvars *)); 8229736Scharniervoid kern_readonly __P((int)); 8329736Scharnierint openfiles __P((char *, char *, struct kvmvars *)); 841553Srgrimesvoid setprof __P((struct kvmvars *kvp, int state)); 851553Srgrimesvoid dumpstate __P((struct kvmvars *kvp)); 861553Srgrimesvoid reset __P((struct kvmvars *kvp)); 8729736Scharnierstatic void usage __P((void)); 881553Srgrimes 891553Srgrimesint 901553Srgrimesmain(int argc, char **argv) 911553Srgrimes{ 921553Srgrimes int ch, mode, disp, accessmode; 931553Srgrimes struct kvmvars kvmvars; 941553Srgrimes char *system, *kmemf; 951553Srgrimes 961553Srgrimes seteuid(getuid()); 971553Srgrimes kmemf = NULL; 981553Srgrimes system = NULL; 9924428Simp while ((ch = getopt(argc, argv, "M:N:Bbhpr")) != -1) { 1001553Srgrimes switch((char)ch) { 1011553Srgrimes 1021553Srgrimes case 'M': 1031553Srgrimes kmemf = optarg; 1041553Srgrimes kflag = 1; 1051553Srgrimes break; 1061553Srgrimes 1071553Srgrimes case 'N': 1081553Srgrimes system = optarg; 1091553Srgrimes break; 1101553Srgrimes 11113107Sbde case 'B': 11213107Sbde Bflag = 1; 11313107Sbde break; 11413107Sbde 1151553Srgrimes case 'b': 1161553Srgrimes bflag = 1; 1171553Srgrimes break; 1181553Srgrimes 1191553Srgrimes case 'h': 1201553Srgrimes hflag = 1; 1211553Srgrimes break; 1221553Srgrimes 1231553Srgrimes case 'p': 1241553Srgrimes pflag = 1; 1251553Srgrimes break; 1261553Srgrimes 1271553Srgrimes case 'r': 1281553Srgrimes rflag = 1; 1291553Srgrimes break; 1301553Srgrimes 1311553Srgrimes default: 13229736Scharnier usage(); 1331553Srgrimes } 1341553Srgrimes } 1351553Srgrimes argc -= optind; 1361553Srgrimes argv += optind; 1371553Srgrimes 1381553Srgrimes#define BACKWARD_COMPATIBILITY 1391553Srgrimes#ifdef BACKWARD_COMPATIBILITY 1401553Srgrimes if (*argv) { 1411553Srgrimes system = *argv; 1421553Srgrimes if (*++argv) { 1431553Srgrimes kmemf = *argv; 1441553Srgrimes ++kflag; 1451553Srgrimes } 1461553Srgrimes } 1471553Srgrimes#endif 1481553Srgrimes if (system == NULL) 1493041Swollman system = (char *)getbootfile(); 1501553Srgrimes accessmode = openfiles(system, kmemf, &kvmvars); 1511553Srgrimes mode = getprof(&kvmvars); 1521553Srgrimes if (hflag) 1531553Srgrimes disp = GMON_PROF_OFF; 15413107Sbde else if (Bflag) 15513107Sbde disp = GMON_PROF_HIRES; 1561553Srgrimes else if (bflag) 1571553Srgrimes disp = GMON_PROF_ON; 1581553Srgrimes else 1591553Srgrimes disp = mode; 1601553Srgrimes if (pflag) 1611553Srgrimes dumpstate(&kvmvars); 1621553Srgrimes if (rflag) 1631553Srgrimes reset(&kvmvars); 1641553Srgrimes if (accessmode == O_RDWR) 1651553Srgrimes setprof(&kvmvars, disp); 1661553Srgrimes (void)fprintf(stdout, "kgmon: kernel profiling is %s.\n", 16713107Sbde disp == GMON_PROF_OFF ? "off" : 16813107Sbde disp == GMON_PROF_HIRES ? "running (high resolution)" : 16913107Sbde disp == GMON_PROF_ON ? "running" : 17013107Sbde disp == GMON_PROF_BUSY ? "busy" : 17113107Sbde disp == GMON_PROF_ERROR ? "off (error)" : 17213107Sbde "in an unknown state"); 1731553Srgrimes return (0); 1741553Srgrimes} 1751553Srgrimes 17629736Scharnierstatic void 17729736Scharnierusage() 17829736Scharnier{ 17929736Scharnier fprintf(stderr, "usage: kgmon [-Bbhrp] [-M core] [-N system]\n"); 18029736Scharnier exit(1); 18129736Scharnier} 18229736Scharnier 1831553Srgrimes/* 1841553Srgrimes * Check that profiling is enabled and open any ncessary files. 1851553Srgrimes */ 18629736Scharnierint 1871553Srgrimesopenfiles(system, kmemf, kvp) 1881553Srgrimes char *system; 1891553Srgrimes char *kmemf; 1901553Srgrimes struct kvmvars *kvp; 1911553Srgrimes{ 1921553Srgrimes int mib[3], state, size, openmode; 1931553Srgrimes char errbuf[_POSIX2_LINE_MAX]; 1941553Srgrimes 1951553Srgrimes if (!kflag) { 1961553Srgrimes mib[0] = CTL_KERN; 1971553Srgrimes mib[1] = KERN_PROF; 1981553Srgrimes mib[2] = GPROF_STATE; 1991553Srgrimes size = sizeof state; 20029736Scharnier if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) 20129736Scharnier errx(20, "profiling not defined in kernel"); 20213107Sbde if (!(Bflag || bflag || hflag || rflag || 20313107Sbde (pflag && 20413107Sbde (state == GMON_PROF_HIRES || state == GMON_PROF_ON)))) 2051553Srgrimes return (O_RDONLY); 2061553Srgrimes (void)seteuid(0); 2071553Srgrimes if (sysctl(mib, 3, NULL, NULL, &state, size) >= 0) 2081553Srgrimes return (O_RDWR); 2091553Srgrimes (void)seteuid(getuid()); 2101553Srgrimes kern_readonly(state); 2111553Srgrimes return (O_RDONLY); 2121553Srgrimes } 21313107Sbde openmode = (Bflag || bflag || hflag || pflag || rflag) 21413107Sbde ? O_RDWR : O_RDONLY; 2151553Srgrimes kvp->kd = kvm_openfiles(system, kmemf, NULL, openmode, errbuf); 2161553Srgrimes if (kvp->kd == NULL) { 2171553Srgrimes if (openmode == O_RDWR) { 2181553Srgrimes openmode = O_RDONLY; 2191553Srgrimes kvp->kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY, 2201553Srgrimes errbuf); 2211553Srgrimes } 22229736Scharnier if (kvp->kd == NULL) 22329736Scharnier errx(2, "kvm_openfiles: %s", errbuf); 2241553Srgrimes kern_readonly(GMON_PROF_ON); 2251553Srgrimes } 22629736Scharnier if (kvm_nlist(kvp->kd, nl) < 0) 22729736Scharnier errx(3, "%s: no namelist", system); 22829736Scharnier if (!nl[N_GMONPARAM].n_value) 22929736Scharnier errx(20, "profiling not defined in kernel"); 2301553Srgrimes return (openmode); 2311553Srgrimes} 2321553Srgrimes 2331553Srgrimes/* 2341553Srgrimes * Suppress options that require a writable kernel. 2351553Srgrimes */ 23629736Scharniervoid 2371553Srgrimeskern_readonly(mode) 2381553Srgrimes int mode; 2391553Srgrimes{ 2401553Srgrimes 2411553Srgrimes (void)fprintf(stderr, "kgmon: kernel read-only: "); 24213107Sbde if (pflag && (mode == GMON_PROF_HIRES || mode == GMON_PROF_ON)) 2431553Srgrimes (void)fprintf(stderr, "data may be inconsistent\n"); 2441553Srgrimes if (rflag) 2451553Srgrimes (void)fprintf(stderr, "-r supressed\n"); 24613107Sbde if (Bflag) 24713107Sbde (void)fprintf(stderr, "-B supressed\n"); 2481553Srgrimes if (bflag) 2491553Srgrimes (void)fprintf(stderr, "-b supressed\n"); 2501553Srgrimes if (hflag) 2511553Srgrimes (void)fprintf(stderr, "-h supressed\n"); 25213107Sbde rflag = Bflag = bflag = hflag = 0; 2531553Srgrimes} 2541553Srgrimes 2551553Srgrimes/* 2561553Srgrimes * Get the state of kernel profiling. 2571553Srgrimes */ 25829736Scharnierint 2591553Srgrimesgetprof(kvp) 2601553Srgrimes struct kvmvars *kvp; 2611553Srgrimes{ 2621553Srgrimes int mib[3], size; 2631553Srgrimes 2641553Srgrimes if (kflag) { 2651553Srgrimes size = kvm_read(kvp->kd, nl[N_GMONPARAM].n_value, &kvp->gpm, 2661553Srgrimes sizeof kvp->gpm); 2671553Srgrimes } else { 2681553Srgrimes mib[0] = CTL_KERN; 2691553Srgrimes mib[1] = KERN_PROF; 2701553Srgrimes mib[2] = GPROF_GMONPARAM; 2711553Srgrimes size = sizeof kvp->gpm; 2721553Srgrimes if (sysctl(mib, 3, &kvp->gpm, &size, NULL, 0) < 0) 2731553Srgrimes size = 0; 2741553Srgrimes } 27529736Scharnier if (size != sizeof kvp->gpm) 27629736Scharnier errx(4, "cannot get gmonparam: %s", 2771553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 2781553Srgrimes return (kvp->gpm.state); 2791553Srgrimes} 2801553Srgrimes 2811553Srgrimes/* 2821553Srgrimes * Enable or disable kernel profiling according to the state variable. 2831553Srgrimes */ 2841553Srgrimesvoid 2851553Srgrimessetprof(kvp, state) 2861553Srgrimes struct kvmvars *kvp; 2871553Srgrimes int state; 2881553Srgrimes{ 2891553Srgrimes struct gmonparam *p = (struct gmonparam *)nl[N_GMONPARAM].n_value; 2901553Srgrimes int mib[3], sz, oldstate; 2911553Srgrimes 2921553Srgrimes sz = sizeof(state); 2931553Srgrimes if (!kflag) { 2941553Srgrimes mib[0] = CTL_KERN; 2951553Srgrimes mib[1] = KERN_PROF; 2961553Srgrimes mib[2] = GPROF_STATE; 2971553Srgrimes if (sysctl(mib, 3, &oldstate, &sz, NULL, 0) < 0) 2981553Srgrimes goto bad; 2991553Srgrimes if (oldstate == state) 3001553Srgrimes return; 3011553Srgrimes (void)seteuid(0); 3021553Srgrimes if (sysctl(mib, 3, NULL, NULL, &state, sz) >= 0) { 3031553Srgrimes (void)seteuid(getuid()); 3041553Srgrimes return; 3051553Srgrimes } 3061553Srgrimes (void)seteuid(getuid()); 3078857Srgrimes } else if (kvm_write(kvp->kd, (u_long)&p->state, (void *)&state, sz) 3081553Srgrimes == sz) 3091553Srgrimes return; 3101553Srgrimesbad: 31129736Scharnier warnx("warning: cannot turn profiling %s", 3121553Srgrimes state == GMON_PROF_OFF ? "off" : "on"); 3131553Srgrimes} 3141553Srgrimes 3151553Srgrimes/* 3161553Srgrimes * Build the gmon.out file. 3171553Srgrimes */ 3181553Srgrimesvoid 3191553Srgrimesdumpstate(kvp) 3201553Srgrimes struct kvmvars *kvp; 3211553Srgrimes{ 3221553Srgrimes register FILE *fp; 3231553Srgrimes struct rawarc rawarc; 3241553Srgrimes struct tostruct *tos; 32529736Scharnier u_long frompc; 3261553Srgrimes u_short *froms, *tickbuf; 3271553Srgrimes int mib[3], i; 3281553Srgrimes struct gmonhdr h; 3291553Srgrimes int fromindex, endfrom, toindex; 3301553Srgrimes 3311553Srgrimes setprof(kvp, GMON_PROF_OFF); 3321553Srgrimes fp = fopen("gmon.out", "w"); 3331553Srgrimes if (fp == 0) { 33429736Scharnier warn("gmon.out"); 3351553Srgrimes return; 3361553Srgrimes } 3371553Srgrimes 3381553Srgrimes /* 3391553Srgrimes * Build the gmon header and write it to a file. 3401553Srgrimes */ 3411553Srgrimes bzero(&h, sizeof(h)); 3421553Srgrimes h.lpc = kvp->gpm.lowpc; 3431553Srgrimes h.hpc = kvp->gpm.highpc; 3441553Srgrimes h.ncnt = kvp->gpm.kcountsize + sizeof(h); 3451553Srgrimes h.version = GMONVERSION; 34613107Sbde h.profrate = kvp->gpm.profrate; 34713107Sbde if (h.profrate == 0) 34813107Sbde h.profrate = getprofhz(kvp); /* ancient kernel */ 3491553Srgrimes fwrite((char *)&h, sizeof(h), 1, fp); 3501553Srgrimes 3511553Srgrimes /* 3521553Srgrimes * Write out the tick buffer. 3531553Srgrimes */ 3541553Srgrimes mib[0] = CTL_KERN; 3551553Srgrimes mib[1] = KERN_PROF; 35629736Scharnier if ((tickbuf = (u_short *)malloc(kvp->gpm.kcountsize)) == NULL) 35729736Scharnier errx(5, "cannot allocate kcount space"); 3581553Srgrimes if (kflag) { 3591553Srgrimes i = kvm_read(kvp->kd, (u_long)kvp->gpm.kcount, (void *)tickbuf, 3601553Srgrimes kvp->gpm.kcountsize); 3611553Srgrimes } else { 3621553Srgrimes mib[2] = GPROF_COUNT; 3631553Srgrimes i = kvp->gpm.kcountsize; 3641553Srgrimes if (sysctl(mib, 3, tickbuf, &i, NULL, 0) < 0) 3651553Srgrimes i = 0; 3661553Srgrimes } 36729736Scharnier if (i != kvp->gpm.kcountsize) 36829736Scharnier errx(6, "read ticks: read %u, got %d: %s", 3691553Srgrimes kvp->gpm.kcountsize, i, 3701553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 37129736Scharnier if ((fwrite(tickbuf, kvp->gpm.kcountsize, 1, fp)) != 1) 37229736Scharnier err(7, "writing tocks to gmon.out"); 3731553Srgrimes free(tickbuf); 3741553Srgrimes 3751553Srgrimes /* 3761553Srgrimes * Write out the arc info. 3771553Srgrimes */ 37829736Scharnier if ((froms = (u_short *)malloc(kvp->gpm.fromssize)) == NULL) 37929736Scharnier errx(8, "cannot allocate froms space"); 3801553Srgrimes if (kflag) { 3811553Srgrimes i = kvm_read(kvp->kd, (u_long)kvp->gpm.froms, (void *)froms, 3821553Srgrimes kvp->gpm.fromssize); 3831553Srgrimes } else { 3841553Srgrimes mib[2] = GPROF_FROMS; 3851553Srgrimes i = kvp->gpm.fromssize; 3861553Srgrimes if (sysctl(mib, 3, froms, &i, NULL, 0) < 0) 3871553Srgrimes i = 0; 3881553Srgrimes } 38929736Scharnier if (i != kvp->gpm.fromssize) 39029736Scharnier errx(9, "read froms: read %u, got %d: %s", 3911553Srgrimes kvp->gpm.fromssize, i, 3921553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 39329736Scharnier if ((tos = (struct tostruct *)malloc(kvp->gpm.tossize)) == NULL) 39429736Scharnier errx(10, "cannot allocate tos space"); 3951553Srgrimes if (kflag) { 3961553Srgrimes i = kvm_read(kvp->kd, (u_long)kvp->gpm.tos, (void *)tos, 3971553Srgrimes kvp->gpm.tossize); 3981553Srgrimes } else { 3991553Srgrimes mib[2] = GPROF_TOS; 4001553Srgrimes i = kvp->gpm.tossize; 4011553Srgrimes if (sysctl(mib, 3, tos, &i, NULL, 0) < 0) 4021553Srgrimes i = 0; 4031553Srgrimes } 40429736Scharnier if (i != kvp->gpm.tossize) 40529736Scharnier errx(11, "read tos: read %u, got %d: %s", 4061553Srgrimes kvp->gpm.tossize, i, 4071553Srgrimes kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 4081553Srgrimes if (debug) 40929736Scharnier warnx("lowpc 0x%x, textsize 0x%x", 4101553Srgrimes kvp->gpm.lowpc, kvp->gpm.textsize); 4111553Srgrimes endfrom = kvp->gpm.fromssize / sizeof(*froms); 4121553Srgrimes for (fromindex = 0; fromindex < endfrom; ++fromindex) { 4131553Srgrimes if (froms[fromindex] == 0) 4141553Srgrimes continue; 4151553Srgrimes frompc = (u_long)kvp->gpm.lowpc + 4161553Srgrimes (fromindex * kvp->gpm.hashfraction * sizeof(*froms)); 4171553Srgrimes for (toindex = froms[fromindex]; toindex != 0; 4181553Srgrimes toindex = tos[toindex].link) { 4191553Srgrimes if (debug) 42029736Scharnier warnx("[mcleanup] frompc 0x%x selfpc 0x%x count %d", 42129736Scharnier frompc, tos[toindex].selfpc, 4221553Srgrimes tos[toindex].count); 4231553Srgrimes rawarc.raw_frompc = frompc; 4241553Srgrimes rawarc.raw_selfpc = (u_long)tos[toindex].selfpc; 4251553Srgrimes rawarc.raw_count = tos[toindex].count; 4261553Srgrimes fwrite((char *)&rawarc, sizeof(rawarc), 1, fp); 4271553Srgrimes } 4281553Srgrimes } 4291553Srgrimes fclose(fp); 4301553Srgrimes} 4311553Srgrimes 4321553Srgrimes/* 4331553Srgrimes * Get the profiling rate. 4341553Srgrimes */ 4351553Srgrimesint 4361553Srgrimesgetprofhz(kvp) 4371553Srgrimes struct kvmvars *kvp; 4381553Srgrimes{ 4391553Srgrimes int mib[2], size, profrate; 4401553Srgrimes struct clockinfo clockrate; 4411553Srgrimes 4421553Srgrimes if (kflag) { 4431553Srgrimes profrate = 1; 4441553Srgrimes if (kvm_read(kvp->kd, nl[N_PROFHZ].n_value, &profrate, 4451553Srgrimes sizeof profrate) != sizeof profrate) 44629736Scharnier warnx("get clockrate: %s", kvm_geterr(kvp->kd)); 4471553Srgrimes return (profrate); 4481553Srgrimes } 4491553Srgrimes mib[0] = CTL_KERN; 4501553Srgrimes mib[1] = KERN_CLOCKRATE; 4511553Srgrimes clockrate.profhz = 1; 4521553Srgrimes size = sizeof clockrate; 4531553Srgrimes if (sysctl(mib, 2, &clockrate, &size, NULL, 0) < 0) 45429736Scharnier warn("get clockrate"); 4551553Srgrimes return (clockrate.profhz); 4561553Srgrimes} 4571553Srgrimes 4581553Srgrimes/* 4591553Srgrimes * Reset the kernel profiling date structures. 4601553Srgrimes */ 4611553Srgrimesvoid 4621553Srgrimesreset(kvp) 4631553Srgrimes struct kvmvars *kvp; 4641553Srgrimes{ 4651553Srgrimes char *zbuf; 4661553Srgrimes u_long biggest; 4671553Srgrimes int mib[3]; 4681553Srgrimes 4691553Srgrimes setprof(kvp, GMON_PROF_OFF); 4701553Srgrimes 4711553Srgrimes biggest = kvp->gpm.kcountsize; 4721553Srgrimes if (kvp->gpm.fromssize > biggest) 4731553Srgrimes biggest = kvp->gpm.fromssize; 4741553Srgrimes if (kvp->gpm.tossize > biggest) 4751553Srgrimes biggest = kvp->gpm.tossize; 47629736Scharnier if ((zbuf = (char *)malloc(biggest)) == NULL) 47729736Scharnier errx(12, "cannot allocate zbuf space"); 4781553Srgrimes bzero(zbuf, biggest); 4791553Srgrimes if (kflag) { 4801553Srgrimes if (kvm_write(kvp->kd, (u_long)kvp->gpm.kcount, zbuf, 48129736Scharnier kvp->gpm.kcountsize) != kvp->gpm.kcountsize) 48229736Scharnier errx(13, "tickbuf zero: %s", kvm_geterr(kvp->kd)); 4831553Srgrimes if (kvm_write(kvp->kd, (u_long)kvp->gpm.froms, zbuf, 48429736Scharnier kvp->gpm.fromssize) != kvp->gpm.fromssize) 48529736Scharnier errx(14, "froms zero: %s", kvm_geterr(kvp->kd)); 4861553Srgrimes if (kvm_write(kvp->kd, (u_long)kvp->gpm.tos, zbuf, 48729736Scharnier kvp->gpm.tossize) != kvp->gpm.tossize) 48829736Scharnier errx(15, "tos zero: %s", kvm_geterr(kvp->kd)); 4891553Srgrimes return; 4901553Srgrimes } 4911553Srgrimes (void)seteuid(0); 4921553Srgrimes mib[0] = CTL_KERN; 4931553Srgrimes mib[1] = KERN_PROF; 4941553Srgrimes mib[2] = GPROF_COUNT; 49529736Scharnier if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.kcountsize) < 0) 49629736Scharnier err(13, "tickbuf zero"); 4971553Srgrimes mib[2] = GPROF_FROMS; 49829736Scharnier if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.fromssize) < 0) 49929736Scharnier err(14, "froms zero"); 5001553Srgrimes mib[2] = GPROF_TOS; 50129736Scharnier if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.tossize) < 0) 50229736Scharnier err(15, "tos zero"); 5031553Srgrimes (void)seteuid(getuid()); 5041553Srgrimes free(zbuf); 5051553Srgrimes} 506