kgmon.c revision 29736
16059Samurai/* 26059Samurai * Copyright (c) 1983, 1992, 1993 36059Samurai * The Regents of the University of California. All rights reserved. 46059Samurai * 56059Samurai * Redistribution and use in source and binary forms, with or without 66059Samurai * modification, are permitted provided that the following conditions 76059Samurai * are met: 86059Samurai * 1. Redistributions of source code must retain the above copyright 96059Samurai * notice, this list of conditions and the following disclaimer. 106059Samurai * 2. Redistributions in binary form must reproduce the above copyright 116059Samurai * notice, this list of conditions and the following disclaimer in the 126059Samurai * documentation and/or other materials provided with the distribution. 136059Samurai * 3. All advertising materials mentioning features or use of this software 146059Samurai * must display the following acknowledgement: 156059Samurai * This product includes software developed by the University of 166059Samurai * California, Berkeley and its contributors. 176059Samurai * 4. Neither the name of the University nor the names of its contributors 186059Samurai * may be used to endorse or promote products derived from this software 196059Samurai * without specific prior written permission. 2050479Speter * 218857Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 226059Samurai * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 236059Samurai * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 246059Samurai * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2528679Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2643313Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 276059Samurai * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 286059Samurai * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 296059Samurai * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 306059Samurai * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3181634Sbrian * SUCH DAMAGE. 3236285Sbrian */ 3330715Sbrian 3430715Sbrian#ifndef lint 3530715Sbrianstatic const char copyright[] = 3636285Sbrian"@(#) Copyright (c) 1983, 1992, 1993\n\ 3730715Sbrian The Regents of the University of California. All rights reserved.\n"; 3846686Sbrian#endif /* not lint */ 3937009Sbrian 4031343Sbrian#ifndef lint 4130715Sbrian#if 0 4230715Sbrianstatic char sccsid[] = "@(#)kgmon.c 8.1 (Berkeley) 6/6/93"; 436059Samurai#endif 4436285Sbrianstatic const char rcsid[] = 4536285Sbrian "$Id$"; 4636285Sbrian#endif /* not lint */ 4736285Sbrian 4836285Sbrian#include <sys/param.h> 4936285Sbrian#include <sys/file.h> 5038557Sbrian#include <sys/time.h> 5138557Sbrian#include <sys/sysctl.h> 5281634Sbrian#include <sys/gmon.h> 5381634Sbrian#include <ctype.h> 5436285Sbrian#include <err.h> 5536285Sbrian#include <errno.h> 5636285Sbrian#include <kvm.h> 5736285Sbrian#include <limits.h> 5836285Sbrian#include <nlist.h> 5936285Sbrian#include <paths.h> 6043313Sbrian#include <stdio.h> 6143313Sbrian#include <stdlib.h> 6243313Sbrian#include <string.h> 6381634Sbrian#include <unistd.h> 6481634Sbrian 6536285Sbrianstruct nlist nl[] = { 666059Samurai#define N_GMONPARAM 0 676059Samurai { "__gmonparam" }, 6846828Sbrian#define N_PROFHZ 1 696059Samurai { "_profhz" }, 7028679Sbrian { NULL }, 7128679Sbrian}; 726059Samurai 7331962Sbrianstruct kvmvars { 7430187Sbrian kvm_t *kd; 7528679Sbrian struct gmonparam gpm; 7628679Sbrian}; 7728679Sbrian 7830187Sbrianint Bflag, bflag, hflag, kflag, rflag, pflag; 7928679Sbrianint debug = 0; 8028679Sbrianint getprof __P((struct kvmvars *)); 8128679Sbrianint getprofhz __P((struct kvmvars *)); 8228679Sbrianvoid kern_readonly __P((int)); 8328679Sbrianint openfiles __P((char *, char *, struct kvmvars *)); 846059Samuraivoid setprof __P((struct kvmvars *kvp, int state)); 856059Samuraivoid dumpstate __P((struct kvmvars *kvp)); 866059Samuraivoid reset __P((struct kvmvars *kvp)); 876059Samuraistatic void usage __P((void)); 8837189Sbrian 896059Samuraiint 906059Samuraimain(int argc, char **argv) 916059Samurai{ 926059Samurai int ch, mode, disp, accessmode; 936059Samurai struct kvmvars kvmvars; 946059Samurai char *system, *kmemf; 956059Samurai 966059Samurai seteuid(getuid()); 976059Samurai kmemf = NULL; 986059Samurai system = NULL; 996059Samurai while ((ch = getopt(argc, argv, "M:N:Bbhpr")) != -1) { 1006059Samurai switch((char)ch) { 1016059Samurai 1026059Samurai case 'M': 1036059Samurai kmemf = optarg; 1046059Samurai kflag = 1; 1056059Samurai break; 1066059Samurai 1076059Samurai case 'N': 1086059Samurai system = optarg; 1096059Samurai break; 1106059Samurai 1116059Samurai case 'B': 1126059Samurai Bflag = 1; 1136059Samurai break; 1146059Samurai 1156059Samurai case 'b': 1166059Samurai bflag = 1; 11737189Sbrian break; 1186059Samurai 1196059Samurai case 'h': 1206059Samurai hflag = 1; 1216059Samurai break; 1226059Samurai 1236059Samurai case 'p': 1246059Samurai pflag = 1; 1256059Samurai break; 12637189Sbrian 1276059Samurai case 'r': 1286059Samurai rflag = 1; 1296059Samurai break; 1306059Samurai 1316059Samurai default: 1326059Samurai usage(); 1336059Samurai } 1346059Samurai } 13537189Sbrian argc -= optind; 1366059Samurai argv += optind; 1376059Samurai 1386059Samurai#define BACKWARD_COMPATIBILITY 1396059Samurai#ifdef BACKWARD_COMPATIBILITY 1406059Samurai if (*argv) { 14128679Sbrian system = *argv; 14228679Sbrian if (*++argv) { 14336285Sbrian kmemf = *argv; 14436285Sbrian ++kflag; 14528679Sbrian } 1466059Samurai } 14728679Sbrian#endif 14828679Sbrian if (system == NULL) 14928679Sbrian system = (char *)getbootfile(); 15028679Sbrian accessmode = openfiles(system, kmemf, &kvmvars); 15128679Sbrian mode = getprof(&kvmvars); 15228679Sbrian if (hflag) 15328679Sbrian disp = GMON_PROF_OFF; 15428679Sbrian else if (Bflag) 1556059Samurai disp = GMON_PROF_HIRES; 15628679Sbrian else if (bflag) 15728679Sbrian disp = GMON_PROF_ON; 15828679Sbrian else 15928679Sbrian disp = mode; 16028679Sbrian if (pflag) 16154912Sbrian dumpstate(&kvmvars); 16258042Sbrian if (rflag) 16358042Sbrian reset(&kvmvars); 16436285Sbrian if (accessmode == O_RDWR) 16528679Sbrian setprof(&kvmvars, disp); 16628679Sbrian (void)fprintf(stdout, "kgmon: kernel profiling is %s.\n", 16728679Sbrian disp == GMON_PROF_OFF ? "off" : 16828679Sbrian disp == GMON_PROF_HIRES ? "running (high resolution)" : 16936285Sbrian disp == GMON_PROF_ON ? "running" : 17036285Sbrian disp == GMON_PROF_BUSY ? "busy" : 17128679Sbrian disp == GMON_PROF_ERROR ? "off (error)" : 17228679Sbrian "in an unknown state"); 1736059Samurai return (0); 17428679Sbrian} 17528679Sbrian 17628679Sbrianstatic void 17728679Sbrianusage() 17828679Sbrian{ 17928679Sbrian fprintf(stderr, "usage: kgmon [-Bbhrp] [-M core] [-N system]\n"); 18028679Sbrian exit(1); 18136285Sbrian} 18236285Sbrian 18336285Sbrian/* 18436285Sbrian * Check that profiling is enabled and open any ncessary files. 1856059Samurai */ 18628679Sbrianint 18728679Sbrianopenfiles(system, kmemf, kvp) 18828679Sbrian char *system; 18928679Sbrian char *kmemf; 19028679Sbrian struct kvmvars *kvp; 19128679Sbrian{ 19228679Sbrian int mib[3], state, size, openmode; 19328679Sbrian char errbuf[_POSIX2_LINE_MAX]; 19428679Sbrian 19528679Sbrian if (!kflag) { 19628679Sbrian mib[0] = CTL_KERN; 19728679Sbrian mib[1] = KERN_PROF; 1986059Samurai mib[2] = GPROF_STATE; 19928679Sbrian size = sizeof state; 20028679Sbrian if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) 20128679Sbrian errx(20, "profiling not defined in kernel"); 20236285Sbrian if (!(Bflag || bflag || hflag || rflag || 20336285Sbrian (pflag && 20436285Sbrian (state == GMON_PROF_HIRES || state == GMON_PROF_ON)))) 20536285Sbrian return (O_RDONLY); 20628679Sbrian (void)seteuid(0); 20728679Sbrian if (sysctl(mib, 3, NULL, NULL, &state, size) >= 0) 2086059Samurai return (O_RDWR); 20928679Sbrian (void)seteuid(getuid()); 21028679Sbrian kern_readonly(state); 21128679Sbrian return (O_RDONLY); 21228679Sbrian } 21328679Sbrian openmode = (Bflag || bflag || hflag || pflag || rflag) 21428679Sbrian ? O_RDWR : O_RDONLY; 21528679Sbrian kvp->kd = kvm_openfiles(system, kmemf, NULL, openmode, errbuf); 21636285Sbrian if (kvp->kd == NULL) { 21728679Sbrian if (openmode == O_RDWR) { 2186059Samurai openmode = O_RDONLY; 21928679Sbrian kvp->kd = kvm_openfiles(system, kmemf, NULL, O_RDONLY, 22028679Sbrian errbuf); 22154912Sbrian } 22228679Sbrian if (kvp->kd == NULL) 22328679Sbrian errx(2, "kvm_openfiles: %s", errbuf); 2246059Samurai kern_readonly(GMON_PROF_ON); 22528679Sbrian } 2266059Samurai if (kvm_nlist(kvp->kd, nl) < 0) 22728679Sbrian errx(3, "%s: no namelist", system); 22828679Sbrian if (!nl[N_GMONPARAM].n_value) 22928679Sbrian errx(20, "profiling not defined in kernel"); 23028679Sbrian return (openmode); 23128679Sbrian} 23228679Sbrian 23328679Sbrian/* 23428679Sbrian * Suppress options that require a writable kernel. 23528679Sbrian */ 23628679Sbrianvoid 23728679Sbriankern_readonly(mode) 2386059Samurai int mode; 23928679Sbrian{ 24028679Sbrian 24128679Sbrian (void)fprintf(stderr, "kgmon: kernel read-only: "); 24228679Sbrian if (pflag && (mode == GMON_PROF_HIRES || mode == GMON_PROF_ON)) 24328679Sbrian (void)fprintf(stderr, "data may be inconsistent\n"); 24428679Sbrian if (rflag) 24528679Sbrian (void)fprintf(stderr, "-r supressed\n"); 24628679Sbrian if (Bflag) 24728679Sbrian (void)fprintf(stderr, "-B supressed\n"); 24828679Sbrian if (bflag) 24928679Sbrian (void)fprintf(stderr, "-b supressed\n"); 25028679Sbrian if (hflag) 25128679Sbrian (void)fprintf(stderr, "-h supressed\n"); 25228679Sbrian rflag = Bflag = bflag = hflag = 0; 25354912Sbrian} 25428679Sbrian 2556059Samurai/* 25628679Sbrian * Get the state of kernel profiling. 25728679Sbrian */ 25828679Sbrianint 25928679Sbriangetprof(kvp) 26028679Sbrian struct kvmvars *kvp; 26130715Sbrian{ 26228679Sbrian int mib[3], size; 26330715Sbrian 26428679Sbrian if (kflag) { 26528679Sbrian size = kvm_read(kvp->kd, nl[N_GMONPARAM].n_value, &kvp->gpm, 2666059Samurai sizeof kvp->gpm); 26728679Sbrian } else { 26828679Sbrian mib[0] = CTL_KERN; 26928679Sbrian mib[1] = KERN_PROF; 27028679Sbrian mib[2] = GPROF_GMONPARAM; 27128679Sbrian size = sizeof kvp->gpm; 27228679Sbrian if (sysctl(mib, 3, &kvp->gpm, &size, NULL, 0) < 0) 27328679Sbrian size = 0; 27428679Sbrian } 27528679Sbrian if (size != sizeof kvp->gpm) 27628679Sbrian errx(4, "cannot get gmonparam: %s", 2776059Samurai kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 27828679Sbrian return (kvp->gpm.state); 27928679Sbrian} 28028679Sbrian 28128679Sbrian/* 28228679Sbrian * Enable or disable kernel profiling according to the state variable. 28328679Sbrian */ 28428679Sbrianvoid 28528679Sbriansetprof(kvp, state) 28628679Sbrian struct kvmvars *kvp; 28728679Sbrian int state; 28828679Sbrian{ 28928679Sbrian struct gmonparam *p = (struct gmonparam *)nl[N_GMONPARAM].n_value; 29028679Sbrian int mib[3], sz, oldstate; 29128679Sbrian 29228679Sbrian sz = sizeof(state); 29328679Sbrian if (!kflag) { 29428679Sbrian mib[0] = CTL_KERN; 29528679Sbrian mib[1] = KERN_PROF; 29628679Sbrian mib[2] = GPROF_STATE; 29728679Sbrian if (sysctl(mib, 3, &oldstate, &sz, NULL, 0) < 0) 29828679Sbrian goto bad; 29928679Sbrian if (oldstate == state) 30028679Sbrian return; 30128679Sbrian (void)seteuid(0); 30228679Sbrian if (sysctl(mib, 3, NULL, NULL, &state, sz) >= 0) { 30328679Sbrian (void)seteuid(getuid()); 30428679Sbrian return; 30528679Sbrian } 30628679Sbrian (void)seteuid(getuid()); 3076059Samurai } else if (kvm_write(kvp->kd, (u_long)&p->state, (void *)&state, sz) 30828679Sbrian == sz) 3096059Samurai return; 31028679Sbrianbad: 31128679Sbrian warnx("warning: cannot turn profiling %s", 31228679Sbrian state == GMON_PROF_OFF ? "off" : "on"); 31328679Sbrian} 31428679Sbrian 31528679Sbrian/* 31628679Sbrian * Build the gmon.out file. 31728679Sbrian */ 31828679Sbrianvoid 31928679Sbriandumpstate(kvp) 3206059Samurai struct kvmvars *kvp; 32128679Sbrian{ 3226059Samurai register FILE *fp; 32328679Sbrian struct rawarc rawarc; 32428679Sbrian struct tostruct *tos; 3256059Samurai u_long frompc; 32628679Sbrian u_short *froms, *tickbuf; 32728679Sbrian int mib[3], i; 32828679Sbrian struct gmonhdr h; 32928679Sbrian int fromindex, endfrom, toindex; 33028679Sbrian 3316059Samurai setprof(kvp, GMON_PROF_OFF); 33228679Sbrian fp = fopen("gmon.out", "w"); 33328679Sbrian if (fp == 0) { 33428679Sbrian warn("gmon.out"); 33528679Sbrian return; 33628679Sbrian } 33728679Sbrian 33828679Sbrian /* 33928679Sbrian * Build the gmon header and write it to a file. 3406059Samurai */ 34128679Sbrian bzero(&h, sizeof(h)); 34228679Sbrian h.lpc = kvp->gpm.lowpc; 34328679Sbrian h.hpc = kvp->gpm.highpc; 34428679Sbrian h.ncnt = kvp->gpm.kcountsize + sizeof(h); 34528679Sbrian h.version = GMONVERSION; 34628679Sbrian h.profrate = kvp->gpm.profrate; 34728679Sbrian if (h.profrate == 0) 34828679Sbrian h.profrate = getprofhz(kvp); /* ancient kernel */ 3496059Samurai fwrite((char *)&h, sizeof(h), 1, fp); 35028679Sbrian 35128679Sbrian /* 35228679Sbrian * Write out the tick buffer. 35328679Sbrian */ 35428679Sbrian mib[0] = CTL_KERN; 35528679Sbrian mib[1] = KERN_PROF; 35628679Sbrian if ((tickbuf = (u_short *)malloc(kvp->gpm.kcountsize)) == NULL) 3576059Samurai errx(5, "cannot allocate kcount space"); 35828679Sbrian if (kflag) { 35928679Sbrian i = kvm_read(kvp->kd, (u_long)kvp->gpm.kcount, (void *)tickbuf, 36028679Sbrian kvp->gpm.kcountsize); 36128679Sbrian } else { 36228679Sbrian mib[2] = GPROF_COUNT; 36330715Sbrian i = kvp->gpm.kcountsize; 3646059Samurai if (sysctl(mib, 3, tickbuf, &i, NULL, 0) < 0) 36528679Sbrian i = 0; 36628679Sbrian } 36728679Sbrian if (i != kvp->gpm.kcountsize) 36828679Sbrian errx(6, "read ticks: read %u, got %d: %s", 36928679Sbrian kvp->gpm.kcountsize, i, 37028679Sbrian kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 37128679Sbrian if ((fwrite(tickbuf, kvp->gpm.kcountsize, 1, fp)) != 1) 37228679Sbrian err(7, "writing tocks to gmon.out"); 37328679Sbrian free(tickbuf); 37428679Sbrian 37528679Sbrian /* 37628679Sbrian * Write out the arc info. 37728679Sbrian */ 37828679Sbrian if ((froms = (u_short *)malloc(kvp->gpm.fromssize)) == NULL) 37928679Sbrian errx(8, "cannot allocate froms space"); 38028679Sbrian if (kflag) { 38130187Sbrian i = kvm_read(kvp->kd, (u_long)kvp->gpm.froms, (void *)froms, 38228679Sbrian kvp->gpm.fromssize); 38328679Sbrian } else { 38428679Sbrian mib[2] = GPROF_FROMS; 38530187Sbrian i = kvp->gpm.fromssize; 38628679Sbrian if (sysctl(mib, 3, froms, &i, NULL, 0) < 0) 38728679Sbrian i = 0; 38828679Sbrian } 38928679Sbrian if (i != kvp->gpm.fromssize) 39028679Sbrian errx(9, "read froms: read %u, got %d: %s", 39128679Sbrian kvp->gpm.fromssize, i, 39254912Sbrian kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 39354912Sbrian if ((tos = (struct tostruct *)malloc(kvp->gpm.tossize)) == NULL) 39428679Sbrian errx(10, "cannot allocate tos space"); 39528679Sbrian if (kflag) { 39630715Sbrian i = kvm_read(kvp->kd, (u_long)kvp->gpm.tos, (void *)tos, 39736285Sbrian kvp->gpm.tossize); 39836285Sbrian } else { 3996059Samurai mib[2] = GPROF_TOS; 40028679Sbrian i = kvp->gpm.tossize; 40128679Sbrian if (sysctl(mib, 3, tos, &i, NULL, 0) < 0) 40228679Sbrian i = 0; 40328679Sbrian } 40428679Sbrian if (i != kvp->gpm.tossize) 4056059Samurai errx(11, "read tos: read %u, got %d: %s", 40630715Sbrian kvp->gpm.tossize, i, 40728679Sbrian kflag ? kvm_geterr(kvp->kd) : strerror(errno)); 40828679Sbrian if (debug) 40928679Sbrian warnx("lowpc 0x%x, textsize 0x%x", 4106059Samurai kvp->gpm.lowpc, kvp->gpm.textsize); 4116059Samurai endfrom = kvp->gpm.fromssize / sizeof(*froms); 4126059Samurai for (fromindex = 0; fromindex < endfrom; ++fromindex) { 4136059Samurai if (froms[fromindex] == 0) 41436960Sbrian continue; 41536960Sbrian frompc = (u_long)kvp->gpm.lowpc + 4166059Samurai (fromindex * kvp->gpm.hashfraction * sizeof(*froms)); 41728679Sbrian for (toindex = froms[fromindex]; toindex != 0; 41828679Sbrian toindex = tos[toindex].link) { 41928679Sbrian if (debug) 42028679Sbrian warnx("[mcleanup] frompc 0x%x selfpc 0x%x count %d", 42128679Sbrian frompc, tos[toindex].selfpc, 42252197Sbrian tos[toindex].count); 4236059Samurai rawarc.raw_frompc = frompc; 42428679Sbrian rawarc.raw_selfpc = (u_long)tos[toindex].selfpc; 4256059Samurai rawarc.raw_count = tos[toindex].count; 42628679Sbrian fwrite((char *)&rawarc, sizeof(rawarc), 1, fp); 42728679Sbrian } 42836960Sbrian } 42928679Sbrian fclose(fp); 43028679Sbrian} 43128679Sbrian 43228679Sbrian/* 4336059Samurai * Get the profiling rate. 43428679Sbrian */ 43528679Sbrianint 43628679Sbriangetprofhz(kvp) 43728679Sbrian struct kvmvars *kvp; 43828679Sbrian{ 43928679Sbrian int mib[2], size, profrate; 44028679Sbrian struct clockinfo clockrate; 44128679Sbrian 44228679Sbrian if (kflag) { 44328679Sbrian profrate = 1; 44428679Sbrian if (kvm_read(kvp->kd, nl[N_PROFHZ].n_value, &profrate, 44530715Sbrian sizeof profrate) != sizeof profrate) 44628679Sbrian warnx("get clockrate: %s", kvm_geterr(kvp->kd)); 44736285Sbrian return (profrate); 44836285Sbrian } 4496059Samurai mib[0] = CTL_KERN; 45028679Sbrian mib[1] = KERN_CLOCKRATE; 45128679Sbrian clockrate.profhz = 1; 4526059Samurai size = sizeof clockrate; 45328679Sbrian if (sysctl(mib, 2, &clockrate, &size, NULL, 0) < 0) 45428679Sbrian warn("get clockrate"); 45528679Sbrian return (clockrate.profhz); 45645138Sbrian} 45728679Sbrian 45836285Sbrian/* 45936285Sbrian * Reset the kernel profiling date structures. 46028679Sbrian */ 46136285Sbrianvoid 46245138Sbrianreset(kvp) 46328679Sbrian struct kvmvars *kvp; 46428679Sbrian{ 46528679Sbrian char *zbuf; 46628679Sbrian u_long biggest; 46728679Sbrian int mib[3]; 46846686Sbrian 46928679Sbrian setprof(kvp, GMON_PROF_OFF); 4706059Samurai 47128679Sbrian biggest = kvp->gpm.kcountsize; 47228679Sbrian if (kvp->gpm.fromssize > biggest) 47328679Sbrian biggest = kvp->gpm.fromssize; 47428679Sbrian if (kvp->gpm.tossize > biggest) 47528679Sbrian biggest = kvp->gpm.tossize; 47628679Sbrian if ((zbuf = (char *)malloc(biggest)) == NULL) 47728679Sbrian errx(12, "cannot allocate zbuf space"); 47828679Sbrian bzero(zbuf, biggest); 47928679Sbrian if (kflag) { 48036285Sbrian if (kvm_write(kvp->kd, (u_long)kvp->gpm.kcount, zbuf, 48136285Sbrian kvp->gpm.kcountsize) != kvp->gpm.kcountsize) 48228679Sbrian errx(13, "tickbuf zero: %s", kvm_geterr(kvp->kd)); 48328679Sbrian if (kvm_write(kvp->kd, (u_long)kvp->gpm.froms, zbuf, 48428679Sbrian kvp->gpm.fromssize) != kvp->gpm.fromssize) 48528679Sbrian errx(14, "froms zero: %s", kvm_geterr(kvp->kd)); 48628679Sbrian if (kvm_write(kvp->kd, (u_long)kvp->gpm.tos, zbuf, 48728679Sbrian kvp->gpm.tossize) != kvp->gpm.tossize) 48828679Sbrian errx(15, "tos zero: %s", kvm_geterr(kvp->kd)); 48928679Sbrian return; 49028679Sbrian } 49128679Sbrian (void)seteuid(0); 49228679Sbrian mib[0] = CTL_KERN; 49328679Sbrian mib[1] = KERN_PROF; 49428679Sbrian mib[2] = GPROF_COUNT; 49528679Sbrian if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.kcountsize) < 0) 49628679Sbrian err(13, "tickbuf zero"); 49728679Sbrian mib[2] = GPROF_FROMS; 49828679Sbrian if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.fromssize) < 0) 49928679Sbrian err(14, "froms zero"); 50028679Sbrian mib[2] = GPROF_TOS; 50128679Sbrian if (sysctl(mib, 3, NULL, NULL, zbuf, kvp->gpm.tossize) < 0) 50228679Sbrian err(15, "tos zero"); 50328679Sbrian (void)seteuid(getuid()); 50428679Sbrian free(zbuf); 50528679Sbrian} 50628679Sbrian