Messages in this thread | | | From | Rick Hohensee <> | Subject | simple kernel state monitor | Date | Thu, 22 Jul 1999 11:28:50 -0400 (EDT) |
| |
This little utility, "shakin", weighs in at 4902 bytes dynamically linked to libc5.4.46 and puts about a 0.1 load average on a 486 with no optimization. Typical output on a quiescent box looks like this....
ctrl&d to terminate 1987404 1e534c 15479 15590 d event 1987420 1e535c 1450f7 1452ef d jiffies 1989472 1e5b60 3fc2 3fc4 d kstat 1991300 1e6284 11 13 D tv2 1991560 1e6388 f8 f0 D tv1 1992588 1e678c 1450f8 1452f0 D timer_jiffies 1992616 1e67a8 35 31 D count.520 1993020 1e693c 347a 347f d pps_valid 2001200 1e8930 c008a780 c008a980 D dentry_unused 2043564 1f2eac 1a0754 10732 D old.485 2043566 1f2eae 1e001a 1a0001 D oldx.486 2043568 1f2eb0 1e 1a D oldy.487 2043836 1f2fbc 0 a d sel_cons 2043888 1f2ff0 1000000 0 D k_down 2043936 1f3020 8 0 d shift_state dec.-address-hex. previous current type symbol_name
ctrl&d to terminate
################################################################ /* cLIeNUX shakin 19990717
RIGHTS Copyright 1999 Rick Hohensee (Richard Allen Hohensee) shakin is released for redistribution only as part of an intact entire cLIeNUX Core, or by itself on the unit of physical distribution medium, or alone as an electronic message. In particular, shakin is not released for bundling with any other Linux-based or other operating system distributions, packages or updates, neither on physically distributed static storage media nor on publicly accessible repositories. Modifications to shakin by other authors may be licensed and redistributed at the pleasure of said authors as patches containing only the modifications.
USAGE shakin /path/to/running_kernel's/System.map [ > logfile]
DESCRIPTION shakin shows a periodic snapshot of recently changed kernel variables based on a System.map (or subset) and /dev/mem, making the Cheap Quick Dirty assumption that the world of kernel data symbols consists of nothing but single ints. shakin is sloppy, but informative. If shakin keeps showing the same huge wad of info your System.map is probably not the one for the running kernel.
BUGS see below
*/
/* ## system header includes */ # include <stdio.h> # include <sys/types.h> # include <sys/stat.h> # include <fcntl.h> # include <unistd.h> # include <stdlib.h> # include <string.h>
/* ## declarations, allocations */ FILE * memmapfile; char linebuffer[80];
#define ARRAYMAX 2000
int addy[ARRAYMAX], current[ARRAYMAX], previous[ARRAYMAX]; char Type[ARRAYMAX]; char * address, *type, *symbolname ; int i, line, record, records; int * swap; FILE * dev_mem; char name[ARRAYMAX][48]; long file_position;
/* ## assignments */ char whitespace[] = " \t\n";
/* ### subroutines */
void help() { printf("\n\n\nUSAGE: shakin mapfile\n\n" "mapfile wants to be (a subset of) System.map for the RUNNING kernel.\n " " 19990718\n"); }
void fuzzysleep() /* randomize the period a bit in hopes of avoiding "aliasing" anomalies. Gee I LOVE that kinda talk! */ { sleep(5); usleep(random() & 0xff); }
int peek(file_position) /* fseeking grab int from fileoid */ { long offset ; offset = fseek( dev_mem, file_position , SEEK_SET ); if ( offset < 0 ) { printf("The fseek failed. Some devices won't lseek, " "and fseek is 31 bits,\n 2 gig range.\n"); return -1; } else {return( getw(dev_mem ) ); } }
/* #### main */
void main (int argc,char *argv[]) /* MAIN MAIN MAIN MAIN */ { if ( argc != 2 ) { help(); return ; }
/* open System.map subset and /dev/mem */ memmapfile = fopen(argv[1], "r" ) ; if ( memmapfile < 0 ) { help(); printf("failed to open file %s, error %d\n", argv[1], errno); return; }
dev_mem = fopen("/dev/mem", "r"); if ( dev_mem < 0 ) { printf("failure to open special file /dev/mem. mknod?\n"); return; }
/* fill arrays with names, "previous" values, and addresses for hits */ line = 0; record = 0; while ( fgets( linebuffer, 80 , memmapfile) ) /* get line */ { line ++; /* Got milk? */ address = strtok(linebuffer , whitespace); address = ( address + (strlen(address) - 6)); /* cut address to 6 chars with some pointer arithmatic. */ type = strtok(0 , whitespace); symbolname = strtok(0 , whitespace);
if ( ! strcmp(type, "D") || ! strcmp(type, "d") ) { record ++; if (strcmp(type, "D")) { Type[record]='D'; } else { Type[record]='d'; } addy[record] = strtol(address,0,16); previous[record] = peek( (long) addy[record]); printf("%s\n", strcpy(name[record], symbolname) ); /* still two Kurds with one bone using side-effects*/ } if ( record > ARRAYMAX ) { printf("the maximum # of records shakin can handle " "is %d, which has been exceeded.\n Trim your " "System.map, or change ARRAYMAX in the\n shakin " " source and recompile.\n", ARRAYMAX ); return; }
} /* end init while loop */ records = record ; printf("\n%d records \n", records); printf("\nctrl&d to terminate\n"); fuzzysleep();
/* on-going "current" loop */ while ( 1 ) { for (i = 0; i < records ; i ++) { current[i] = peek( (long) addy[i]); if ( current[i] != previous[i] ) printf("%8d %8x %10x %10x %c %s\n", addy[i], addy[i], previous[i], current[i], Type[i], name[i]); } printf(" dec.-address-hex. previous " " current type symbol_name\n"); memmove(previous, current, records << 2 ); printf("\nctrl&d to terminate\n"); fuzzysleep(); } } ######################################################################### Rick Hohensee
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |