387 lines · 6.2 KB · Text
RawDownload
include("/sys/lib/acid/syscall"); // print various /proc filesdefn fd() {	rc("cat /proc/"+itoa(pid)+"/fd");} defn segment() {	rc("cat /proc/"+itoa(pid)+"/segment");} defn ns() {	rc("cat /proc/"+itoa(pid)+"/ns");} defn qid(qid) {	complex Qid qid;	return itoa(qid.path\X)+"."+itoa(qid.vers\X);} defn path(p) {	complex Path p;	if p != 0 then {		return *(p.s\s);	} else		return "<null>";} // print Image cache contents// requires include("/sys/src/9/xxx/segment.acid")IHASHSIZE = 64;defn imagecacheline(h) {	while h != 0 do {		complex Image h;		print (h\X, " ", qid(h.qid), " type ", h.type\D, " ref ", h.ref, " next ", h.next\X, " ", path(h.c.path), "\n");		h = h.hash;	}} defn imagecache() {	local i; 	i=0; loop 1,IHASHSIZE do {		imagecacheline(imagealloc.free[i]);		i = i+1;	}} // dump channelsdefn chan(c) {	local d, q; 	c = (Chan)c;	d=(Dev)(*(devtab+4*c.type));	q=c.qid;	print("chan(", c\X, "): ref=", c.ref\D, " #", d.dc\r, c.dev\D, " (", q.path, " ", q.vers\D, " ", q.type\X, ")");	print(" fid=", c.fid\D, " iounit=", c.iounit\D);	if c.ref != 0 then {		print(" ", path(c.path), " mchan=", c.mchan\X);		if c.mchan != 0 then {			print(" ", path(c.mchan.path));		}	}	print("\n");} defn chans() {	local c; 	c = (Chan)chanalloc.list;	while c != 0 do {		if c.ref != 0 then			chan(c);		c=(Chan)c.link;	}} defn nchans() {	local c, n;		n = 0;	c = (Chan)chanalloc.list;	while c != 0 do {		if c.ref != 0 then			n++;		c = (Chan)c.link;	}	return n;} defn activechanlist() {	local l, n;		l = {};	c = (Chan)chanalloc.list;	while c != 0 do {		if c.ref != 0 then			l = append l,c;		c = (Chan)c.link;	}	return l;} defn difflist(a, b) {	local l, x;		l = {};	while a != {} do {		x = head a;		if match(x, b) == -1 then			l = append l, x;		a = tail a;	}	return l;} _active_chan_list = {};defn newchans() {	local l, new;		l = activechanlist();	if _active_chan_list != {} then		newerchans(_active_chan_list);	_active_chan_list = l;} defn newerchans(oldlist){	local new;		new = difflist(activechanlist(), oldlist);	while new != {} do {		chan(head new);		new = tail new;	}} // look for channels that refer to themselvesdefn badchans() {	local bad, c, i, len, mtpt, p;		c = (Chan)chanalloc.list;	while c != 0 do {		if c.ref != 0 then {			bad = "";			p = (Path)c.path;			if p != 0 then {				path(p);				mtpt = p.mtpt;				len = p.mlen;				i=0; loop 1,len do {					if mtpt[i] == c then						bad = bad+" mtpt self-ref";					i = i+1;				}			}			if bad != "" then				print("chan(", c\X, "):", bad, "\n");		}		c = (Chan)c.link;	}} // manipulate processesdefn proctab(x) {	return procalloc.arena+sizeofProc*x;} defn proc(p) {	complex Proc p;	local s, i; 	if p.state != 0 && p.pid != 0 && p.text != 0 then {	// 0 is Dead		s = p.psstate;		if s == 0 then {			s = "kproc";		} else {			s = *(s\s);		}		print(p\X, " ", p.pid, ": ", *(p.text\s), " ", *(p.user\s), " pc ", p.pc\X, " ", s, " (", *(statename[p.state]\s), ") ut ", p.time[0]\D, " st ", p.time[1]\D, " qpc ", p.qpc\X, "\n");	}} defn procenv(p) {	complex Proc p;	local e, v; 	e = p.egrp;	complex Egrp e;	v = e.ent;	while v != 0 do {		complex Evalue v;		print(*(v.name\s), "=");		printstringn(v.value, v.len);		print("\n");		v = v.link;	}} KSTACK=4096; defn procstksize(p) {	complex Proc p;	local top, sp; 	if p.state != 0 then {	// 0 is Dead		top = p.kstack+KSTACK;		sp = *p.sched;		print(top-sp\D, "\n");	}} defn procstk(p) {	complex Proc p;	local l; 	if p.state != 0 then {	// 0 is Dead		l = p.sched;		if objtype=="386" then			_stk(gotolabel, *l, linkreg(0), 0);		else			_stk(*(l+4), *l, linkreg(0), 0);	}} defn procs() {	local i; 	i=0; loop 1,conf.nproc do {		proc(proctab(i));		i = i+1;	}} defn stacks() {	local i, p; 	i=0; loop 1,conf.nproc do {		p = (Proc)proctab(i);		if p.state != 0 then {			print("=========================================================\n");			proc(p);			procstk(p);		}		i = i+1;	}} defn stacksizes() {	local i; 	i=0; loop 1,conf.nproc do {		procstksize(proctab(i));		i = i+1;	}} // segment-relateddefn procsegs(p) {	complex Proc p;	local i; 	i=0; loop 1,NSEG do {		psegment(p.seg[i]);		i = i+1;	}} segtypes = { "text", "data", "bss", "stack", "shared", "physical", "shdata", "map" };defn psegment(s) {	complex Segment s; 	if s != 0 then {		print(s\X, " ", segtypes[s.type&SG_TYPE], " ", s.base\X, "-", s.top\X, " image ", s.image\X, "\n");	}} // find physical address for an address in a given processdefn procaddr(p, a) {	complex Proc p;	local i, s, r; 	r = 0;	i=0; loop 1,NSEG do {		s = p.seg[i];		if s != 0 then {			complex Segment s;			if s.base <= a && a < s.top then {				r = segaddr(s, a);			}		}		i = i+1;	}	return r;} // find an address in a given segmentdefn segaddr(s, a) {	complex Segment s;	local pte, pg; 	a = a - s.base;	if s.map == 0 || s.mapsize < a/PTEMAPMEM then {		return 0;	} 	pte = s.map[a/PTEMAPMEM];	if pte == 0 then {		return 0;	} 	complex Pte pte;	pg = pte.pages[(a%PTEMAPMEM)/BY2PG];	if pg == 0 then {		return 0;	} 	if pg & 1 then {	// swapped out, return disk address		return pg&~1;	} 	complex Page pg;	return (KZERO|(pg.pa+(a%BY2PG)))\X;} defn kzero() {	return main - (main & 0x0FFFFFFF);} // PC onlyPTEMAPMEM = (1024*1024);BY2PG = 4096;PTEPERTAB = (PTEMAPMEM/BY2PG);defn up() {	local mach; 	MACHADDR = KZERO+0x15000;	mach = MACHADDR;	complex Mach mach;	return mach.externup;} defn intrcount() {	local p, pp, t, i, j; 	p = intrtimes;	i=0;	loop 1,256 do {		pp = p[i];		i=i+1;		if pp != 0 then {			j=0;			t=0;			loop 1,1000 do {				t = t+pp[j];				j=j+1;			}			print(itoa(i, "%5d"), " ", itoa(t, "%11d"), "\n");		}	}} print("/sys/lib/acid/kernel"); defn needacid(s){	print("\trc(\"cd /sys/src/9/", kdir, "; mk ", s, ".acid\")\n");	print("\tinclude(\"/sys/src/9/", kdir, "/", s, ".acid\")\n");} defn kinit() {if (map()[2]) != {} then {	// map has more than two elements -> active proc	kdir = "unknown";	KZERO = kzero();		if objtype == "386" then {		map({"*data", KZERO, 0xffffffff, KZERO});		kdir="pc";	}	if (objtype == "mips" || objtype == "mips2") then {		kdir = "ch";	}	if objtype == "alpha" then {		map({"*data", KZERO, 0xffffffff, KZERO});		kdir = "alpha";	}	needacid("proc");}}