1 #pragma lib "libdtracy.a"
2 #pragma src "/sys/src/libdtracy"
5 triggered probes run in "probe context", which involves grabbing a per-CPU lock using dtmachlock/dtmachunlock.
6 everything else in the library assumes that the calling code has grabbed a global lock (which is done in 9/port/devtracy.c).
17 DTABUCKETS = DTBUFSZ - 4 * DTANUMBUCKETS,
19 #define DTANIL ((u32int)-1)
21 typedef struct DTProbe DTProbe;
22 typedef struct DTExprState DTExprState;
23 typedef struct DTAct DTAct;
24 typedef struct DTActGr DTActGr;
25 typedef struct DTClause DTClause;
26 typedef struct DTEnab DTEnab;
27 typedef struct DTChan DTChan;
28 typedef struct DTExpr DTExpr;
29 typedef struct DTProvider DTProvider;
30 typedef struct DTAgg DTAgg;
31 typedef struct DTBuf DTBuf;
32 typedef struct DTTrigInfo DTTrigInfo;
35 we assign all pairs (probe,action-group) (called an enabling or DTEnab) a unique ID called EPID.
36 we could also use probe IDs and action group IDs but using a single 32-bit ID for both is more flexible/efficient.
38 epid == -1 indicates a fault record (see below)
43 DTEnab *probnext, *probprev;
48 /* probes are never freed */
54 void *aux; /* for the provider */
61 provide() is called when the user first uses a provider.
62 provide() should call dtpnew() to create probes.
64 void (*provide)(DTProvider *);
65 int (*enable)(DTProbe *); /* enable the probe. return >= 0 for success and < 0 for failure */
66 void (*disable)(DTProbe *); /* disable the probe */
68 /* for the library, not the provider */
74 the dtracy vm is a simple RISC machine with (currently) 16 64-bit registers.
75 all operations are 64-bit.
97 DTE_LSL = 0x0B, /* logical shift left */
98 DTE_LSR = 0x0C, /* logical shift right */
99 DTE_ASR = 0x0D, /* arithmetic shift right */
100 DTE_SEQ = 0x10, /* set if equal */
101 DTE_SNE = 0x11, /* set if not equal */
102 DTE_SLT = 0x12, /* set if less than */
103 DTE_SLE = 0x13, /* set if less or equal */
105 /* immediate operations, const = 10 top bits of ab, sign extended and shifted left by 6 bottom bits */
106 DTE_LDI = 0x20, /* Rc = const */
107 DTE_XORI = 0x21, /* Rc = Rc ^ const */
109 /* if(Ra (op) Rb) PC += c; */
115 DTE_LDV = 0x40, /* R[b] = Var[a] */
117 DTE_ZXT = 0x50, /* R[c] = lower b bits of R[a], zero extended, 0 < b <= 64 */
118 DTE_SXT = 0x51, /* R[c] = lower b bits of R[a], sign extended, 0 < b <= 64 */
120 DTE_RET = 0xF0, /* RET Ra */
122 #define DTE(op,a,b,c) ((op)<<24|(a)<<16|(b)<<8|(c))
130 aggregation buffers are hashtables and use a different record format.
131 there are DTANUMBUCKETS 4-byte buckets at the end of the buffer.
132 each entry is (link,id,key,val) with a 4-byte link field for the hash chains and a 4-byte aggregation id.
134 the aggregation id actually contains all the data in the DTAgg struct:
136 12-bit keysize in qwords
139 the struct is just for kernel convenience
153 u16int keysize; /* in bytes */
158 /* an action is an expression, plus info about what to do with the result */
161 ACTTRACE, /* record the result. size is the number of bytes used. 0 <= size <= 8 */
162 ACTTRACESTR, /* take the result to be a pointer to a null-terminated string. store it as zero-padded char[size]. */
164 ACTAGGKEY and ACTAGGVAL together record a value in an aggregation.
165 they must occur as a pair and targ must point to an already allocated aggregation buffer.
166 currently 0 <= size <= 8.
170 ACTCANCEL, /* (must be last action) don't write anything into the main buffer. used to avoid pointless records when using aggregations. */
177 /* an action group is an optional predicate and a set of actions. */
181 DTExpr *pred; /* if non-nil and evaluates to 0, skip the actions. */
185 int reclen; /* record size, including 12-byte header */
188 /* a clause lists probe wildcard expressions and an action group. only used during set-up. */
200 /* a chan is the kernel representation of a client. */
208 u32int epidalloc; /* lowest unused EPID */
210 /* we have 2 buffers per cpu, one for writing and one for reading. dtcread() swaps them if empty. */
213 /* aggregations use separate buffers */
217 /* list of enablings. */
221 /* this struct collects the state during the execution of a probe */
223 /* filled in by caller of dtptrigger */
225 /* filled in by dtptrigger */
232 /* fault records are used to note when a probe had to be aborted (e.g. because of a page fault) */
234 DTFILL = 1, /* illegal address */
240 /* probe functions */
241 DTProbe *dtpnew(char *, DTProvider *, void *aux);
242 int dtpmatch(char *, DTProbe ***);
243 int dtplist(DTProbe ***);
244 void dtptrigger(DTProbe *, int, DTTrigInfo *);
246 /* expression functions */
247 int dteverify(DTExpr *);
249 #pragma varargck type "I" u32int
251 /* action group functions */
252 void dtgpack(Fmt *, DTActGr *);
253 char *dtgunpack(char *, DTActGr **);
254 int dtgverify(DTChan *, DTActGr *);
255 void dtgfree(DTActGr *);
257 /* clause functions */
258 void dtclpack(Fmt *, DTClause *);
259 char *dtclunpack(char *, DTClause **);
260 void dtclfree(DTClause *);
263 DTChan *dtcnew(void);
264 void dtcfree(DTChan *);
265 int dtcaddgr(DTChan *, char *, DTActGr *);
266 int dtcaddcl(DTChan *, DTClause *);
267 int dtcread(DTChan *, void *, int);
268 int dtcaggread(DTChan *, void *, int);
269 void dtcreset(DTChan *);
270 void dtcrun(DTChan *, int);
271 int dtcfault(DTTrigInfo *, int, char *, ...);
273 /* aggbuf functions */
274 int dtaunpackid(DTAgg *);
275 void dtarecord(DTChan *, int, DTAgg *, uchar *, int, s64int);
277 extern DTProvider *dtproviders[];
281 char *dtstrdup(char *);
283 /* these functions are provided by the kernel interface */
284 uvlong dttime(void); /* return current timestamp */
285 void *dtrealloc(void *, ulong);
287 void *dtmalloc(ulong);
288 void dtmachlock(int); /* lock the per-cpu lock */
289 void dtmachunlock(int); /* unlock the per-cpu lock */
290 void dtcoherence(void); /* memory barrier */
291 uvlong dtgetvar(int); /* return the value of a variable */
292 int dtpeek(uvlong, void*, int); /* safe memmemove(). returns -1 on error. */
311 extern char *dtvarnames[DTNVARS];