467 lines · 7.6 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 contentsIHASHSIZE = 64; defn imagecacheline(h) {	local d, p, q; 	while h != 0 do {		complex Image h; 		d=(Dev)devtab[h.type];		p = "*closed*";		if h.c != 0 then			p = path(h.c.path);		q = h.qid;		print (h\A, " ref=", h.ref, " pgref=", h.pgref, "\t#", d.dc\r, h.dev\D, " (",			q.path, " ", q.vers\D, " ", q.type\X, ") ", p, "\n");		h = h.hash;	}} defn imagecache() {	local i; 	i=0; loop 1,IHASHSIZE do {		imagecacheline(imagealloc.hash[i]);		i = i+1;	}} // dump channelsdefn chan(c) {	local d, q; 	c = (Chan)c;	d= (Dev)devtab[c.type];	q=c.qid;	print("chan(", c\A, "): 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\A);		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 findchan(dev,type,path) {	local c; 	c = (Chan)chanalloc.list;	while c != 0 do {		if c.ref != 0 then {			if c.dev == dev && c.type == type && c.qid.path == path then				return c;		}		c=(Chan)c.link;	}	return 0;} 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\A, "):", bad, "\n");		}		c = (Chan)c.link;	}} NHASH=128;defn mntcache() {	local i, m, c; 	i=0; loop 1,NHASH do {		m = cache.hash[i];		while m != 0 do {			complex Mntcache m;			print(m\A, " dev ", m.dev\D, " type ", m.type, " qid (", 				m.qid.path, " ", m.qid.vers\D, ")\n");			c = findchan(m.dev, m.type, m.qid.path);			if c != 0 then {				print("	");				chan(c);			}			m = m.hash;		}		i = i+1;	}} // manipulate processesdefn proctab(x) {	return procalloc.tab[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\A, " ", p.pid, ": ", *(p.text\s), " ", *(p.user\s), " pc ", p.pc, " ", s, " (", *(statename[p.state]\s), ") ut ", p.time[0]\D, " st ", p.time[1]\D, " qpc ", p.qpc, "\n");	}} defn procenv(p) {	complex Proc p;	local i, e, v; 	e = p.egrp;	complex Egrp e;	i=0; loop 1,e.nent do {		v = e.ent + i;		i = i+sizeofEvalue;		complex Evalue v;		print(*(v.name\s), "=");		printstringn(v.value, v.len);		print("\n");	}}BY2PG=4096;KSTACK=4096;if objtype=="amd64" then {	KSTACK=16*1024;}if objtype=="arm64" then {	BY2PG=65536;	KSTACK=8*1024;} 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, n; 	if p.state != 0 then {	// 0 is Dead		if p.mach == 0 then {			l = p.sched;		} else {			n = p.nerrlab;			if n == 0 then {				return 0;			}			l = p.errlab + (n-1)*sizeofLabel;		}		complex Label l;		if objtype=="386" || objtype=="amd64" then			_stk(gotolabel, l.sp, linkreg(0), 0);		else			_stk(l.pc, l.sp, 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\A, " ", segtypes[s.type&SG_TYPE], " ", s.base, "-", s.top, " image ", s.image, "\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)))\A;} defn kzero() {	return main - (main & 0x0FFFFFFF);} PTEMAPMEM = (1024*1024);PTEPERTAB = (PTEMAPMEM/BY2PG);defn up() {	if objtype == "386" then {		local mach; 		MACHADDR = KZERO+0x15000;		mach = MACHADDR;		complex Mach mach;		return mach.externup;	}	if objtype == "amd64" then {		local proc; 		proc = *R14;		complex Proc proc;		return proc;	}	if objtype == "arm64" then {		local proc; 		proc = *R26;		complex Proc proc;		return proc;	}	print("up() not implemented for", objtype, "\n");	return -1;} defn intrcount() {	local p, t, i, j; 	p = intrtimes\X;	i=0; loop 1,256 do {		t=0;		j=0; loop 1,20 do {			t = t+*p++;			j=j+1;		}		if t != 0 then {			print(itoa(i, "%5d"), " ", itoa(t, "%11d"), "\n");		}		i=i+1;	}} 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 == "amd64" then {		map({"*data", KZERO, 0xffffffffffffffff, KZERO});		kdir="pc64";	}	if (objtype == "mips" || objtype == "mips2") then {		kdir = "ch";	}	if objtype == "arm" then {		kdir = "bcm";	}	if objtype == "arm64" then {		kdir = "bcm64";	}	needacid("proc");	needacid("chan");	needacid("segment");	needacid("cache");}}