shithub: riscv

Download patch

ref: 40d6302b5f289ad8a617d12fa911197dddafc634
parent: a6517fb4984458d6f5ce4864a408c5057d15306d
author: aiju <devnull@localhost>
date: Tue Dec 11 04:20:34 EST 2018

forgotten files

--- a/sys/include/dtracy.h
+++ b/sys/include/dtracy.h
@@ -41,6 +41,8 @@
 /*
 	we assign all pairs (probe,action-group) (called an enabling or DTEnab) a unique ID called EPID.
 	we could also use probe IDs and action group IDs but using a single 32-bit ID for both is more flexible/efficient.
+	
+	epid == -1 indicates a fault record (see below)
 */
 struct DTEnab {
 	u32int epid;
@@ -235,6 +237,10 @@
 	DTChan *ch;
 };
 
+/* fault records are used to note when a probe had to be aborted (e.g. because of a page fault) */
+enum {
+	DTFILL = 1, /* illegal address */
+};
 
 void dtinit(int);
 void dtsync(void);
@@ -269,6 +275,7 @@
 int dtcaggread(DTChan *, void *, int);
 void dtcreset(DTChan *);
 void dtcrun(DTChan *, int);
+int dtcfault(DTTrigInfo *, int, char *, ...);
 
 /* aggbuf functions */
 int dtaunpackid(DTAgg *);
--- a/sys/src/cmd/dtracy/act.c
+++ b/sys/src/cmd/dtracy/act.c
@@ -462,6 +462,34 @@
 	return 0;
 }
 
+uchar *
+parsefault(uchar *p0, uchar *e)
+{
+	uchar *p;
+	u32int epid;
+	u8int type, dummy;
+	u16int n;
+	Enab *en;
+
+	p = unpack(p0, e, "csci", &type, &n, &dummy, &epid);
+	if(p == nil) return nil;
+	en = epidlookup(epid);
+	switch(type){
+	case DTFILL: {
+		u32int pid;
+		u64int addr;
+		
+		p = unpack(p, e, "iv", &pid, &addr);
+		if(p == nil) return nil;
+		fprint(2, "dtracy: illegal access: probe=%s, pid=%d, addr=%#llx\n", en != nil ? en->probe : nil, pid, addr);
+		break;
+	}
+	default:
+		fprint(2, "dtracy: unknown fault type %#.2ux\n", type);
+	}
+	return p0 + n - 12;
+}
+
 int
 parsebuf(uchar *p, int n, Biobuf *bp)
 {
@@ -474,6 +502,11 @@
 	while(p < e){
 		p = unpack(p, e, "iv", &epid, &ts);
 		if(p == nil) goto err;
+		if(epid == (u32int)-1){
+			p = parsefault(p, e);
+			if(p == nil) goto err;
+			continue;
+		}
 		en = epidlookup(epid);
 		if(en == nil) goto err;
 		if(parseclause(en->cl, p - 12, p + en->reclen - 12, en, bp) < 0) return -1;
--- a/sys/src/libdtracy/prog.c
+++ b/sys/src/libdtracy/prog.c
@@ -230,6 +230,55 @@
 #define PUT4(c) *bp++ = c; *bp++ = c >> 8; *bp++ = c >> 16; *bp++ = c >> 24;
 #define PUT8(c) PUT4(c); PUT4(c>>32);
 
+int
+dtcfault(DTTrigInfo *info, int type, char *fmt, ...)
+{
+	DTBuf *b;
+	va_list va;
+	int n;
+	char *s;
+	u8int *bp;
+	u32int l;
+	uvlong q;
+	
+	b = info->ch->wrbufs[info->machno];
+	n = 20;
+	va_start(va, fmt);
+	for(s = fmt; *s != 0; s++)
+		switch(*s){
+		case 'i': n += 4; break;
+		case 'p': n += 8; break;
+		default:
+			assert(0);
+		}
+	va_end(va);
+	if(b->wr + n > DTBUFSZ)
+		return -1;
+	bp = &b->data[b->wr];
+	PUT4(-1);
+	PUT8(info->ts);
+	PUT1(type);
+	PUT2(n);
+	PUT1(0);
+	PUT4(info->epid);
+	va_start(va, fmt);
+	for(s = fmt; *s != 0; s++)
+		switch(*s){
+		case 'i':
+			l = va_arg(va, int);
+			PUT4(l);
+			break;
+		case 'p':
+			q = (uintptr) va_arg(va, void *);
+			PUT8(q);
+			break;
+		}
+	va_end(va);
+	assert(bp - b->data - b->wr == n);
+	b->wr = bp - b->data;
+	return 0;
+}
+
 static int
 dtgexec(DTActGr *g, DTTrigInfo *info)
 {
@@ -265,8 +314,8 @@
 			break;
 		case ACTTRACESTR:
 			if(dtpeekstr(v, bp, g->acts[i].size) < 0){
-				snprint(info->ch->errstr, sizeof(info->ch->errstr), "fault @ %#llux", v);
-				return -1;
+				dtcfault(info, DTFILL, "ip", dtgetvar(DTV_PID), v);
+				return 0;
 			}
 			bp += g->acts[i].size;
 			break;