forgotten files
This commit is contained in:
parent
a6517fb498
commit
40d6302b5f
3 changed files with 91 additions and 2 deletions
|
@ -41,6 +41,8 @@ struct DTName {
|
||||||
/*
|
/*
|
||||||
we assign all pairs (probe,action-group) (called an enabling or DTEnab) a unique ID called EPID.
|
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.
|
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 {
|
struct DTEnab {
|
||||||
u32int epid;
|
u32int epid;
|
||||||
|
@ -235,6 +237,10 @@ struct DTTrigInfo {
|
||||||
DTChan *ch;
|
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 dtinit(int);
|
||||||
void dtsync(void);
|
void dtsync(void);
|
||||||
|
@ -269,6 +275,7 @@ int dtcread(DTChan *, void *, int);
|
||||||
int dtcaggread(DTChan *, void *, int);
|
int dtcaggread(DTChan *, void *, int);
|
||||||
void dtcreset(DTChan *);
|
void dtcreset(DTChan *);
|
||||||
void dtcrun(DTChan *, int);
|
void dtcrun(DTChan *, int);
|
||||||
|
int dtcfault(DTTrigInfo *, int, char *, ...);
|
||||||
|
|
||||||
/* aggbuf functions */
|
/* aggbuf functions */
|
||||||
int dtaunpackid(DTAgg *);
|
int dtaunpackid(DTAgg *);
|
||||||
|
|
|
@ -462,6 +462,34 @@ parseclause(Clause *cl, uchar *p, uchar *e, Enab *en, Biobuf *bp)
|
||||||
return 0;
|
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
|
int
|
||||||
parsebuf(uchar *p, int n, Biobuf *bp)
|
parsebuf(uchar *p, int n, Biobuf *bp)
|
||||||
{
|
{
|
||||||
|
@ -474,6 +502,11 @@ parsebuf(uchar *p, int n, Biobuf *bp)
|
||||||
while(p < e){
|
while(p < e){
|
||||||
p = unpack(p, e, "iv", &epid, &ts);
|
p = unpack(p, e, "iv", &epid, &ts);
|
||||||
if(p == nil) goto err;
|
if(p == nil) goto err;
|
||||||
|
if(epid == (u32int)-1){
|
||||||
|
p = parsefault(p, e);
|
||||||
|
if(p == nil) goto err;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
en = epidlookup(epid);
|
en = epidlookup(epid);
|
||||||
if(en == nil) goto err;
|
if(en == nil) goto err;
|
||||||
if(parseclause(en->cl, p - 12, p + en->reclen - 12, en, bp) < 0) return -1;
|
if(parseclause(en->cl, p - 12, p + en->reclen - 12, en, bp) < 0) return -1;
|
||||||
|
|
|
@ -230,6 +230,55 @@ dtpeekstr(uvlong addr, u8int *v, int len)
|
||||||
#define PUT4(c) *bp++ = c; *bp++ = c >> 8; *bp++ = c >> 16; *bp++ = c >> 24;
|
#define PUT4(c) *bp++ = c; *bp++ = c >> 8; *bp++ = c >> 16; *bp++ = c >> 24;
|
||||||
#define PUT8(c) PUT4(c); PUT4(c>>32);
|
#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
|
static int
|
||||||
dtgexec(DTActGr *g, DTTrigInfo *info)
|
dtgexec(DTActGr *g, DTTrigInfo *info)
|
||||||
{
|
{
|
||||||
|
@ -265,8 +314,8 @@ dtgexec(DTActGr *g, DTTrigInfo *info)
|
||||||
break;
|
break;
|
||||||
case ACTTRACESTR:
|
case ACTTRACESTR:
|
||||||
if(dtpeekstr(v, bp, g->acts[i].size) < 0){
|
if(dtpeekstr(v, bp, g->acts[i].size) < 0){
|
||||||
snprint(info->ch->errstr, sizeof(info->ch->errstr), "fault @ %#llux", v);
|
dtcfault(info, DTFILL, "ip", dtgetvar(DTV_PID), v);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
bp += g->acts[i].size;
|
bp += g->acts[i].size;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue