Browse Source

Plan 9 from Bell Labs 2007-10-04

David du Colombier 13 years ago
parent
commit
3839123d49

+ 10 - 11
dist/replica/_plan9.db

@@ -258,7 +258,7 @@
 386/bin/games/juggle - 775 sys sys 1179372089 125804
 386/bin/games/jukebox - 775 sys sys 1105589128 264821
 386/bin/games/jukefs - 775 sys sys 1105589129 165320
-386/bin/games/mahjongg - 775 sys sys 1179372089 165271
+386/bin/games/mahjongg - 775 sys sys 1191381911 165242
 386/bin/games/memo - 775 sys sys 1179372089 156656
 386/bin/games/playlistfs - 775 sys sys 1105589129 148484
 386/bin/games/sokoban - 775 sys sys 1179372090 165514
@@ -409,7 +409,7 @@
 386/bin/snap - 775 sys sys 1188530194 316182
 386/bin/snapfs - 775 sys sys 1188530202 390401
 386/bin/sniffer - 775 sys sys 1038443185 99028
-386/bin/snoopy - 775 sys sys 1187639427 190560
+386/bin/snoopy - 775 sys sys 1191381914 194808
 386/bin/sort - 775 sys sys 1178568303 81057
 386/bin/spin - 775 sys sys 1186543935 769291
 386/bin/split - 775 sys sys 1181507270 75811
@@ -509,7 +509,7 @@
 386/bin/venti/ro - 775 sys sys 1191273722 161694
 386/bin/venti/sync - 775 sys sys 1190716753 153672
 386/bin/venti/syncindex - 775 sys sys 1191273727 267127
-386/bin/venti/venti - 775 sys sys 1191273735 459037
+386/bin/venti/venti - 775 sys sys 1191442426 705674
 386/bin/venti/verifyarena - 775 sys sys 1191273738 166940
 386/bin/venti/wrarena - 775 sys sys 1191273743 284205
 386/bin/venti/write - 775 sys sys 1190716792 155215
@@ -8244,7 +8244,7 @@ sys/src/9/port/mkextract - 775 sys sys 1039753334 435
 sys/src/9/port/mkfile - 664 sys sys 1063856960 350
 sys/src/9/port/mkfilelist - 775 sys sys 1124890427 266
 sys/src/9/port/mkroot - 775 sys sys 1039753334 235
-sys/src/9/port/mkrootall - 775 sys sys 1055954696 386
+sys/src/9/port/mkrootall - 775 sys sys 1191430540 453
 sys/src/9/port/mkrootc - 775 sys sys 1055954695 717
 sys/src/9/port/mksystab - 664 sys sys 1014931176 783
 sys/src/9/port/mul64fract.c - 664 sys sys 1071671674 867
@@ -9150,7 +9150,7 @@ sys/src/boot/pc/dosboot.c - 664 sys sys 1097716791 11240
 sys/src/boot/pc/dosfs.h - 664 sys sys 1032215924 1467
 sys/src/boot/pc/eoffs - 664 sys sys 1015007950 0
 sys/src/boot/pc/error.h - 664 sys sys 1015007950 3081
-sys/src/boot/pc/ether.c - 664 sys sys 1178926685 5380
+sys/src/boot/pc/ether.c - 664 sys sys 1191446356 5411
 sys/src/boot/pc/ether2000.c - 664 sys sys 1015007950 2609
 sys/src/boot/pc/ether2114x.c - 664 sys sys 1144977462 38028
 sys/src/boot/pc/ether589.c - 664 sys sys 1144961189 4624
@@ -9170,7 +9170,7 @@ sys/src/boot/pc/etherelnk3x.c - 664 sys sys 1015007951 24989
 sys/src/boot/pc/etherga620.c - 664 sys sys 1175289484 27168
 sys/src/boot/pc/etherga620fw.h - 664 sys sys 1174080072 222295
 sys/src/boot/pc/etherif.h - 664 sys sys 1174077279 1338
-sys/src/boot/pc/etherigbe.c - 664 sys sys 1181675291 41434
+sys/src/boot/pc/etherigbe.c - 664 sys sys 1191446222 41284
 sys/src/boot/pc/ethermii.c - 664 sys sys 1103641771 4413
 sys/src/boot/pc/ethermii.h - 664 sys sys 1071175087 3259
 sys/src/boot/pc/etherrhine.c - 664 sys sys 1144961190 12383
@@ -14340,10 +14340,11 @@ sys/src/cmd/venti/srv/fmtarenas.c - 664 sys sys 1177189436 2702
 sys/src/cmd/venti/srv/fmtbloom.c - 664 sys sys 1142736352 2293
 sys/src/cmd/venti/srv/fmtindex.c - 664 sys sys 1178160304 2599
 sys/src/cmd/venti/srv/fmtisect.c - 664 sys sys 1177189436 1454
-sys/src/cmd/venti/srv/fns.h - 664 sys sys 1191257308 9208
+sys/src/cmd/venti/srv/fns.h - 664 sys sys 1191430752 9231
 sys/src/cmd/venti/srv/graph.c - 664 sys sys 1177189436 4190
 sys/src/cmd/venti/srv/hdisk.c - 664 sys sys 1191257294 16482
-sys/src/cmd/venti/srv/httpd.c - 664 sys sys 1191257304 22869
+sys/src/cmd/venti/srv/hproc.c - 664 sys sys 1191430754 10333
+sys/src/cmd/venti/srv/httpd.c - 664 sys sys 1191430753 22897
 sys/src/cmd/venti/srv/icache.c - 664 sys sys 1191257303 10676
 sys/src/cmd/venti/srv/icachewrite.c - 664 sys sys 1191257310 7528
 sys/src/cmd/venti/srv/ifile.c - 664 sys sys 1189307036 2592
@@ -14352,7 +14353,7 @@ sys/src/cmd/venti/srv/lump.c - 664 sys sys 1191257295 4947
 sys/src/cmd/venti/srv/lumpcache.c - 664 sys sys 1177189437 8811
 sys/src/cmd/venti/srv/lumpqueue.c - 664 sys sys 1142736354 2722
 sys/src/cmd/venti/srv/mirrorarenas.c - 664 sys sys 1191257291 10802
-sys/src/cmd/venti/srv/mkfile - 664 sys sys 1189304068 1243
+sys/src/cmd/venti/srv/mkfile - 664 sys sys 1191430751 1300
 sys/src/cmd/venti/srv/part.c - 664 sys sys 1191217317 4500
 sys/src/cmd/venti/srv/png.c - 664 sys sys 1142736354 3729
 sys/src/cmd/venti/srv/printarena.c - 664 sys sys 1177189438 2673
@@ -15734,5 +15735,3 @@ usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
-386/bin/games/mahjongg - 775 sys sys 1191381911 165242
-386/bin/snoopy - 775 sys sys 1191381914 194808

+ 8 - 7
dist/replica/plan9.db

@@ -509,7 +509,7 @@
 386/bin/venti/ro - 775 sys sys 1191273722 161694
 386/bin/venti/sync - 775 sys sys 1190716753 153672
 386/bin/venti/syncindex - 775 sys sys 1191273727 267127
-386/bin/venti/venti - 775 sys sys 1191273735 459037
+386/bin/venti/venti - 775 sys sys 1191442426 705674
 386/bin/venti/verifyarena - 775 sys sys 1191273738 166940
 386/bin/venti/wrarena - 775 sys sys 1191273743 284205
 386/bin/venti/write - 775 sys sys 1190716792 155215
@@ -8244,7 +8244,7 @@ sys/src/9/port/mkextract - 775 sys sys 1039753334 435
 sys/src/9/port/mkfile - 664 sys sys 1063856960 350
 sys/src/9/port/mkfilelist - 775 sys sys 1124890427 266
 sys/src/9/port/mkroot - 775 sys sys 1039753334 235
-sys/src/9/port/mkrootall - 775 sys sys 1055954696 386
+sys/src/9/port/mkrootall - 775 sys sys 1191430540 453
 sys/src/9/port/mkrootc - 775 sys sys 1055954695 717
 sys/src/9/port/mksystab - 664 sys sys 1014931176 783
 sys/src/9/port/mul64fract.c - 664 sys sys 1071671674 867
@@ -9150,7 +9150,7 @@ sys/src/boot/pc/dosboot.c - 664 sys sys 1097716791 11240
 sys/src/boot/pc/dosfs.h - 664 sys sys 1032215924 1467
 sys/src/boot/pc/eoffs - 664 sys sys 1015007950 0
 sys/src/boot/pc/error.h - 664 sys sys 1015007950 3081
-sys/src/boot/pc/ether.c - 664 sys sys 1178926685 5380
+sys/src/boot/pc/ether.c - 664 sys sys 1191446356 5411
 sys/src/boot/pc/ether2000.c - 664 sys sys 1015007950 2609
 sys/src/boot/pc/ether2114x.c - 664 sys sys 1144977462 38028
 sys/src/boot/pc/ether589.c - 664 sys sys 1144961189 4624
@@ -9170,7 +9170,7 @@ sys/src/boot/pc/etherelnk3x.c - 664 sys sys 1015007951 24989
 sys/src/boot/pc/etherga620.c - 664 sys sys 1175289484 27168
 sys/src/boot/pc/etherga620fw.h - 664 sys sys 1174080072 222295
 sys/src/boot/pc/etherif.h - 664 sys sys 1174077279 1338
-sys/src/boot/pc/etherigbe.c - 664 sys sys 1181675291 41434
+sys/src/boot/pc/etherigbe.c - 664 sys sys 1191446222 41284
 sys/src/boot/pc/ethermii.c - 664 sys sys 1103641771 4413
 sys/src/boot/pc/ethermii.h - 664 sys sys 1071175087 3259
 sys/src/boot/pc/etherrhine.c - 664 sys sys 1144961190 12383
@@ -14340,10 +14340,11 @@ sys/src/cmd/venti/srv/fmtarenas.c - 664 sys sys 1177189436 2702
 sys/src/cmd/venti/srv/fmtbloom.c - 664 sys sys 1142736352 2293
 sys/src/cmd/venti/srv/fmtindex.c - 664 sys sys 1178160304 2599
 sys/src/cmd/venti/srv/fmtisect.c - 664 sys sys 1177189436 1454
-sys/src/cmd/venti/srv/fns.h - 664 sys sys 1191257308 9208
+sys/src/cmd/venti/srv/fns.h - 664 sys sys 1191430752 9231
 sys/src/cmd/venti/srv/graph.c - 664 sys sys 1177189436 4190
 sys/src/cmd/venti/srv/hdisk.c - 664 sys sys 1191257294 16482
-sys/src/cmd/venti/srv/httpd.c - 664 sys sys 1191257304 22869
+sys/src/cmd/venti/srv/hproc.c - 664 sys sys 1191430754 10333
+sys/src/cmd/venti/srv/httpd.c - 664 sys sys 1191430753 22897
 sys/src/cmd/venti/srv/icache.c - 664 sys sys 1191257303 10676
 sys/src/cmd/venti/srv/icachewrite.c - 664 sys sys 1191257310 7528
 sys/src/cmd/venti/srv/ifile.c - 664 sys sys 1189307036 2592
@@ -14352,7 +14353,7 @@ sys/src/cmd/venti/srv/lump.c - 664 sys sys 1191257295 4947
 sys/src/cmd/venti/srv/lumpcache.c - 664 sys sys 1177189437 8811
 sys/src/cmd/venti/srv/lumpqueue.c - 664 sys sys 1142736354 2722
 sys/src/cmd/venti/srv/mirrorarenas.c - 664 sys sys 1191257291 10802
-sys/src/cmd/venti/srv/mkfile - 664 sys sys 1189304068 1243
+sys/src/cmd/venti/srv/mkfile - 664 sys sys 1191430751 1300
 sys/src/cmd/venti/srv/part.c - 664 sys sys 1191217317 4500
 sys/src/cmd/venti/srv/png.c - 664 sys sys 1142736354 3729
 sys/src/cmd/venti/srv/printarena.c - 664 sys sys 1177189438 2673

+ 8 - 0
dist/replica/plan9.log

@@ -52993,3 +52993,11 @@
 1191360604 0 c sys/man/2/pool - 664 sys sys 1191360187 8577
 1191382203 0 c 386/bin/games/mahjongg - 775 sys sys 1191381911 165242
 1191382203 1 c 386/bin/snoopy - 775 sys sys 1191381914 194808
+1191430805 0 c sys/src/9/port/mkrootall - 775 sys sys 1191430540 453
+1191430805 1 c sys/src/cmd/venti/srv/fns.h - 664 sys sys 1191430752 9231
+1191430805 2 a sys/src/cmd/venti/srv/hproc.c - 664 sys sys 1191430754 10333
+1191430805 3 c sys/src/cmd/venti/srv/httpd.c - 664 sys sys 1191430753 22897
+1191430805 4 c sys/src/cmd/venti/srv/mkfile - 664 sys sys 1191430751 1300
+1191443404 0 c 386/bin/venti/venti - 775 sys sys 1191442426 705674
+1191447003 0 c sys/src/boot/pc/ether.c - 664 sys sys 1191446356 5411
+1191447003 1 c sys/src/boot/pc/etherigbe.c - 664 sys sys 1191446222 41284

+ 2 - 1
sys/src/9/port/mkrootall

@@ -23,7 +23,8 @@ while(! ~ $#* 0){
 	allcname=($allcname $cname)
 	cp $file $tmp
 	t=`{file $tmp}
-	if(~ $"t *executable*)
+	# do not strip venti - it uses its own symbols
+	if(~ $"t *executable* && ! ~ $name venti)
 		strip $tmp
 	aux/data2s $cname < $tmp
 }

+ 1 - 0
sys/src/boot/pc/ether.c

@@ -38,6 +38,7 @@ struct {
 	{ "i82557", i82557reset, 0, },
 	{ "igbe",  igbepnp, 0, },
 	{ "i82563",i82563pnp, 0, },
+	{ "igbepcie",i82563pnp, 0, },
 	{ "elnk3", elnk3reset, 0, },
 	{ "3C509", elnk3reset, 0, },
 	{ "3C575", elnk3reset, 0, },

+ 0 - 8
sys/src/boot/pc/etherigbe.c

@@ -46,7 +46,6 @@ enum {
 	i82541gi2  = (0x1077<<16)|0x8086,
 	i82546gb   = (0x1079<<16)|0x8086,
 	i82541pi   = (0x107c<<16)|0x8086,
-	i82573pl   = (0x109a<<16)|0x8086,
 };
 
 /* compatibility with cpu kernels */
@@ -857,7 +856,6 @@ igbeinit(Ether* edev)
 	case i82546gb:
 	case i82546eb:
 	case i82547gi:
-	case i82573pl:
 		csr32w(ctlr, Radv, 64);
 		break;
 	}
@@ -901,7 +899,6 @@ igbeinit(Ether* edev)
 	case i82546gb:
 	case i82546eb:
 	case i82547gi:
-	case i82573pl:
 		r = 8;
 		break;
 	}
@@ -941,7 +938,6 @@ igbeinit(Ether* edev)
 	case i82546eb:
 	case i82541gi:
 	case i82541gi2:
-	case i82573pl:
 		r = csr32r(ctlr, Txdctl);
 		r &= ~WthreshMASK;
 		r |= Gran|(4<<WthreshSHIFT);
@@ -1174,7 +1170,6 @@ igbemii(Ctlr* ctlr)
 	case i82541pi:
 	case i82546gb:
 	case i82546eb:
-	case i82573pl:
 		ctrl &= ~(Frcdplx|Frcspd);
 		csr32w(ctlr, Ctrl, ctrl);
 		ctlr->mii->mir = igbemiimir;
@@ -1344,7 +1339,6 @@ at93c46r(Ctlr* ctlr)
 	case i82547gi:
 	case i82546gb:
 	case i82546eb:
-//	case i82573pl:
 		areq = 1;
 		csr32w(ctlr, Eecd, eecd|Areq);
 		for(i = 0; i < 1000; i++){
@@ -1427,7 +1421,6 @@ detach(Ctlr *ctlr)
 	case i82547gi:
 	case i82546gb:
 	case i82546eb:
-	case i82573pl:
 		r = csr32r(ctlr, Manc);
 		r &= ~Arpen;
 		csr32w(ctlr, Manc, r);
@@ -1622,7 +1615,6 @@ igbepci(void)
 		case i82541pi:
 		case i82546gb:
 		case i82546eb:
-		case i82573pl:
 			break;
 		}
 

+ 1 - 0
sys/src/cmd/venti/srv/fns.h

@@ -59,6 +59,7 @@ vlong	hargint(HConnect*, char*, vlong);
 int		hdebug(HConnect*);
 int		hdisk(HConnect*);
 int		hnotfound(HConnect*);
+int		hproc(HConnect*);
 int		hsethtml(HConnect*);
 int		hsettext(HConnect*);
 int		httpdinit(char *address, char *webroot);

+ 659 - 0
sys/src/cmd/venti/srv/hproc.c

@@ -0,0 +1,659 @@
+#include "stdinc.h"
+#include <bio.h>
+#include <mach.h>
+#include <ureg.h>
+#include "/sys/src/libthread/threadimpl.h"
+#include "dat.h"
+#include "fns.h"
+
+typedef struct Ureg Ureg;
+typedef struct Debug Debug;
+
+struct Debug
+{
+	int textfd;
+	QLock lock;
+	Fhdr fhdr;
+	Map *map;
+	Fmt *fmt;
+	int pid;
+	char *stkprefix;
+};
+
+static Debug debug = { -1 };
+
+static int
+text(int pid)
+{
+	int fd;
+	char buf[100];
+
+	if(debug.textfd >= 0){
+		close(debug.textfd);
+		debug.textfd = -1;
+	}
+	memset(&debug.fhdr, 0, sizeof debug.fhdr);
+	
+	snprint(buf, sizeof buf, "#p/%d/text", pid);
+	fd = open(buf, OREAD);
+	if(fd < 0)
+		return -1;
+	if(crackhdr(fd, &debug.fhdr) < 0){
+		close(fd);
+		return -1;
+	}
+	if(syminit(fd, &debug.fhdr) < 0){
+		memset(&debug.fhdr, 0, sizeof debug.fhdr);
+		close(fd);
+		return -1;
+	}
+	debug.textfd = fd;
+	machbytype(debug.fhdr.type);
+	return 0;
+}
+
+static void
+unmap(Map *m)
+{
+	int i;
+	
+	for(i=0; i<m->nsegs; i++)
+		if(m->seg[i].inuse)
+			close(m->seg[i].fd);
+	free(m);
+}
+
+static Map*
+map(int pid)
+{
+	int mem;
+	char buf[100];
+	Map *m;
+	
+	snprint(buf, sizeof buf, "#p/%d/mem", pid);
+	mem = open(buf, OREAD);
+	if(mem < 0)
+		return nil;
+
+	m = attachproc(pid, 0, mem, &debug.fhdr);
+	if(m == 0){
+		close(mem);
+		return nil;
+	}
+	
+	if(debug.map)
+		unmap(debug.map);
+	debug.map = m;
+	debug.pid = pid;
+	return m;
+}
+
+static void
+dprint(char *fmt, ...)
+{
+	va_list arg;
+	
+	va_start(arg, fmt);
+	fmtvprint(debug.fmt, fmt, arg);
+	va_end(arg);
+}
+
+static void
+openfiles(void)
+{
+	char buf[4096];
+	int fd, n;
+	
+	snprint(buf, sizeof buf, "#p/%d/fd", getpid());
+	if((fd = open(buf, OREAD)) < 0){
+		dprint("open %s: %r\n", buf);
+		return;
+	}
+	n = readn(fd, buf, sizeof buf-1);
+	close(fd);
+	if(n >= 0){
+		buf[n] = 0;
+		fmtstrcpy(debug.fmt, buf);
+	}
+}
+
+/*
+ *	dump the raw symbol table
+ */
+static void
+printsym(void)
+{
+	int i;
+	Sym *sp;
+
+	for (i = 0; sp = getsym(i); i++) {
+		switch(sp->type) {
+		case 't':
+		case 'l':
+			dprint("%16#llux t %s\n", sp->value, sp->name);
+			break;
+		case 'T':
+		case 'L':
+			dprint("%16#llux T %s\n", sp->value, sp->name);
+			break;
+		case 'D':
+		case 'd':
+		case 'B':
+		case 'b':
+		case 'a':
+		case 'p':
+		case 'm':
+			dprint("%16#llux %c %s\n", sp->value, sp->type, sp->name);
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+static void
+printmap(char *s, Map *map)
+{
+	int i;
+
+	if (!map)
+		return;
+	dprint("%s\n", s);
+	for (i = 0; i < map->nsegs; i++) {
+		if (map->seg[i].inuse)
+			dprint("%-16s %-16#llux %-16#llux %-16#llux\n",
+				map->seg[i].name, map->seg[i].b,
+				map->seg[i].e, map->seg[i].f);
+	}
+}
+
+#define ADDR ulong
+
+static void
+printlocals(Map *map, Symbol *fn, ADDR fp)
+{
+	int i;
+	ulong w;
+	Symbol s;
+	char buf[100];
+
+	s = *fn;
+	for (i = 0; localsym(&s, i); i++) {
+		if (s.class != CAUTO)
+			continue;
+		snprint(buf, sizeof buf, "%s%s/", debug.stkprefix, s.name);
+		if (get4(map, fp-s.value, &w) > 0)
+			dprint("\t%-10s %10#lux %ld\n", buf, w, w);
+		else
+			dprint("\t%-10s ?\n", buf);
+	}
+}
+
+static void
+printparams(Map *map, Symbol *fn, ADDR fp)
+{
+	int i;
+	Symbol s;
+	ulong w;
+	int first = 0;
+
+	fp += mach->szaddr;			/* skip saved pc */
+	s = *fn;
+	for (i = 0; localsym(&s, i); i++) {
+		if (s.class != CPARAM)
+			continue;
+		if (first++)
+			dprint(", ");
+		if (get4(map, fp+s.value, &w) > 0)
+			dprint("%s=%#lux", s.name, w);
+	}
+}
+
+static void
+printsource(ADDR dot)
+{
+	char str[100];
+
+	if (fileline(str, sizeof str, dot))
+		dprint("%s", str);
+}
+
+
+/*
+ *	callback on stack trace
+ */
+static ulong nextpc;
+static void
+ptrace(Map *map, uvlong pc, uvlong sp, Symbol *sym)
+{
+	if(nextpc == 0)
+		nextpc = sym->value;
+	if(debug.stkprefix == nil)
+		debug.stkprefix = "";
+	dprint("%s%s(", debug.stkprefix, sym->name);
+	printparams(map, sym, sp);
+	dprint(")");
+	if(nextpc != sym->value)
+		dprint("+%#lx ", nextpc - sym->value);
+	printsource(nextpc);
+	dprint("\n");
+	printlocals(map, sym, sp);
+	nextpc = pc;
+}
+
+static void
+stacktracepcsp(Map *m, ulong pc, ulong sp)
+{
+	nextpc = 0;
+	if(machdata->ctrace==nil)
+		dprint("no machdata->ctrace\n");
+	else if(machdata->ctrace(m, pc, sp, 0, ptrace) <= 0)
+		dprint("no stack frame: pc=%#lux sp=%#lux\n", pc, sp);
+}
+
+static void
+stacktrace(Map *m)
+{
+	ulong pc, sp;
+	
+	if(get4(m, offsetof(Ureg, pc), &pc) < 0){
+		dprint("get4 pc: %r");
+		return;
+	}
+	if(get4(m, offsetof(Ureg, sp), &sp) < 0){
+		dprint("get4 sp: %r");
+		return;
+	}
+	stacktracepcsp(m, pc, sp);
+}
+
+static ulong
+star(ulong addr)
+{
+	ulong x;
+	static int warned;
+
+	if(addr == 0)
+		return 0;
+
+	if(debug.map == nil){
+		if(!warned++)
+			dprint("no debug.map\n");
+		return 0;
+	}
+	if(get4(debug.map, addr, &x) < 0){
+		dprint("get4 %#lux (pid=%d): %r\n", addr, debug.pid);
+		return 0;
+	}
+	return x;
+}
+
+static ulong
+resolvev(char *name)
+{
+	Symbol s;
+
+	if(lookup(nil, name, &s) == 0)
+		return 0;
+	return s.value;
+}
+
+static ulong
+resolvef(char *name)
+{
+	Symbol s;
+
+	if(lookup(name, nil, &s) == 0)
+		return 0;
+	return s.value;
+}
+
+#define FADDR(type, p, name) ((p) + offsetof(type, name))
+#define FIELD(type, p, name) star(FADDR(type, p, name))
+
+static ulong threadpc;
+
+static int
+strprefix(char *big, char *pre)
+{
+	return strncmp(big, pre, strlen(pre));
+}
+static void
+tptrace(Map *map, uvlong pc, uvlong sp, Symbol *sym)
+{
+	char buf[512];
+
+	USED(map);
+	USED(sym);
+	USED(sp);
+
+	if(threadpc != 0)
+		return;
+	if(!fileline(buf, sizeof buf, pc))
+		return;
+	if(strprefix(buf, "/sys/src/libc/") == 0)
+		return;
+	if(strprefix(buf, "/sys/src/libthread/") == 0)
+		return;
+	if(strprefix(buf, "/sys/src/libthread/") == 0)
+		return;
+	threadpc = pc;
+}
+
+static char*
+threadstkline(ulong t)
+{
+	ulong pc, sp;
+	static char buf[500];
+
+	if(FIELD(Thread, t, state) == Running){
+		get4(debug.map, offsetof(Ureg, pc), &pc);
+		get4(debug.map, offsetof(Ureg, sp), &sp);
+	}else{
+		// pc = FIELD(Thread, t, sched[JMPBUFPC]);
+		pc = resolvef("longjmp");
+		sp = FIELD(Thread, t, sched[JMPBUFSP]);
+	}
+	if(machdata->ctrace == nil)
+		return "";
+	threadpc = 0;
+	machdata->ctrace(debug.map, pc, sp, 0, tptrace);
+	if(!fileline(buf, sizeof buf, threadpc))
+		buf[0] = 0;
+	return buf;
+}
+
+static void
+proc(ulong p)
+{
+	dprint("p=(Proc)%#lux pid %d ", p, FIELD(Proc, p, pid));
+	if(FIELD(Proc, p, thread) == 0)
+		dprint(" Sched\n");
+	else
+		dprint(" Running\n");
+}
+
+static void
+fmtbufinit(Fmt *f, char *buf, int len)
+{
+	memset(f, 0, sizeof *f);
+	f->runes = 0;
+	f->start = buf;
+	f->to = buf;
+	f->stop = buf + len - 1;
+	f->flush = nil;
+	f->farg = nil;
+	f->nfmt = 0;
+}
+
+static char*
+fmtbufflush(Fmt *f)
+{
+	*(char*)f->to = 0;
+	return (char*)f->start;
+}
+
+static char*
+debugstr(ulong s)
+{
+	static char buf[4096];
+	char *p, *e;
+	
+	p = buf;
+	e = buf+sizeof buf - 1;
+	while(p < e){
+		if(get1(debug.map, s++, (uchar*)p, 1) < 0)
+			break;
+		if(*p == 0)
+			break;
+		p++;
+	}
+	*p = 0;
+	return buf;
+}
+
+static char*
+threadfmt(ulong t)
+{
+	static char buf[4096];
+	Fmt fmt;
+	int s;
+
+	fmtbufinit(&fmt, buf, sizeof buf);
+	
+	fmtprint(&fmt, "t=(Thread)%#lux ", t);
+	switch(s = FIELD(Thread, t, state)){
+	case Running:
+		fmtprint(&fmt, " Running   ");
+		break;
+	case Ready:
+		fmtprint(&fmt, " Ready     ");
+		break;
+	case Rendezvous:
+		fmtprint(&fmt, " Rendez    ");
+		break;
+	default:
+		fmtprint(&fmt, " bad state %d ", s);
+		break;
+	}
+	
+	fmtprint(&fmt, "%s", threadstkline(t));
+	
+	if(FIELD(Thread, t, moribund) == 1)
+		fmtprint(&fmt, " Moribund");
+	if(s = FIELD(Thread, t, cmdname)){
+		fmtprint(&fmt, " [%s]", debugstr(s));
+	}
+
+	fmtbufflush(&fmt);
+	return buf;
+}
+
+
+static void
+thread(ulong t)
+{
+	dprint("%s\n", threadfmt(t));
+}
+
+static void
+threadapply(ulong p, void (*fn)(ulong))
+{
+	int oldpid, pid;
+	ulong tq, t;
+	
+	oldpid = debug.pid;
+	pid = FIELD(Proc, p, pid);
+	if(map(pid) == nil)
+		return;
+	tq = FADDR(Proc, p, threads);
+	t = FIELD(Tqueue, tq, head);
+	while(t != 0){
+		fn(t);
+		t = FIELD(Thread, t, nextt);
+	}
+	map(oldpid);
+}
+
+static void
+pthreads1(ulong t)
+{
+	dprint("\t");
+	thread(t);
+}
+
+static void
+pthreads(ulong p)
+{
+	threadapply(p, pthreads1);
+}
+
+static void
+lproc(ulong p)
+{
+	proc(p);
+	pthreads(p);
+}
+
+static void
+procapply(void (*fn)(ulong))
+{
+	ulong proc;
+	ulong pq;
+	
+	pq = resolvev("_threadpq");
+	if(pq == 0){
+		dprint("no thread run queue\n");
+		return;
+	}
+
+	proc = FIELD(Pqueue, pq, head);
+	while(proc){
+		fn(proc);
+		proc = FIELD(Proc, proc, next);
+	}
+}
+
+static void
+threads(HConnect *c)
+{
+	USED(c);
+	procapply(lproc);
+}
+
+static void
+procs(HConnect *c)
+{
+	USED(c);
+	procapply(proc);
+}
+
+static void
+threadstack(ulong t)
+{
+	ulong pc, sp;
+
+	if(FIELD(Thread, t, state) == Running){
+		stacktrace(debug.map);
+	}else{
+		// pc = FIELD(Thread, t, sched[JMPBUFPC]);
+		pc = resolvef("longjmp");
+		sp = FIELD(Thread, t, sched[JMPBUFSP]);
+		stacktracepcsp(debug.map, pc, sp);
+	}
+}
+
+
+static void
+tstacks(ulong t)
+{
+	dprint("\t");
+	thread(t);
+	threadstack(t);
+	dprint("\n");
+}
+
+static void
+pstacks(ulong p)
+{
+	proc(p);
+	threadapply(p, tstacks);
+}
+
+static void
+stacks(HConnect *c)
+{
+	USED(c);
+	debug.stkprefix = "\t\t";
+	procapply(pstacks);
+	debug.stkprefix = "";
+}
+
+static void
+symbols(HConnect *c)
+{
+	USED(c);
+	printsym();
+}
+
+static void
+segments(HConnect *c)
+{
+	USED(c);
+	printmap("segments", debug.map);
+}
+
+static void
+fds(HConnect *c)
+{
+	USED(c);
+	openfiles();
+}
+
+static void
+all(HConnect *c)
+{
+	dprint("/proc/segment\n");
+	segments(c);
+	dprint("\n/proc/fd\n");
+	fds(c);
+	dprint("\n/proc/procs\n");
+	procs(c);
+	dprint("\n/proc/threads\n");
+	threads(c);
+	dprint("\n/proc/stacks\n");
+	stacks(c);
+	dprint("\n# /proc/symbols\n");
+	// symbols(c);
+}
+
+int
+hproc(HConnect *c)
+{
+	void (*fn)(HConnect*);
+	static char buf[65536];
+	Fmt fmt;
+
+	if(strcmp(c->req.uri, "/proc/all") == 0)
+		fn = all;
+	else if(strcmp(c->req.uri, "/proc/segment") == 0)
+		fn = segments;
+	else if(strcmp(c->req.uri, "/proc/fd") == 0)
+		fn = fds;
+	else if(strcmp(c->req.uri, "/proc/procs") == 0)
+		fn = procs;
+	else if(strcmp(c->req.uri, "/proc/threads") == 0)
+		fn = threads;
+	else if(strcmp(c->req.uri, "/proc/stacks") == 0)
+		fn = stacks;
+	else if(strcmp(c->req.uri, "/proc/symbols") == 0)
+		fn = symbols;
+	else
+		return hnotfound(c);
+
+	if(hsettext(c) < 0)
+		return -1;
+	if(!canqlock(&debug.lock)){
+		hprint(&c->hout, "debugger is busy\n");
+		return 0;
+	}
+	if(debug.textfd < 0){
+		if(text(getpid()) < 0){
+			hprint(&c->hout, "cannot attach self text: %r\n");
+			goto out;
+		}
+	}
+	if(map(getpid()) == nil){
+		hprint(&c->hout, "cannot map self: %r\n");
+		goto out;
+	}
+
+	fmtbufinit(&fmt, buf, sizeof buf);
+	debug.fmt = &fmt;
+	fn(c);
+	hprint(&c->hout, "%s\n", fmtbufflush(&fmt));
+	debug.fmt = nil;
+out:
+	qunlock(&debug.lock);
+	return 0;
+}

+ 1 - 0
sys/src/cmd/venti/srv/httpd.c

@@ -69,6 +69,7 @@ httpdinit(char *address, char *dir)
 	httpdobj("/emptydcache", hdcacheempty);
 	httpdobj("/disk", hdisk);
 	httpdobj("/debug", hdebug);
+	httpdobj("/proc/", hproc);
 
 	if(vtproc(listenproc, address) < 0)
 		return -1;

+ 3 - 0
sys/src/cmd/venti/srv/mkfile

@@ -13,6 +13,7 @@ LIBOFILES=\
 	dump.$O\
 	graph.$O\
 	hdisk.$O\
+	hproc.$O\
 	httpd.$O\
 	icache.$O\
 	icachewrite.$O\
@@ -45,6 +46,8 @@ LIB=$SLIB # /$objtype/lib/libventi.a
 HFILES=	dat.h\
 	fns.h\
 	stdinc.h\
+	/sys/include/venti.h\
+	/sys/include/httpd.h\
 
 TARG=\
 	venti\