X-Git-Url: https://git.saurik.com/apple/system_cmds.git/blobdiff_plain/83f6dbe8135dc38ce4ac497ebea7f0ebc87d9199..b58caf92d598c70ddd398b3909b0a2b8b5a110e1:/sc_usage.tproj/sc_usage.c diff --git a/sc_usage.tproj/sc_usage.c b/sc_usage.tproj/sc_usage.c index 6808993..d39e8ef 100644 --- a/sc_usage.tproj/sc_usage.c +++ b/sc_usage.tproj/sc_usage.c @@ -1,30 +1,29 @@ /* - * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * + * + * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 1.0 (the 'License'). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." + * * @APPLE_LICENSE_HEADER_END@ */ /* -cc -I. -DKERNEL_PRIVATE -O -o sc_usage sc_usage.c -lncurses +cc -I. -DPRIVATE -D__APPLE_PRIVATE -O -o sc_usage sc_usage.c -lncurses */ #define Default_DELAY 1 /* default delay interval */ @@ -60,7 +59,7 @@ cc -I. -DKERNEL_PRIVATE -O -o sc_usage sc_usage.c -lncurses #include #include #include - +#include /* Number of lines of header information on the standard screen */ #define HEADER_LINES 5 @@ -91,9 +90,9 @@ long start_time = 0; #define MAX_NESTED 8 #define MAX_FAULTS 5 -/* If NUMPARMS from kernel changes, it will be reflected in PATHLENGTH as well */ + #define NUMPARMS 23 -#define PATHLENGTH (NUMPARMS*sizeof(long)) + char *state_name[] = { "Dont Know", @@ -120,17 +119,17 @@ struct entry { }; struct th_info { - int thread; + uintptr_t thread; int depth; int vfslookup; int curpri; long *pathptr; - char pathname[PATHLENGTH + 1]; + long pathname[NUMPARMS + 1]; struct entry th_entry[MAX_NESTED]; }; struct sc_entry { - char name[32]; + char name[64]; int delta_count; int total_count; int waiting; @@ -172,6 +171,7 @@ double other_start; int max_sc = 0; int bsc_base = 0; int msc_base = 0; +int mach_idle = 0; int mach_sched = 0; int mach_stkhandoff = 0; int vfs_lookup = 0; @@ -194,10 +194,9 @@ int scalls; #define DIVISOR 16.6666 /* Trace divisor converts to microseconds */ double divisor = DIVISOR; - int mib[6]; size_t needed; -char *my_buffer; +void *my_buffer; kbufinfo_t bufinfo = {0, 0, 0, 0}; @@ -205,27 +204,36 @@ int trace_enabled = 0; int set_remove_flag = 1; struct kinfo_proc *kp_buffer = 0; -int kp_nentries = 0; +size_t kp_nentries = 0; extern char **environ; -void set_enable(); -void set_pidcheck(); -void set_remove(); -void set_numbufs(); -void set_init(); +static void set_enable(int); +static void set_pidcheck(int, int); +static void set_remove(void); +static void set_numbufs(int); +static void set_init(void); void quit(char *); int argtopid(char *); int argtoi(int, char*, char*, int); +void get_bufinfo(kbufinfo_t *); +static void reset_counters(void); +static void getdivisor(void); +static void screen_update(void); +static void sc_tab_init(char *); +static void sort_scalls(void); +static void sample_sc(void); +static int find_msgcode(int); /* * signal handlers */ -void leave() /* exit under normal conditions -- INT handler */ +/* exit under normal conditions -- INT handler */ +static void +leave(__unused int unused) { - if (no_screen_refresh == 0) { move(LINES - 1, 0); refresh(); @@ -237,36 +245,16 @@ void leave() /* exit under normal conditions -- INT handler */ exit(0); } -void err_leave(s) /* exit under error conditions */ -char *s; -{ - - if (no_screen_refresh == 0) { - move(LINES - 1, 0); - refresh(); - endwin(); - } - - printf("sc_usage: "); - if (s) - printf("%s ", s); - - set_enable(0); - set_pidcheck(pid, 0); - set_remove(); - - exit(1); -} - -void sigwinch() +static void +sigwinch(__unused int unused) { if (no_screen_refresh == 0) newLINES = 1; } -int -exit_usage(char *myname) { - +static int +exit_usage(char *myname) +{ fprintf(stderr, "Usage: %s [-c codefile] [-e] [-l] [-sn] pid | cmd | -E execute path\n", myname); fprintf(stderr, " -c name of codefile containing mappings for syscalls\n"); fprintf(stderr, " Default is /usr/share/misc/trace.codes\n"); @@ -280,10 +268,10 @@ exit_usage(char *myname) { exit(1); } - #define usec_to_1000ths(t) ((t) / 1000) -void print_time(char *p, unsigned int useconds, unsigned int seconds) +static void +print_time(char *p, unsigned int useconds, unsigned int seconds) { long minutes, hours; @@ -291,11 +279,11 @@ void print_time(char *p, unsigned int useconds, unsigned int seconds) hours = minutes / 60; if (minutes < 100) { // up to 100 minutes - sprintf(p, "%2ld:%02ld.%03ld", minutes, (unsigned long)(seconds % 60), + sprintf(p, "%02ld:%02ld.%03ld", minutes, (unsigned long)(seconds % 60), (unsigned long)usec_to_1000ths(useconds)); } else if (hours < 100) { // up to 100 hours - sprintf(p, "%2ld:%02ld:%02ld ", hours, (minutes % 60), + sprintf(p, "%02ld:%02ld:%02ld ", hours, (minutes % 60), (unsigned long)(seconds % 60)); } else { @@ -304,26 +292,24 @@ void print_time(char *p, unsigned int useconds, unsigned int seconds) } int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { char *myname = "sc_usage"; char *codefile = "/usr/share/misc/trace.codes"; char ch; char *ptr; int delay = Default_DELAY; - void screen_update(); - void sort_scalls(); - void sc_tab_init(); - void getdivisor(); - void reset_counters(); if ( geteuid() != 0 ) { printf("'sc_usage' must be run as root...\n"); exit(1); } + if (0 != reexec_to_match_kernel()) { + fprintf(stderr, "Could not re-execute: %d\n", errno); + exit(1); + } + /* get our name */ if (argc > 0) { if ((myname = rindex(argv[0], '/')) == 0) { @@ -374,7 +360,7 @@ main(argc, argv) uid_t uid, euid; gid_t gid, egid; - + ptr = strrchr(argv[optind], '/'); if (ptr) ptr++; @@ -384,7 +370,7 @@ main(argc, argv) strncpy(proc_name, ptr, sizeof(proc_name)-1); proc_name[sizeof(proc_name)-1] = '\0'; - uid= getuid(); + uid= getuid(); gid= getgid(); euid= geteuid(); egid= getegid(); @@ -448,8 +434,6 @@ main(argc, argv) topn = 1024; COLS = 80; } - if ((my_buffer = malloc(SAMPLE_SIZE * sizeof(kd_buf))) == (char *)0) - quit("can't allocate memory for tracing info\n"); set_remove(); set_numbufs(SAMPLE_SIZE); @@ -465,6 +449,12 @@ main(argc, argv) if ((sort_now = 10 / delay) < 2) sort_now = 2; + get_bufinfo(&bufinfo); + + my_buffer = malloc(bufinfo.nkdbufs * sizeof(kd_buf)); + if(my_buffer == (char *) 0) + quit("can't allocate memory for tracing info\n"); + (void)sort_scalls(); (void)screen_update(); @@ -473,13 +463,12 @@ main(argc, argv) while (1) { int i; char c; - void sample_sc(); - + for (i = 0; i < (10 * delay) && newLINES == 0; i++) { if (no_screen_refresh == 0) { - if ((c = getch()) != ERR && (char)c == 'q') - leave(); + if ((c = getch()) != ERR && (char)c == 'q') + leave(0); if (c != ERR) reset_counters(); } else @@ -504,10 +493,11 @@ main(argc, argv) } } -void -print_row(struct sc_entry *se, int no_wtime) { +static void +print_row(struct sc_entry *se, int no_wtime) +{ char tbuf[256]; - int clen; + size_t clen; if (se->delta_count) sprintf(tbuf, "%-23.23s %8d(%d)", se->name, se->total_count, se->delta_count); @@ -517,14 +507,14 @@ print_row(struct sc_entry *se, int no_wtime) { memset(&tbuf[clen], ' ', 45 - clen); - print_time(&tbuf[45], (unsigned long)(se->stime_usecs), se->stime_secs); + print_time(&tbuf[45], (unsigned int)(se->stime_usecs), se->stime_secs); clen = strlen(tbuf); if (no_wtime == 0 && (se->wtime_usecs || se->wtime_secs)) { sprintf(&tbuf[clen], " "); clen += strlen(&tbuf[clen]); - print_time(&tbuf[clen], (unsigned long)(se->wtime_usecs), se->wtime_secs); + print_time(&tbuf[clen], (unsigned int)(se->wtime_usecs), se->wtime_secs); clen += strlen(&tbuf[clen]); if (se->waiting || se->delta_wtime_usecs || se->delta_wtime_secs) { @@ -532,7 +522,7 @@ print_row(struct sc_entry *se, int no_wtime) { sprintf(&tbuf[clen], "("); clen += strlen(&tbuf[clen]); - print_time(&tbuf[clen], (unsigned long)(se->delta_wtime_usecs), + print_time(&tbuf[clen], (unsigned int)(se->delta_wtime_usecs), se->delta_wtime_secs); clen += strlen(&tbuf[clen]); @@ -549,34 +539,29 @@ print_row(struct sc_entry *se, int no_wtime) { } } sprintf(&tbuf[clen], "\n"); - - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } if (no_screen_refresh) printf("%s", tbuf); else printw(tbuf); } - -void screen_update() +static void +screen_update(void) { char *p1, *p2, *p3; char tbuf[256]; - int clen; - int plen; + size_t clen; + size_t plen; int n, i, rows; long curr_time; long elapsed_secs; - int hours; - int minutes; + long hours; + long minutes; struct sc_entry *se; int output_lf; int max_rows; struct th_info *ti; - + if (no_screen_refresh == 0) { /* clear for new display */ erase(); @@ -586,7 +571,7 @@ void screen_update() sprintf(tbuf, "%-14.14s", proc_name); clen = strlen(tbuf); - + if (preempted == 1) p1 = "preemption "; else @@ -607,7 +592,7 @@ void screen_update() /* * Display the current time. * "ctime" always returns a string that looks like this: - * + * * Sun Sep 16 01:03:52 1973 * 012345678901234567890123 * 1 2 @@ -628,11 +613,6 @@ void screen_update() clen = 78 - 8; sprintf(&tbuf[clen], "%-8.8s\n", &(ctime(&curr_time)[11])); - - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } if (no_screen_refresh) printf("%s", tbuf); else @@ -651,12 +631,7 @@ void screen_update() clen = strlen(tbuf); sprintf(&tbuf[clen], " %3ld:%02ld:%02ld\n", - (long)hours, (long)(minutes % 60), (long)(elapsed_secs % 60)); - - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } + hours, minutes % 60, elapsed_secs % 60); if (no_screen_refresh) printf("%s", tbuf); else @@ -664,22 +639,13 @@ void screen_update() - sprintf(tbuf, "\nTYPE NUMBER CPU_TIME WAIT_TIME\n"); - - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } + sprintf(tbuf, "\nTYPE NUMBER CPU_TIME WAIT_TIME\n"); if (no_screen_refresh) printf("%s", tbuf); else printw(tbuf); sprintf(tbuf, "------------------------------------------------------------------------------\n"); - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } if (no_screen_refresh) printf("%s", tbuf); else @@ -691,7 +657,7 @@ void screen_update() sprintf(tbuf, "System Idle "); clen = strlen(tbuf); - print_time(&tbuf[clen], (unsigned long)(itime_usecs), itime_secs); + print_time(&tbuf[clen], itime_usecs, itime_secs); clen += strlen(&tbuf[clen]); if (delta_itime_usecs || delta_itime_secs) { @@ -699,18 +665,13 @@ void screen_update() sprintf(&tbuf[clen], "("); clen += strlen(&tbuf[clen]); - print_time(&tbuf[clen], (unsigned long)(delta_itime_usecs), delta_itime_secs); + print_time(&tbuf[clen], delta_itime_usecs, delta_itime_secs); clen += strlen(&tbuf[clen]); sprintf(&tbuf[clen], ")"); clen += strlen(&tbuf[clen]); } sprintf(&tbuf[clen], "\n"); - - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } if (no_screen_refresh) printf("%s", tbuf); else @@ -722,26 +683,21 @@ void screen_update() sprintf(tbuf, "System Busy "); clen = strlen(tbuf); - print_time(&tbuf[clen], (unsigned long)(otime_usecs), otime_secs); + print_time(&tbuf[clen], otime_usecs, otime_secs); clen += strlen(&tbuf[clen]); if (delta_otime_usecs || delta_otime_secs) { - sprintf(&tbuf[clen], "("); + sprintf(&tbuf[clen], "("); clen += strlen(&tbuf[clen]); - print_time(&tbuf[clen], (unsigned long)(delta_otime_usecs), delta_otime_secs); + print_time(&tbuf[clen], delta_otime_usecs, delta_otime_secs); clen += strlen(&tbuf[clen]); sprintf(&tbuf[clen], ")"); clen += strlen(&tbuf[clen]); } sprintf(&tbuf[clen], "\n"); - - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } if (no_screen_refresh) printf("%s", tbuf); else @@ -752,14 +708,10 @@ void screen_update() sprintf(tbuf, "%-14.14s Usermode ", proc_name); clen = strlen(tbuf); - print_time(&tbuf[clen], (unsigned long)(utime_usecs), utime_secs); + print_time(&tbuf[clen], utime_usecs, utime_secs); clen += strlen(&tbuf[clen]); - sprintf(&tbuf[clen], "\n"); - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } + sprintf(&tbuf[clen], "\n"); if (no_screen_refresh) printf("%s", tbuf); else @@ -809,40 +761,34 @@ void screen_update() print_row(&sc_tab[n], 0); rows++; } - if (no_screen_refresh == 0) { - sprintf(tbuf, "\n"); + + sprintf(tbuf, "\n"); + if (no_screen_refresh == 0) { while (rows++ < max_rows) printw(tbuf); } else - printf("\n"); + printf("%s", tbuf); if (num_of_threads) { sprintf(tbuf, "\nCURRENT_TYPE LAST_PATHNAME_WAITED_FOR CUR_WAIT_TIME THRD# PRI\n"); - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } if (no_screen_refresh) printf("%s", tbuf); else printw(tbuf); sprintf(tbuf, "------------------------------------------------------------------------------\n"); - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } if (no_screen_refresh) printf("%s", tbuf); else printw(tbuf); } ti = &th_state[0]; - + for (i = 0; i < num_of_threads; i++, ti++) { struct entry *te; + char *p; uint64_t now; int secs, time_secs, time_usecs; @@ -861,37 +807,34 @@ void screen_update() sprintf(tbuf, "%-23.23s", sc_tab[te->code].name); else sprintf(tbuf, "%-23.23s", "vm_fault"); - } else + } else sprintf(tbuf, "%-23.23s", state_name[te->sc_state]); } else { te = &ti->th_entry[0]; sprintf(tbuf, "%-23.23s", state_name[te->sc_state]); } clen = strlen(tbuf); - + /* print the tail end of the pathname */ - plen = strlen(ti->pathname); - if (plen > 34) - plen -= 34; + p = (char *)ti->pathname; + + plen = strlen(p); + if (plen > 26) + plen -= 26; else plen = 0; - sprintf(&tbuf[clen], " %-34.34s ", &ti->pathname[plen]); + sprintf(&tbuf[clen], " %-26.26s ", &p[plen]); clen += strlen(&tbuf[clen]); - time_usecs = (unsigned long)(((double)now - te->otime) / divisor); + time_usecs = (((double)now - te->otime) / divisor); secs = time_usecs / 1000000; time_usecs -= secs * 1000000; time_secs = secs; print_time(&tbuf[clen], time_usecs, time_secs); clen += strlen(&tbuf[clen]); - sprintf(&tbuf[clen], " %2d %3d\n", i, ti->curpri); - - if (tbuf[COLS-2] != '\n') { - tbuf[COLS-1] = '\n'; - tbuf[COLS] = 0; - } + sprintf(&tbuf[clen], " %2d %3d\n", i, ti->curpri); if (no_screen_refresh) printf("%s", tbuf); else @@ -929,8 +872,9 @@ void screen_update() delta_otime_usecs = 0; } -void -reset_counters() { +static void +reset_counters(void) +{ int i; for (i = 0; i < (MAX_SC + msgcode_cnt) ; i++) { @@ -960,7 +904,7 @@ reset_counters() { total_faults = 0; scalls = 0; called = 0; - + utime_secs = 0; utime_usecs = 0; itime_secs = 0; @@ -973,10 +917,11 @@ reset_counters() { delta_otime_usecs = 0; } -void -sc_tab_init(char *codefile) { +static void +sc_tab_init(char *codefile) +{ int code; - int n, cnt; + int n; int msgcode_indx=0; char name[56]; FILE *fp; @@ -986,18 +931,14 @@ sc_tab_init(char *codefile) { exit(1); } - n = fscanf(fp, "%d\n", &cnt); - if (n != 1) - return; - /* Count Mach message MSG_ codes */ for (msgcode_cnt=0;;) { - n = fscanf(fp, "%x%s\n", &code, &name[0]); + n = fscanf(fp, "%x%55s\n", &code, &name[0]); if (n != 2) break; if (strncmp ("MSG_", &name[0], 4) == 0) msgcode_cnt++; - if (strcmp("USER_TEST", &name[0]) == 0) + if (strcmp("TRACE_LAST_WRAPPER", &name[0]) == 0) break; } @@ -1024,13 +965,8 @@ sc_tab_init(char *codefile) { rewind(fp); - n = fscanf(fp, "%d\n", &cnt); - - if (n != 1) - return; - for (;;) { - n = fscanf(fp, "%x%s\n", &code, &name[0]); + n = fscanf(fp, "%x%55s\n", &code, &name[0]); if (n != 2) break; @@ -1047,6 +983,10 @@ sc_tab_init(char *codefile) { mach_stkhandoff = code; continue; } + if (strcmp("MACH_IDLE", &name[0]) == 0) { + mach_idle = code; + continue; + } if (strcmp("VFS_LOOKUP", &name[0]) == 0) { vfs_lookup = code; continue; @@ -1080,7 +1020,7 @@ sc_tab_init(char *codefile) { strcpy(&sc_tab[n].name[0], &name[4]); continue; } - if (strcmp("USER_TEST", &name[0]) == 0) + if (strcmp("TRACE_LAST_WRAPPER", &name[0]) == 0) break; } strcpy(&faults[1].name[0], "zero_fill"); @@ -1089,8 +1029,8 @@ sc_tab_init(char *codefile) { strcpy(&faults[4].name[0], "cache_hit"); } -void -find_proc_names() +static void +find_proc_names(void) { size_t bufSize = 0; struct kinfo_proc *kp; @@ -1105,7 +1045,7 @@ find_proc_names() if((kp = (struct kinfo_proc *)malloc(bufSize)) == (struct kinfo_proc *)0) quit("can't allocate memory for proc buffer\n"); - + if (sysctl(mib, 4, kp, &bufSize, NULL, 0) < 0) quit("trace facility failure, KERN_PROC_ALL\n"); @@ -1113,7 +1053,9 @@ find_proc_names() kp_buffer = kp; } -struct th_info *find_thread(int thread) { +static struct th_info * +find_thread(uintptr_t thread) +{ struct th_info *ti; for (ti = th_state; ti < &th_state[MAX_THREADS]; ti++) { @@ -1123,10 +1065,9 @@ struct th_info *find_thread(int thread) { return ((struct th_info *)0); } - -int -cmp_wtime(struct sc_entry *s1, struct sc_entry *s2) { - +static int +cmp_wtime(struct sc_entry *s1, struct sc_entry *s2) +{ if (s1->wtime_secs < s2->wtime_secs) return 0; if (s1->wtime_secs > s2->wtime_secs) @@ -1136,9 +1077,9 @@ cmp_wtime(struct sc_entry *s1, struct sc_entry *s2) { return 1; } - -void -sort_scalls() { +static void +sort_scalls(void) +{ int i, n, k, cnt, secs; struct th_info *ti; struct sc_entry *se; @@ -1179,7 +1120,7 @@ sort_scalls() { if ((unsigned long)(((double)now - te->otime) / divisor) > 5000000) { ti->thread = 0; ti->vfslookup = 0; - ti->pathptr = (long *)0; + ti->pathptr = (long *)NULL; ti->pathname[0] = 0; num_of_threads--; } @@ -1220,8 +1161,8 @@ sort_scalls() { called++; } -void -set_enable(int val) +static void +set_enable(int val) { mib[0] = CTL_KERN; mib[1] = KERN_KDEBUG; @@ -1238,8 +1179,8 @@ set_enable(int val) trace_enabled = 0; } -void -set_numbufs(int nbufs) +static void +set_numbufs(int nbufs) { mib[0] = CTL_KERN; mib[1] = KERN_KDEBUG; @@ -1252,7 +1193,7 @@ set_numbufs(int nbufs) mib[0] = CTL_KERN; mib[1] = KERN_KDEBUG; - mib[2] = KERN_KDSETUP; + mib[2] = KERN_KDSETUP; mib[3] = 0; mib[4] = 0; mib[5] = 0; /* no flags */ @@ -1261,8 +1202,8 @@ set_numbufs(int nbufs) } -void -set_pidcheck(int pid, int on_off) +static void +set_pidcheck(int pid, int on_off) { kd_regtype kr; @@ -1277,7 +1218,7 @@ set_pidcheck(int pid, int on_off) mib[4] = 0; mib[5] = 0; if (sysctl(mib, 3, &kr, &needed, NULL, 0) < 0) { - if (on_off == 1) { + if (on_off == 1) { printf("pid %d does not exist\n", pid); set_remove(); exit(2); @@ -1291,7 +1232,7 @@ get_bufinfo(kbufinfo_t *val) needed = sizeof (*val); mib[0] = CTL_KERN; mib[1] = KERN_KDEBUG; - mib[2] = KERN_KDGETBUF; + mib[2] = KERN_KDGETBUF; mib[3] = 0; mib[4] = 0; mib[5] = 0; /* no flags */ @@ -1300,8 +1241,8 @@ get_bufinfo(kbufinfo_t *val) } -void -set_remove() +static void +set_remove(void) { extern int errno; @@ -1319,15 +1260,16 @@ set_remove() set_remove_flag = 0; if (errno == EBUSY) - quit("the trace facility is currently in use...\n fs_usage, sc_usage, and latency use this feature.\n\n"); + quit("The trace facility is currently in use...\n Note: fs_usage, sc_usage, and latency use this feature.\n\n"); else quit("trace facility failure, KERN_KDREMOVE\n"); } } -void -set_init() -{ kd_regtype kr; +static void +set_init(void) +{ + kd_regtype kr; kr.type = KDBG_RANGETYPE; kr.value1 = 0; @@ -1335,7 +1277,7 @@ set_init() needed = sizeof(kd_regtype); mib[0] = CTL_KERN; mib[1] = KERN_KDEBUG; - mib[2] = KERN_KDSETREG; + mib[2] = KERN_KDSETREG; mib[3] = 0; mib[4] = 0; mib[5] = 0; /* no flags */ @@ -1344,37 +1286,38 @@ set_init() mib[0] = CTL_KERN; mib[1] = KERN_KDEBUG; - mib[2] = KERN_KDSETUP; + mib[2] = KERN_KDSETUP; mib[3] = 0; mib[4] = 0; mib[5] = 0; /* no flags */ if (sysctl(mib, 3, NULL, &needed, NULL, 0) < 0) quit("trace facility failure, KERN_KDSETUP\n"); - } -void -sample_sc() +static void +sample_sc(void) { kd_buf *kd; - int i, count; + int i; + size_t count; int secs; - int find_msgcode(); - - /* Get kernel buffer information */ - get_bufinfo(&bufinfo); + #ifdef OLD_KDEBUG set_enable(0); #endif + get_bufinfo(&bufinfo); + needed = bufinfo.nkdbufs * sizeof(kd_buf); mib[0] = CTL_KERN; mib[1] = KERN_KDEBUG; - mib[2] = KERN_KDREADTR; + mib[2] = KERN_KDREADTR; mib[3] = 0; mib[4] = 0; - mib[5] = 0; /* no flags */ + mib[5] = 0; + if (sysctl(mib, 3, my_buffer, &needed, NULL, 0) < 0) - quit("trace facility failure, KERN_KDREADTR\n"); + quit("trace facility failure, KERN_KDREADTR\n"); + count = needed; if (bufinfo.flags & KDBG_WRAPPED) { @@ -1382,11 +1325,12 @@ sample_sc() th_state[i].depth = 0; th_state[i].thread = 0; th_state[i].vfslookup = 0; - th_state[i].pathptr = (long *)0; + th_state[i].pathptr = (long *)NULL; th_state[i].pathname[0] = 0; } num_of_threads = 0; } + #ifdef OLD_KDEBUG set_remove(); set_init(); @@ -1396,7 +1340,8 @@ sample_sc() kd = (kd_buf *)my_buffer; for (i = 0; i < count; i++) { - int debugid, baseid, thread; + int debugid, baseid; + uintptr_t thread; int type, code; uint64_t now; struct th_info *ti, *switched_out, *switched_in; @@ -1412,7 +1357,7 @@ sample_sc() switched_in = (struct th_info *)0; now = kd[i].timestamp & KDBG_TIMESTAMP_MASK; - + baseid = debugid & 0xffff0000; if (type == vfs_lookup) { @@ -1423,12 +1368,16 @@ sample_sc() if (ti->vfslookup == 1) { ti->vfslookup++; - memset(&ti->pathname[0], 0, (PATHLENGTH + 1)); - sargptr = (long *)&ti->pathname[0]; + sargptr = ti->pathname; *sargptr++ = kd[i].arg2; *sargptr++ = kd[i].arg3; *sargptr++ = kd[i].arg4; + /* + * NULL terminate the 'string' + */ + *sargptr = 0; + ti->pathptr = sargptr; } else if (ti->vfslookup > 1) { @@ -1441,7 +1390,7 @@ sample_sc() handle. */ - if ((long *)sargptr >= (long *)&ti->pathname[PATHLENGTH]) + if (sargptr >= &ti->pathname[NUMPARMS]) continue; /* @@ -1453,7 +1402,7 @@ sample_sc() if (debugid & DBG_FUNC_START) { - (long *)ti->pathptr = (long *)&ti->pathname[PATHLENGTH]; + ti->pathptr = &ti->pathname[NUMPARMS]; continue; } @@ -1461,16 +1410,61 @@ sample_sc() *sargptr++ = kd[i].arg2; *sargptr++ = kd[i].arg3; *sargptr++ = kd[i].arg4; + /* + * NULL terminate the 'string' + */ + *sargptr = 0; + ti->pathptr = sargptr; } continue; } else if (baseid == bsc_base) code = (debugid >> 2) & 0x1ff; - else if (baseid == msc_base) + else if (baseid == msc_base) code = 512 + ((debugid >> 2) & 0x1ff); + else if (type == mach_idle) { + if (debugid & DBG_FUNC_START) { + switched_out = find_thread(kd[i].arg5); + switched_in = 0; + } + else + if (debugid & DBG_FUNC_END) { + switched_in = find_thread(kd[i].arg5); + switched_out = 0; + } + + if (in_idle) { + itime_usecs += ((double)now - idle_start) / divisor; + delta_itime_usecs += ((double)now - idle_start) / divisor; + in_idle = 0; + } else if (in_other) { + otime_usecs += ((double)now - other_start) / divisor; + delta_otime_usecs += ((double)now - other_start) / divisor; + in_other = 0; + } + if ( !switched_in) { + /* + * not one of the target proc's threads + */ + if (now_collect_cpu_time) { + in_idle = 1; + idle_start = (double)now; + } + } + else { + if (now_collect_cpu_time) { + in_idle = 0; + in_other = 1; + other_start = (double)now; + } + } + if ( !switched_in && !switched_out) + continue; + + } else if (type == mach_sched || type == mach_stkhandoff) { - switched_out = find_thread(kd[i].arg5); + switched_out = find_thread(kd[i].arg5); switched_in = find_thread(kd[i].arg2); if (in_idle) { @@ -1484,17 +1478,12 @@ sample_sc() } if ( !switched_in) { /* - * not one of the target proc's threads - */ + * not one of the target proc's threads + */ if (now_collect_cpu_time) { - if (kd[i].arg4 == 0) { - in_idle = 1; - idle_start = (double)now; - } else { in_other = 1; - other_start = (double)now; + other_start = (double)now; } - } } if ( !switched_in && !switched_out) continue; @@ -1510,14 +1499,14 @@ sample_sc() if (switched_out || switched_in) { if (switched_out) { ti = switched_out; - ti->curpri = kd[i].arg3; + ti->curpri = (int)kd[i].arg3; if (ti->depth) { te = &ti->th_entry[ti->depth-1]; if (te->sc_state == KERNEL_MODE) te->ctime += (double)now - te->stime; - te->sc_state = WAITING; + te->sc_state = WAITING; ti->vfslookup = 1; @@ -1536,14 +1525,14 @@ sample_sc() } if (switched_in) { ti = switched_in; - ti->curpri = kd[i].arg4; + ti->curpri = (int)kd[i].arg4; if (ti->depth) { te = &ti->th_entry[ti->depth-1]; if (te->sc_state == WAITING) te->wtime += (double)now - te->stime; - te->sc_state = KERNEL_MODE; + te->sc_state = KERNEL_MODE; } else { te = &ti->th_entry[0]; @@ -1553,7 +1542,7 @@ sample_sc() te->otime = (double)now; } continue; - } + } if ((ti = find_thread(thread)) == (struct th_info *)0) { for (ti = &th_state[0]; ti < &th_state[MAX_THREADS]; ti++) { if (ti->thread == 0) { @@ -1600,7 +1589,7 @@ sample_sc() se = &sc_tab[code]; scalls++; } else { - se = &faults[kd[i].arg2]; + se = &faults[kd[i].arg4]; total_faults++; } if (se->total_count == 0) @@ -1633,7 +1622,7 @@ sample_sc() ti->depth--; if (ti->depth == 0) { - /* + /* * headed back to user mode * start the time accumulation */ @@ -1650,7 +1639,7 @@ sample_sc() ti->depth--; if (ti->depth == 0) { - /* + /* * headed back to user mode * start the time accumulation */ @@ -1689,95 +1678,95 @@ quit(char *s) if (trace_enabled) set_enable(0); - /* + /* This flag is turned off when calling quit() due to a set_remove() failure. */ if (set_remove_flag) set_remove(); + if (no_screen_refresh == 0) { + /* clear for new display */ + erase(); + move(0, 0); + refresh(); + endwin(); + } + printf("sc_usage: "); if (s) - printf("%s ", s); + printf("%s", s); exit(1); } -void getdivisor() +static void +getdivisor(void) { - mach_timebase_info_data_t info; + mach_timebase_info_data_t info; - (void) mach_timebase_info (&info); - - divisor = ( (double)info.denom / (double)info.numer) * 1000; + (void) mach_timebase_info (&info); + divisor = ( (double)info.denom / (double)info.numer) * 1000; } - int -argtopid(str) - char *str; +argtopid(char *str) { - char *cp; - int ret; + char *cp; + int ret; int i; if (!kp_buffer) - find_proc_names(); - - ret = (int)strtol(str, &cp, 10); - if (cp == str || *cp) { - /* Assume this is a command string and find first matching pid */ - for (i=0; i < kp_nentries; i++) { - if(kp_buffer[i].kp_proc.p_stat == 0) - continue; - else { - if(!strcmp(str, kp_buffer[i].kp_proc.p_comm)) - { - strncpy(proc_name, kp_buffer[i].kp_proc.p_comm, sizeof(proc_name)-1); - proc_name[sizeof(proc_name)-1] = '\0'; - return(kp_buffer[i].kp_proc.p_pid); - } - } + find_proc_names(); + + ret = (int)strtol(str, &cp, 10); + if (cp == str || *cp) { + /* Assume this is a command string and find first matching pid */ + for (i=0; i < kp_nentries; i++) { + if (kp_buffer[i].kp_proc.p_stat == 0) + continue; + else { + if (!strcmp(str, kp_buffer[i].kp_proc.p_comm)) { + strncpy(proc_name, + kp_buffer[i].kp_proc.p_comm, + sizeof(proc_name)-1); + proc_name[sizeof(proc_name)-1] = '\0'; + return (kp_buffer[i].kp_proc.p_pid); + } + } } - } - else - { - for (i=0; i < kp_nentries; i++) - { - if(kp_buffer[i].kp_proc.p_stat == 0) - continue; - else if (kp_buffer[i].kp_proc.p_pid == ret) { - strncpy(proc_name, kp_buffer[i].kp_proc.p_comm, sizeof(proc_name)-1); - proc_name[sizeof(proc_name)-1] = '\0'; - return(kp_buffer[i].kp_proc.p_pid); + } else { + for (i=0; i < kp_nentries; i++) { + if (kp_buffer[i].kp_proc.p_stat == 0) + continue; + else if (kp_buffer[i].kp_proc.p_pid == ret) { + strncpy(proc_name, + kp_buffer[i].kp_proc.p_comm, + sizeof(proc_name)-1); + proc_name[sizeof(proc_name)-1] = '\0'; + return (kp_buffer[i].kp_proc.p_pid); + } } - } - } - return(-1); + } + return (-1); } - /* Returns index into sc_tab for a mach msg entry */ -int +static int find_msgcode(int debugid) { + int indx; - int indx; - - for (indx=0; indx< msgcode_cnt; indx++) - { - if (msgcode_tab[indx] == ((debugid & 0x00ffffff) >>2)) - return (MAX_SC+indx); - } - return (0); + for (indx=0; indx< msgcode_cnt; indx++) { + if (msgcode_tab[indx] == ((debugid & 0x00ffffff) >>2)) + return (MAX_SC+indx); + } + return (0); } int -argtoi(flag, req, str, base) - int flag; - char *req, *str; - int base; +argtoi(int flag, char *req, char *str, int base) { char *cp; int ret; @@ -1787,4 +1776,3 @@ argtoi(flag, req, str, base) errx(EINVAL, "-%c flag requires a %s", flag, req); return (ret); } -