* [PATCH v7 03/19] Deprecate enabled probe ID (epid)
@ 2024-09-24 20:25 eugene.loh
2024-09-24 20:25 ` [PATCH v2 05/19] Split dt_pid_create_probes() into pid and USDT functions eugene.loh
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: eugene.loh @ 2024-09-24 20:25 UTC (permalink / raw)
To: dtrace, dtrace-devel
From: Eugene Loh <eugene.loh@oracle.com>
Historically, the enabled probe id (epid) was an integer, passed from
producer to consumer, that uniquely identified probe ID and statement
(data description). It was used in error reporting and was available
to D users via a built-in variable "epid".
However, its value was opaque to users and difficult to use.
Deprecate the use of EPID:
*) Have the producer pass to the consumer the probe ID and statement
ID explicitly, instead of passing an opaque integer that requires
additional lookup tables.
*) Keep an array dt_stmts[] of statements, from which we can retrieve
probe descriptions and data descriptions.
*) Remove data structures related to epid: dt_ddesc[], dt_pdesc[],
dt_nextepid, dt_maxprobe, etc.
Nevertheless, continue to provide a value for the built-in "epid" variable
for back compatability. Expand the epid from 4 bytes to 8 bytes: the
upper half is the probe ID and the lower half the statement ID.
The output buffer (written by the producer, read by the consumer) is
rearranged slightly. Note that:
*) It starts with a 4-byte size, which perf_event writes.
*) The beginning of the output buffer should have 8-byte alignment.
*) The beginning of the trace data within the output buffer should
also have 8-byte alignment.
*) So we rearrange as follows:
old new
0: pad / size pad / size <==
4: pad specid
8: epid <== prid
12: specid stid
16: data[n] data[n]
The arrow <== indicates where the buffer starts.
For error reporting:
*) Report errors in terms of the probe ID (and description) and the
clause function name, which is decipherable in terms of the
disassembly output. Specifically, change ERROR-probe arguments:
-) arg1 changes from epid to the probe ID
-) arg2 changes from "clause index" (which is no longer needed)
to the statement ID that identifies the clause named in
disassembly output
*) No longer report the "action number", which has lost much of its
meaning in the port to eBPF. Nonetheless, keep dteda_action; its
value is not used, but set the value to stid for possible future use.
Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
bpf/get_bvar.c | 5 +-
bpf/probe_error.c | 8 +-
include/dtrace/metadesc.h | 4 +-
include/dtrace/universal.h | 3 +-
libdtrace/dt_bpf.c | 2 -
libdtrace/dt_bpf.h | 46 ++++----
libdtrace/dt_cc.c | 47 ++------
libdtrace/dt_cg.c | 49 ++++-----
libdtrace/dt_consume.c | 85 ++++++++-------
libdtrace/dt_dctx.h | 21 ++--
libdtrace/dt_dlibs.c | 2 -
libdtrace/dt_error.c | 2 +-
libdtrace/dt_handle.c | 103 ++++++++----------
libdtrace/dt_impl.h | 15 +--
libdtrace/dt_map.c | 97 ++---------------
libdtrace/dt_open.c | 5 +-
libdtrace/dt_program.c | 9 +-
libdtrace/dtrace.h | 3 +-
test/demo/builtin/eipd.d | 4 -
test/demo/dtrace/error.r | 2 +-
test/demo/spec/specopen.d | 5 +-
test/stress/buffering/tst.resize3-manual.d | 2 +-
test/stress/buffering/tst.resize3-manual.r | 2 +-
test/stress/buffering/tst.resize3.d | 2 +-
test/stress/buffering/tst.resize3.r | 2 +-
test/unittest/actions/setopt/tst.badopt.r | 14 +--
.../arrays/tst.declared-bounds.runtime_out.r | 2 +-
test/unittest/codegen/err.deref_0.r | 2 +-
test/unittest/codegen/err.deref_1.r | 2 +-
test/unittest/codegen/err.deref_i0.r | 2 +-
test/unittest/codegen/err.deref_i1.r | 2 +-
.../unittest/codegen/err.deref_string-assoc.r | 2 +-
test/unittest/codegen/err.deref_string-gvar.r | 2 +-
test/unittest/codegen/err.deref_string-lvar.r | 2 +-
test/unittest/codegen/err.deref_string-tvar.r | 2 +-
.../codegen/err.str_NULL_plus_offset-assoc.r | 2 +-
.../codegen/err.str_NULL_plus_offset-lvar.r | 2 +-
.../codegen/err.str_NULL_plus_offset-tvar.r | 2 +-
.../codegen/err.str_NULL_plus_offset.r | 2 +-
test/unittest/disasm/tst.vartab-bvar.r | 2 +-
test/unittest/drops/drp.DTRACEDROP_DBLERROR.r | 2 +-
.../tst.DTRACEFLT_BADADDR.null_ptr_field.d | 6 +-
.../tst.DTRACEFLT_BADADDR.null_ptr_field.r | 2 +-
test/unittest/error/tst.DTRACEFLT_BADADDR.r | 4 +-
test/unittest/error/tst.DTRACEFLT_BADADDR2.r | 4 +-
.../error/tst.DTRACEFLT_DIVZERO.div.d | 11 +-
.../error/tst.DTRACEFLT_DIVZERO.div.r | 2 +-
.../error/tst.DTRACEFLT_DIVZERO.mod.d | 11 +-
.../error/tst.DTRACEFLT_DIVZERO.mod.r | 2 +-
test/unittest/error/tst.DTRACEFLT_UNKNOWN.r | 4 +-
.../error/tst.clause_scope-begin-ended.r | 2 +-
test/unittest/error/tst.clause_scope-begin.r | 2 +-
.../unittest/error/tst.clause_scope-regular.r | 2 +-
.../error/tst.clause_scope-regular.r.p | 8 +-
test/unittest/error/tst.error.r | 2 +-
test/unittest/error/tst.errorend.r | 2 +-
.../alloca/err.alloca-bcopy-before-beyond.r | 2 +-
.../alloca/err.alloca-bcopy-before-bottom.r | 2 +-
.../alloca/err.alloca-bcopy-beyond-top.r | 2 +-
.../alloca/err.alloca-bcopy-crossing-bottom.r | 2 +-
.../alloca/err.alloca-bcopy-crossing-top.r | 2 +-
.../alloca/err.alloca-crossing-clauses.r | 2 +-
.../alloca/err.alloca-load-before-bottom.r | 2 +-
.../funcs/alloca/err.alloca-load-beyond-top.r | 2 +-
.../alloca/err.alloca-load-crossing-bottom.r | 2 +-
.../alloca/err.alloca-null-deref-lvalue.r | 2 +-
.../funcs/alloca/err.alloca-null-deref.r | 2 +-
.../err.alloca-scratch-exceeding-bcopy.r | 2 +-
.../alloca/err.alloca-store-before-bottom.r | 2 +-
.../alloca/err.alloca-store-beyond-top.r | 2 +-
.../alloca/err.alloca-store-crossing-bottom.r | 2 +-
test/unittest/funcs/bcopy/err.badbcopy1.r | 2 +-
test/unittest/funcs/bcopy/err.badbcopy4.r | 2 +-
test/unittest/funcs/bcopy/err.badbcopy5.r | 2 +-
test/unittest/funcs/bcopy/err.badbcopy6.r | 2 +-
test/unittest/funcs/bcopy/err.badbcopy7.r | 2 +-
test/unittest/funcs/bcopy/err.badbcopy8.r | 2 +-
test/unittest/funcs/copyin/err.badaddr.r | 2 +-
test/unittest/funcs/copyin/err.null_arg1.r | 2 +-
test/unittest/funcs/copyinstr/err.badaddr.r | 2 +-
test/unittest/funcs/copyinstr/err.null_arg1.r | 2 +-
test/unittest/funcs/copyinto/err.badaddr.r | 2 +-
test/unittest/funcs/copyinto/err.badsize.r | 2 +-
test/unittest/funcs/copyinto/err.null_arg1.r | 2 +-
test/unittest/funcs/err.badalloca.r | 2 +-
test/unittest/funcs/err.badalloca.r.p | 8 +-
test/unittest/funcs/err.link_ntopbadaddr.r | 2 +-
test/unittest/funcs/err.link_ntopbadarg.r | 2 +-
.../inet_ntoa6/err.inet_ntoa6.arg1_null.r | 2 +-
.../err.inet_ntoa6.arg1_null_const.r | 2 +-
test/unittest/funcs/strlen/tst.null.r | 2 +-
test/unittest/funcs/strtok/tst.strtok_null.r | 2 +-
.../funcs/strtok/tst.strtok_nulldel.r | 2 +-
.../funcs/strtok/tst.strtok_nullstr.r | 2 +-
.../funcs/strtok/tst.strtok_nullstr2.r | 2 +-
.../funcs/substr/err.substr_null_arg1.r | 2 +-
test/unittest/pointers/err.AllocaOverrun.r | 2 +-
test/unittest/pointers/err.BadAlign.r | 2 +-
test/unittest/pointers/err.InvalidAddress2.r | 2 +-
test/unittest/pointers/err.InvalidAddress4.r | 2 +-
.../speculation/err.CommitWithInvalid.r | 2 +-
.../speculation/err.DiscardWithInvalid.r | 2 +-
.../speculation/tst.SpecSizeVariations.r | 22 ----
.../speculation/tst.SpecSizeVariations.sh | 2 +-
test/unittest/speculation/tst.negcommit.r | 2 +-
.../variables/bvar/tst.arg3-ERROR-b.sh | 2 +-
.../unittest/variables/bvar/tst.arg3-ERROR.sh | 2 +-
107 files changed, 322 insertions(+), 439 deletions(-)
delete mode 100644 test/demo/builtin/eipd.d
diff --git a/bpf/get_bvar.c b/bpf/get_bvar.c
index a0c04f3a3..37f29a591 100644
--- a/bpf/get_bvar.c
+++ b/bpf/get_bvar.c
@@ -48,8 +48,9 @@ noinline uint64_t dt_get_bvar(const dt_dctx_t *dctx, uint32_t id, uint32_t idx)
mst->tstamp = bpf_ktime_get_ns();
return mst->tstamp;
- case DIF_VAR_EPID:
- return mst->epid;
+ case DIF_VAR_EPID: {
+ return (((uint64_t)mst->prid) << 32) | mst->stid;
+ }
case DIF_VAR_ID:
return mst->prid;
case DIF_VAR_ARG0: case DIF_VAR_ARG1: case DIF_VAR_ARG2:
diff --git a/bpf/probe_error.c b/bpf/probe_error.c
index 1081ee71d..a9233b7c9 100644
--- a/bpf/probe_error.c
+++ b/bpf/probe_error.c
@@ -16,8 +16,8 @@ extern int64_t dt_error(const dt_dctx_t *dctx);
/*
* DTrace ERROR probes provide 6 arguments:
* arg0 = always NULL (used to be kernel consumer state pointer)
- * arg1 = EPID of probe that triggered the fault
- * arg2 = clause index of code that triggered the fault
+ * arg1 = probe ID that triggered the fault
+ * arg2 = statement ID that triggered the fault
* arg3 = BPF offset in the clause that triggered the fault (or -1)
* arg4 = fault type
* arg5 = fault-specific value (usually address being accessed or 0)
@@ -30,8 +30,8 @@ noinline void dt_probe_error(const dt_dctx_t *dctx, uint64_t pc, uint64_t fault,
__builtin_memcpy(mst->saved_argv, mst->argv, sizeof(mst->saved_argv));
mst->argv[0] = 0;
- mst->argv[1] = mst->epid;
- mst->argv[2] = mst->clid;
+ mst->argv[1] = mst->prid;
+ mst->argv[2] = mst->stid;
mst->argv[3] = pc;
mst->argv[4] = fault;
mst->argv[5] = illval;
diff --git a/include/dtrace/metadesc.h b/include/dtrace/metadesc.h
index ab9061f73..41125ff13 100644
--- a/include/dtrace/metadesc.h
+++ b/include/dtrace/metadesc.h
@@ -19,8 +19,8 @@
/*
* DTrace separates the trace data stream from the metadata stream. The only
- * metadata tokens placed in the data stream are enabled probe identifiers
- * (EPIDs) or (in the case of aggregations) aggregation identifiers. In order
+ * metadata tokens placed in the data stream are probe and statement identifiers
+ * or (in the case of aggregations) aggregation identifiers. In order
* to determine the structure of the data, DTrace uses the token to perform a
* lookup to retrieve the corresponding description of the enabled probe (via
* the dtrace_datadesc structure) or the aggregation (via the dtrace_aggdesc
diff --git a/include/dtrace/universal.h b/include/dtrace/universal.h
index d65624899..325586e57 100644
--- a/include/dtrace/universal.h
+++ b/include/dtrace/universal.h
@@ -17,7 +17,6 @@
#define DTRACE_CPUALL -1 /* all CPUs */
#define DTRACE_IDNONE 0 /* invalid probe identifier */
-#define DTRACE_EPIDNONE 0 /* invalid enabled probe identifier */
#define DTRACE_AGGIDNONE 0 /* invalid aggregation identifier */
#define DTRACE_AGGVARIDNONE 0 /* invalid aggregation variable ID */
#define DTRACE_CACHEIDNONE 0 /* invalid predicate cache */
@@ -37,7 +36,7 @@ typedef uint16_t dtrace_actkind_t; /* action kind */
typedef uint32_t dtrace_aggid_t; /* aggregation identifier */
typedef uint32_t dtrace_cacheid_t; /* predicate cache identifier */
-typedef uint32_t dtrace_epid_t; /* enabled probe identifier */
+typedef uint32_t dtrace_stid_t; /* statement identifier */
typedef uint32_t dtrace_optid_t; /* option identifier */
typedef uint32_t dtrace_specid_t; /* speculation identifier */
diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
index df427c864..ad11d178e 100644
--- a/libdtrace/dt_bpf.c
+++ b/libdtrace/dt_bpf.c
@@ -774,7 +774,6 @@ gmap_create_cpuinfo(dtrace_hdl_t *dtp)
* The size of the memory region is the sum of:
* - size of the DTrace machine state, rounded up to the nearest
* multiple of 8
- * - 8 bytes padding for trace buffer alignment purposes
* - maximum trace buffer record size, rounded up to the nearest
* multiple of 8
* - size of dctx->mem (see dt_dctx.h)
@@ -783,7 +782,6 @@ static int
gmap_create_mem(dtrace_hdl_t *dtp)
{
size_t sz = roundup(sizeof(dt_mstate_t), 8) +
- 8 +
roundup(dtp->dt_maxreclen, 8) +
DMEM_SIZE(dtp);
diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
index 5b2df2641..5716d2320 100644
--- a/libdtrace/dt_bpf.h
+++ b/libdtrace/dt_bpf.h
@@ -32,30 +32,28 @@ extern "C" {
(dtp)->dt_bpffeatures |= (feat); \
} while (0)
-#define DT_CONST_EPID 1
-#define DT_CONST_PRID 2
-#define DT_CONST_CLID 3
-#define DT_CONST_ARGC 4
-#define DT_CONST_STBSZ 5
-#define DT_CONST_STRSZ 6
-#define DT_CONST_STKSIZ 7
-#define DT_CONST_BOOTTM 8
-#define DT_CONST_NSPEC 9
-#define DT_CONST_NCPUS 10
-#define DT_CONST_PC 11
-#define DT_CONST_TUPSZ 12
-#define DT_CONST_TASK_PID 13
-#define DT_CONST_TASK_TGID 14
-#define DT_CONST_TASK_REAL_PARENT 15
-#define DT_CONST_TASK_COMM 16
-#define DT_CONST_MUTEX_OWNER 17
-#define DT_CONST_RWLOCK_CNTS 18
-#define DT_CONST_DCTX_RODATA 19
-#define DT_CONST_RODATA_OFF 20
-#define DT_CONST_RODATA_SIZE 21
-#define DT_CONST_ZERO_OFF 22
-#define DT_CONST_STACK_OFF 23
-#define DT_CONST_STACK_SKIP 24
+#define DT_CONST_PRID 1
+#define DT_CONST_ARGC 2
+#define DT_CONST_STBSZ 3
+#define DT_CONST_STRSZ 4
+#define DT_CONST_STKSIZ 5
+#define DT_CONST_BOOTTM 6
+#define DT_CONST_NSPEC 7
+#define DT_CONST_NCPUS 8
+#define DT_CONST_PC 9
+#define DT_CONST_TUPSZ 10
+#define DT_CONST_TASK_PID 11
+#define DT_CONST_TASK_TGID 12
+#define DT_CONST_TASK_REAL_PARENT 13
+#define DT_CONST_TASK_COMM 14
+#define DT_CONST_MUTEX_OWNER 15
+#define DT_CONST_RWLOCK_CNTS 16
+#define DT_CONST_DCTX_RODATA 17
+#define DT_CONST_RODATA_OFF 18
+#define DT_CONST_RODATA_SIZE 19
+#define DT_CONST_ZERO_OFF 20
+#define DT_CONST_STACK_OFF 21
+#define DT_CONST_STACK_SKIP 22
#define DT_BPF_LOG_SIZE_DEFAULT (UINT32_MAX >> 8)
#define DT_BPF_LOG_SIZE_SMALL 4096
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index d1ee38431..4202771a9 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -123,6 +123,7 @@ dt_stmt_create(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp,
if (sdp == NULL)
longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
+ sdp->dtsd_id = dtp->dt_stmt_nextid++;
assert(yypcb->pcb_stmt == NULL);
yypcb->pcb_stmt = sdp;
yypcb->pcb_maxrecs = 0;
@@ -133,11 +134,10 @@ dt_stmt_create(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp,
return sdp;
}
-static dt_ident_t *
-dt_clause_create(dtrace_hdl_t *dtp, dtrace_difo_t *dp)
+static void
+dt_stmt_set_clause(dtrace_hdl_t *dtp, dtrace_difo_t *dp, dtrace_stmtdesc_t *sdp)
{
char *name;
- int len;
dt_ident_t *idp;
/*
@@ -156,25 +156,21 @@ dt_clause_create(dtrace_hdl_t *dtp, dtrace_difo_t *dp)
/*
* Generate a symbol name.
*/
- len = snprintf(NULL, 0, "dt_clause_%d", dtp->dt_clause_nextid) + 1;
- name = dt_alloc(dtp, len);
- if (name == NULL)
+ if (asprintf(&name, "dt_clause_%d", sdp->dtsd_id) < 0)
longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
- snprintf(name, len, "dt_clause_%d", dtp->dt_clause_nextid++);
-
/*
* Add the symbol to the BPF identifier table and associate the DIFO
* with the symbol.
*/
idp = dt_dlib_add_func(dtp, name);
- dt_free(dtp, name);
+ free(name);
if (idp == NULL)
longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
dt_ident_set_data(idp, dp);
- return idp;
+ sdp->dtsd_clause = idp;
}
static void
@@ -214,7 +210,7 @@ dt_compile_one_clause(dtrace_hdl_t *dtp, dt_node_t *cnp, dt_node_t *pnp)
* Compile the clause (predicate and action).
*/
dt_cg(yypcb, cnp);
- sdp->dtsd_clause = dt_clause_create(dtp, dt_as(yypcb));
+ dt_stmt_set_clause(dtp, dt_as(yypcb), sdp);
assert(yypcb->pcb_stmt == sdp);
if (dtrace_stmt_add(yypcb->pcb_hdl, yypcb->pcb_prog, sdp) != 0)
@@ -947,7 +943,7 @@ static int get_boottime() {
static int
dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
dt_ident_t *idp, const dtrace_difo_t *sdp, uint_t *pcp,
- uint_t *rcp, uint_t *vcp, dtrace_epid_t epid, uint_t clid)
+ uint_t *rcp, uint_t *vcp)
{
uint_t pc = *pcp;
uint_t rc = *rcp;
@@ -958,7 +954,6 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
uint_t len = sdp->dtdo_brelen;
const dof_relodesc_t *rp = sdp->dtdo_breltab;
dof_relodesc_t *nrp = &dp->dtdo_breltab[rc];
- dtrace_id_t prid = prp->desc->id;
int no_deps = 0;
if (idp != NULL) {
@@ -1029,7 +1024,6 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
for (; len != 0; len--, rp++, nrp++) {
const char *name = dt_difo_getstr(sdp, rp->dofr_name);
dtrace_difo_t *rdp;
- dtrace_epid_t nepid;
int ipc;
idp = dt_dlib_get_sym(dtp, name);
@@ -1044,15 +1038,9 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
}
switch (idp->di_id) {
- case DT_CONST_EPID:
- nrp->dofr_data = epid;
- continue;
case DT_CONST_PRID:
nrp->dofr_data = prp->desc->id;
continue;
- case DT_CONST_CLID:
- nrp->dofr_data = clid;
- continue;
case DT_CONST_ARGC:
nrp->dofr_data = 0; /* FIXME */
continue;
@@ -1196,11 +1184,6 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
case DT_CONST_STACK_SKIP:
nrp->dofr_data = prp->prov->impl->stack_skip;
continue;
- default:
- /* probe name -> value is probe id */
- if (strchr(idp->di_name, ':') != NULL)
- prid = rp->dofr_data;
- continue;
}
continue;
@@ -1216,13 +1199,8 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
rdp = dt_dlib_get_func_difo(dtp, idp);
if (rdp == NULL)
return -1;
- if (rdp->dtdo_ddesc != NULL) {
- nepid = dt_epid_add(dtp, rdp->dtdo_ddesc, prid);
- clid++;
- } else
- nepid = 0;
ipc = dt_link_construct(dtp, prp, dp, idp, rdp, pcp,
- rcp, vcp, nepid, clid);
+ rcp, vcp);
if (ipc == -1)
return -1;
@@ -1263,8 +1241,8 @@ dt_link_resolve(dtrace_hdl_t *dtp, dtrace_difo_t *dp)
continue;
/*
- * We are only relocating constants (EPID and ARGC) and call
- * instructions to functions that have been linked in.
+ * We are only relocating constants and call instructions to
+ * functions that have been linked in.
*/
switch (idp->di_kind) {
case DT_IDENT_SCALAR:
@@ -1336,8 +1314,7 @@ dt_link(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
*/
insc = relc = varc = 0;
- rc = dt_link_construct(dtp, prp, fdp, idp, dp, &insc, &relc, &varc, 0,
- 0);
+ rc = dt_link_construct(dtp, prp, fdp, idp, dp, &insc, &relc, &varc);
dt_dlib_reset(dtp, B_FALSE);
if (rc == -1)
goto fail;
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index f6c88c5ca..39c27ab0e 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -277,15 +277,9 @@ dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act)
* buf = rc + roundup(sizeof(dt_mstate_t), 8);
* // add %r0, roundup(
* sizeof(dt_mstate_t), 8)
- * *((uint64_t *)&buf[0]) = 0;
- * // stdw [%r0 + 0], 0
- * buf += 8; // add %r0, 8
- * // (%r0 = pointer to buffer space)
* dctx.buf = buf; // stdw [%r9 + DCTX_BUF], %r0
*/
emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, roundup(sizeof(dt_mstate_t), 8)));
- emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_0, 0, 0));
- emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8));
emit(dlp, BPF_STORE(BPF_DW, BPF_REG_9, DCTX_BUF, BPF_REG_0));
/*
@@ -1047,8 +1041,9 @@ dt_cg_tramp_error(dt_pcb_t *pcb)
*
* - Store the base pointer to the output data buffer in %r9.
* - Initialize the machine state (dctx->mst).
- * - Store the epid at [%r9 + DBUF_EPID].
* - Store 0 to indicate no active speculation at [%r9 + DBUF_SPECID].
+ * - Store the prid at [%r9 + DBUF_PRID].
+ * - Store the stid at [%r9 + DBUF_STID].
* - Evaluate the predicate expression and return if false.
*
* The dt_program() function will always return 0.
@@ -1057,11 +1052,6 @@ static void
dt_cg_prologue(dt_pcb_t *pcb, dt_node_t *pred)
{
dt_irlist_t *dlp = &pcb->pcb_ir;
- dt_ident_t *epid = dt_dlib_get_var(pcb->pcb_hdl, "EPID");
- dt_ident_t *clid = dt_dlib_get_var(pcb->pcb_hdl, "CLID");
-
- assert(epid != NULL);
- assert(clid != NULL);
/*
* void dt_program(dt_dctx_t *dctx)
@@ -1093,18 +1083,13 @@ dt_cg_prologue(dt_pcb_t *pcb, dt_node_t *pred)
* // stdw [%r0 + DMST_FAULT], 0
* dctx->mst->tstamp = 0; // stdw [%r0 + DMST_TSTAMP], 0
* dctx->mst->specsize = 0;// stdw [%r0 + DMST_SPECSIZE], 0
- * dctx->mst->epid = EPID; // stw [%r0 + DMST_EPID], EPID
- * dctx->mst->clid = CLID; // stw [%r0 + DMST_CLID], CLID
- * *((uint32_t *)&buf[DBUF_EPID]) = EPID;
- * // stw [%r9 + DBUF_EPID], EPID
+ * dctx->mst->stid = STID; // stw [%r0 + DMST_STID], STID
*/
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_0, DCTX_MST));
emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_0, DMST_FAULT, 0));
emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_0, DMST_TSTAMP, 0));
emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_0, DMST_SPECSIZE, 0));
- emite(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_0, DMST_EPID, -1), epid);
- emite(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_0, DMST_CLID, -1), clid);
- emite(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_9, DBUF_EPID, -1), epid);
+ emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_0, DMST_STID, pcb->pcb_stmt->dtsd_id));
/*
* Set the speculation ID field to zero to indicate no active
@@ -1114,6 +1099,17 @@ dt_cg_prologue(dt_pcb_t *pcb, dt_node_t *pred)
*/
emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_9, DBUF_SPECID, 0));
+ /*
+ * *((uint32_t *)&buf[DBUF_PRID]) = dctx->mst->prid;
+ * // ld %r1, [%r0 + DMST_PRID]
+ * // st [%r9 + DBUF_PRID], %r1
+ * *((uint32_t *)&buf[DBUF_STID]) = stid;
+ * // st [%r9 + DBUF_STID], stid
+ */
+ emit (dlp, BPF_LOAD(BPF_W, BPF_REG_1, BPF_REG_0, DMST_PRID));
+ emit (dlp, BPF_STORE(BPF_W, BPF_REG_9, DBUF_PRID, BPF_REG_1));
+ emit (dlp, BPF_STORE_IMM(BPF_W, BPF_REG_9, DBUF_STID, pcb->pcb_stmt->dtsd_id));
+
/*
* If there is a predicate:
*
@@ -1132,10 +1128,9 @@ dt_cg_prologue(dt_pcb_t *pcb, dt_node_t *pred)
TRACE_REGSET("Prologue: End ");
/*
- * Account for 32-bit EPID (at offset 0) and 32-bit speculation ID (at
- * offset 4).
+ * Set the offset for the beginning of trace data.
*/
- pcb->pcb_bufoff += 2 * sizeof(uint32_t);
+ pcb->pcb_bufoff = DBUF_DATA;
}
/*
@@ -1170,15 +1165,15 @@ dt_cg_epilogue(dt_pcb_t *pcb)
/*
* rc = bpf_perf_event_output(dctx->ctx, &buffers,
* BPF_F_CURRENT_CPU,
- * buf - 4, bufoff + 4);
+ * buf + 4, bufoff - 4);
* // lddw %r1, [%fp + DT_STK_DCTX]
* // lddw %r1, [%r1 + DCTX_CTX]
* // lddw %r2, &buffers
* // lddw %r3, BPF_F_CURRENT_CPU
* // mov %r4, %r9
- * // add %r4, -4
+ * // add %r4, 4
* // mov %r5, pcb->pcb_bufoff
- * // add %r5, 4
+ * // add %r5, -4
* // call bpf_perf_event_output
*/
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_FP, DT_STK_DCTX));
@@ -1186,9 +1181,9 @@ dt_cg_epilogue(dt_pcb_t *pcb)
dt_cg_xsetx(dlp, buffers, DT_LBL_NONE, BPF_REG_2, buffers->di_id);
dt_cg_xsetx(dlp, NULL, DT_LBL_NONE, BPF_REG_3, BPF_F_CURRENT_CPU);
emit(dlp, BPF_MOV_REG(BPF_REG_4, BPF_REG_9));
- emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -4));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4));
emit(dlp, BPF_MOV_IMM(BPF_REG_5, pcb->pcb_bufoff));
- emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 4));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -4));
emit(dlp, BPF_CALL_HELPER(BPF_FUNC_perf_event_output));
/*
diff --git a/libdtrace/dt_consume.c b/libdtrace/dt_consume.c
index 6d93613d4..3e8e1b465 100644
--- a/libdtrace/dt_consume.c
+++ b/libdtrace/dt_consume.c
@@ -15,9 +15,11 @@
#include <alloca.h>
#include <dt_impl.h>
#include <dt_aggregate.h>
+#include <dt_dctx.h>
#include <dt_module.h>
#include <dt_pcap.h>
#include <dt_peb.h>
+#include <dt_probe.h>
#include <dt_state.h>
#include <dt_string.h>
#include <libproc.h>
@@ -433,7 +435,7 @@ static dt_htab_ops_t dt_spec_buf_htab_ops = {
};
static int
-dt_flowindent(dtrace_hdl_t *dtp, dtrace_probedata_t *data, dtrace_epid_t last)
+dt_flowindent(dtrace_hdl_t *dtp, dtrace_probedata_t *data, dtrace_id_t lastprid, dtrace_stid_t laststid)
{
dtrace_probedesc_t *pd = data->dtpda_pdesc;
dtrace_flowkind_t flow = DTRACEFLOW_NONE;
@@ -445,7 +447,7 @@ dt_flowindent(dtrace_hdl_t *dtp, dtrace_probedata_t *data, dtrace_epid_t last)
static const char *r_str[2] = { " <- ", " <= " };
static const char *ent = "entry", *ret = "return";
static int entlen = 0, retlen = 0;
- dtrace_epid_t id = data->dtpda_epid;
+ dtrace_stid_t stid = data->dtpda_stid;
if (entlen == 0) {
assert(retlen == 0);
@@ -473,13 +475,12 @@ dt_flowindent(dtrace_hdl_t *dtp, dtrace_probedata_t *data, dtrace_epid_t last)
/*
* If we're going to indent this, we need to check the ID of our last
- * call. If we're looking at the same probe ID but a different EPID,
+ * call. If we're looking at the same probe ID but a different STID,
* we _don't_ want to indent. (Yes, there are some minor holes in
* this scheme -- it's a heuristic.)
*/
if (flow == DTRACEFLOW_ENTRY) {
- if (last != DTRACE_EPIDNONE && id != last &&
- pd->id == dtp->dt_pdesc[last]->id)
+ if (stid != laststid && pd->id == lastprid)
flow = DTRACEFLOW_NONE;
}
@@ -2145,8 +2146,8 @@ static dtrace_workstatus_t
dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
dtrace_probedata_t *pdat, dtrace_consume_probe_f *efunc,
dtrace_consume_rec_f *rfunc, int flow, int quiet,
- int peekflags, dtrace_epid_t *last, int committing,
- void *arg);
+ int peekflags, dtrace_id_t *lastprid,
+ dtrace_stid_t *laststid, int committing, void *arg);
/*
* Commit one speculation.
@@ -2155,7 +2156,8 @@ static dtrace_workstatus_t
dt_commit_one_spec(dtrace_hdl_t *dtp, FILE *fp, dt_spec_buf_t *dtsb,
dtrace_probedata_t *pdat, dtrace_consume_probe_f *efunc,
dtrace_consume_rec_f *rfunc, int flow, int quiet,
- int peekflags, dtrace_epid_t *last, void *arg)
+ int peekflags, dtrace_id_t *lastprid,
+ dtrace_stid_t *laststid, void *arg)
{
dt_spec_buf_data_t *dsbd;
@@ -2169,7 +2171,7 @@ dt_commit_one_spec(dtrace_hdl_t *dtp, FILE *fp, dt_spec_buf_t *dtsb,
ret = dt_consume_one_probe(dtp, fp, dsbd->dsbd_data,
dsbd->dsbd_size, &specpdat,
efunc, rfunc, flow, quiet,
- peekflags, last, 1, arg);
+ peekflags, lastprid, laststid, 1, arg);
if (ret != DTRACE_WORKSTATUS_OKAY)
return ret;
}
@@ -2181,34 +2183,33 @@ static dtrace_workstatus_t
dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
dtrace_probedata_t *pdat, dtrace_consume_probe_f *efunc,
dtrace_consume_rec_f *rfunc, int flow, int quiet,
- int peekflags, dtrace_epid_t *last, int committing,
- void *arg)
+ int peekflags, dtrace_id_t *lastprid,
+ dtrace_stid_t *laststid, int committing, void *arg)
{
- dtrace_epid_t epid;
+ dtrace_specid_t specid;
+ dtrace_id_t prid;
+ dtrace_stid_t stid;
dtrace_datadesc_t *epd;
dt_spec_buf_t tmpl;
dt_spec_buf_t *dtsb;
- int specid;
int i;
int rval;
dtrace_workstatus_t ret;
int commit_discard_seen, only_commit_discards;
int data_recording = 1;
- epid = ((uint32_t *)data)[0];
- specid = ((uint32_t *)data)[1];
+ specid = *((dtrace_specid_t *)(data + DBUF_SPECID));
+ prid = *((dtrace_id_t *)(data + DBUF_PRID));
+ stid = *((dtrace_stid_t *)(data + DBUF_STID));
- /*
- * Fill in the epid and address of the epid in the buffer. We need to
- * pass this to the efunc and possibly to create speculations.
- */
- pdat->dtpda_epid = epid;
+ pdat->dtpda_stid = stid;
pdat->dtpda_data = data;
- rval = dt_epid_lookup(dtp, epid, &pdat->dtpda_ddesc,
- &pdat->dtpda_pdesc);
- if (rval != 0)
- return dt_set_errno(dtp, EDT_BADEPID);
+ if (prid > dtp->dt_probe_id)
+ return dt_set_errno(dtp, EDT_BADID);
+ pdat->dtpda_pdesc = (dtrace_probedesc_t *)dtp->dt_probes[prid]->desc;
+ if (dt_stid_lookup(dtp, stid, &pdat->dtpda_ddesc) != 0)
+ return dt_set_errno(dtp, EDT_BADSTID);
epd = pdat->dtpda_ddesc;
if (epd->dtdd_uarg != DT_ECB_DEFAULT) {
@@ -2306,7 +2307,7 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
if (data_recording) {
if (flow)
- dt_flowindent(dtp, pdat, *last);
+ dt_flowindent(dtp, pdat, *lastprid, *laststid);
rval = (*efunc)(pdat, arg);
@@ -2569,14 +2570,15 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
}
/*
- * Call the record callback with a NULL record to indicate
- * that we're done processing this EPID. The return value is ignored in
- * this case. XXX should we respect at least DTRACE_CONSUME_ABORT?
+ * Call the record callback with a NULL record to indicate that we're
+ * done processing this record. The return value is ignored in this
+ * case. XXX should we respect at least DTRACE_CONSUME_ABORT?
*/
if (data_recording) {
(*rfunc)(pdat, NULL, arg);
- *last = epid;
+ *lastprid = prid;
+ *laststid = stid;
}
/*
@@ -2597,7 +2599,7 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
if ((ret = dt_commit_one_spec(dtp, fp, dtsb,
pdat, efunc, rfunc,
flow, quiet, peekflags,
- last, arg)) !=
+ lastprid, laststid, arg)) !=
DTRACE_WORKSTATUS_OKAY) {
dt_spec_buf_data_destroy(dtp, dtsb);
return ret;
@@ -2623,7 +2625,7 @@ static dtrace_workstatus_t
dt_consume_one(dtrace_hdl_t *dtp, FILE *fp, char *buf,
dtrace_probedata_t *pdat, dtrace_consume_probe_f *efunc,
dtrace_consume_rec_f *rfunc, int flow, int quiet, int peekflags,
- dtrace_epid_t *last, void *arg)
+ dtrace_id_t *lastprid, dtrace_stid_t *laststid, void *arg)
{
char *data = buf;
struct perf_event_header *hdr;
@@ -2639,9 +2641,9 @@ dt_consume_one(dtrace_hdl_t *dtp, FILE *fp, char *buf,
* struct {
* struct perf_event_header header;
* uint32_t size;
- * uint32_t pad;
- * uint32_t epid;
* uint32_t specid;
+ * uint32_t prid;
+ * uint32_t stid;
* uint64_t data[n];
* }
* and 'data' points to the 'size' member at this point.
@@ -2651,17 +2653,21 @@ dt_consume_one(dtrace_hdl_t *dtp, FILE *fp, char *buf,
return dt_set_errno(dtp, EDT_DSIZE);
size = *(uint32_t *)data;
- data += sizeof(size);
ptr += sizeof(size) + size;
if (ptr != buf + hdr->size)
return dt_set_errno(dtp, EDT_DSIZE);
- data += sizeof(uint32_t); /* skip padding */
- size -= sizeof(uint32_t);
+ /*
+ * "size" measures from after &size to the end. But buffer
+ * offsets are relative to &size itself, to preserve 8-byte
+ * alignment. So, we leave data pointing at &size, and we
+ * increase size by 4 bytes.
+ */
+ size += 4;
return dt_consume_one_probe(dtp, fp, data, size, pdat, efunc,
rfunc, flow, quiet, peekflags,
- last, 0, arg);
+ lastprid, laststid, 0, arg);
} else if (hdr->type == PERF_RECORD_LOST) {
return DTRACE_WORKSTATUS_OKAY;
} else
@@ -2692,7 +2698,8 @@ dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, dt_peb_t *peb,
{
struct perf_event_mmap_page *rb_page = (void *)peb->base;
struct perf_event_header *hdr;
- dtrace_epid_t last = DTRACE_EPIDNONE;
+ dtrace_id_t lastprid;
+ dtrace_stid_t laststid;
char *base;
char *event;
uint32_t len;
@@ -2764,7 +2771,7 @@ dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, dt_peb_t *peb,
}
rval = dt_consume_one(dtp, fp, event, &pdat, efunc, rfunc, flow,
- quiet, peekflags, &last, arg);
+ quiet, peekflags, &lastprid, &laststid, arg);
if (rval == DTRACE_WORKSTATUS_DONE)
return DTRACE_WORKSTATUS_OKAY;
if (rval != DTRACE_WORKSTATUS_OKAY)
diff --git a/libdtrace/dt_dctx.h b/libdtrace/dt_dctx.h
index d8232868d..beb037072 100644
--- a/libdtrace/dt_dctx.h
+++ b/libdtrace/dt_dctx.h
@@ -25,9 +25,8 @@
* The DTrace machine state.
*/
typedef struct dt_mstate {
- uint32_t epid; /* Enabled probe ID */
uint32_t prid; /* Probe ID */
- uint32_t clid; /* Clause ID (unique per probe) */
+ uint32_t stid; /* Statement ID */
uint32_t tag; /* Tag (for future use) */
uint32_t scratch_top; /* Current top of scratch space */
int32_t syscall_errno; /* syscall errno */
@@ -41,9 +40,8 @@ typedef struct dt_mstate {
uint64_t saved_argv[6]; /* Saved arguments */
} dt_mstate_t;
-#define DMST_EPID offsetof(dt_mstate_t, epid)
#define DMST_PRID offsetof(dt_mstate_t, prid)
-#define DMST_CLID offsetof(dt_mstate_t, clid)
+#define DMST_STID offsetof(dt_mstate_t, stid)
#define DMST_TAG offsetof(dt_mstate_t, tag)
#define DMST_SCRATCH_TOP offsetof(dt_mstate_t, scratch_top)
#define DMST_ERRNO offsetof(dt_mstate_t, syscall_errno)
@@ -90,16 +88,23 @@ typedef struct dt_dctx {
* The dctx->buf pointer references a block of memory that contains:
*
* +----------------+
- * 0 -> | EPID |
+ * 0 -> | size |
* +----------------+
- * 4 -> | Speculation ID |
+ * 4 -> | Speculation ID |
* +----------------+
- * | Trace Data |
+ * 8 -> | PRID |
+ * +----------------+
+ * 12 -> | STID |
+ * +----------------+
+ * 16 -> | Trace Data |
* | ... |
* +----------------+
*/
-#define DBUF_EPID 0
+#define DBUF_SIZE 0
#define DBUF_SPECID 4
+#define DBUF_PRID 8
+#define DBUF_STID 12
+#define DBUF_DATA 16
/*
* The dctx->mem pointer references a block of memory that contains:
diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
index bc883e110..ba4d4abef 100644
--- a/libdtrace/dt_dlibs.c
+++ b/libdtrace/dt_dlibs.c
@@ -73,9 +73,7 @@ static const dt_ident_t dt_bpf_symbols[] = {
DT_BPF_SYMBOL(tuples, DT_IDENT_PTR),
/* BPF internal identifiers */
- DT_BPF_SYMBOL_ID(EPID, DT_IDENT_SCALAR, DT_CONST_EPID),
DT_BPF_SYMBOL_ID(PRID, DT_IDENT_SCALAR, DT_CONST_PRID),
- DT_BPF_SYMBOL_ID(CLID, DT_IDENT_SCALAR, DT_CONST_CLID),
DT_BPF_SYMBOL_ID(ARGC, DT_IDENT_SCALAR, DT_CONST_ARGC),
DT_BPF_SYMBOL_ID(STBSZ, DT_IDENT_SCALAR, DT_CONST_STBSZ),
DT_BPF_SYMBOL_ID(STRSZ, DT_IDENT_SCALAR, DT_CONST_STRSZ),
diff --git a/libdtrace/dt_error.c b/libdtrace/dt_error.c
index dbf18c766..16a605d3f 100644
--- a/libdtrace/dt_error.c
+++ b/libdtrace/dt_error.c
@@ -54,7 +54,7 @@ static const struct {
{ EDT_DOFFSET, "Data record offset exceeds buffer boundary" },
{ EDT_DALIGN, "Data record has inappropriate alignment" },
{ EDT_DSIZE, "Data record has incorrect size" },
- { EDT_BADEPID, "Invalid EPID" },
+ { EDT_BADSTID, "Invalid statement ID" },
{ EDT_BADOPTNAME, "Invalid option name" },
{ EDT_BADOPTVAL, "Invalid value for specified option" },
{ EDT_BADOPTCTX, "Option cannot be used from within a D program" },
diff --git a/libdtrace/dt_handle.c b/libdtrace/dt_handle.c
index 4c9b94132..09fae99c3 100644
--- a/libdtrace/dt_handle.c
+++ b/libdtrace/dt_handle.c
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
@@ -14,6 +14,7 @@
#include <alloca.h>
#include <dt_impl.h>
+#include <dt_probe.h>
#include <dt_program.h>
static const char _dt_errprog[] =
@@ -126,16 +127,13 @@ dt_handle_err(dtrace_hdl_t *dtp, dtrace_probedata_t *data)
{
dtrace_datadesc_t *dd = data->dtpda_ddesc, *errdd;
dtrace_probedesc_t *pd = data->dtpda_pdesc, *errpd;
+ dtrace_stmtdesc_t *stp;
dtrace_errdata_t err;
- dtrace_epid_t epid;
+ dtrace_id_t prid;
+ dtrace_stid_t stid;
- char where[30];
- char details[30];
- char offinfo[30];
- const int slop = 80;
- const char *faultstr;
- char *str;
- int len;
+ char *str, *details, *offinfo;
+ int rc = 0;
assert(dd->dtdd_uarg == DT_ECB_ERROR);
@@ -144,38 +142,29 @@ dt_handle_err(dtrace_hdl_t *dtp, dtrace_probedata_t *data)
return dt_set_errno(dtp, EDT_BADERROR);
/*
- * This is an error. We have the following items here: EPID,
- * faulting action, BPF pc, fault code and faulting address.
+ * This is an error. We have the following items here: PRID,
+ * statement ID, BPF pc, fault code and faulting address.
*/
- epid = (uint32_t)DT_REC(uint64_t, 0);
+ prid = DT_REC(uint64_t, 0);
+ stid = DT_REC(uint64_t, 1);
- if (dt_epid_lookup(dtp, epid, &errdd, &errpd) != 0)
+ if (prid > dtp->dt_probe_id)
return dt_set_errno(dtp, EDT_BADERROR);
-
+ if (dt_stid_lookup(dtp, stid, &errdd) != 0)
+ return dt_set_errno(dtp, EDT_BADERROR);
+ errpd = (dtrace_probedesc_t *)dtp->dt_probes[prid]->desc;
err.dteda_ddesc = errdd;
err.dteda_pdesc = errpd;
err.dteda_cpu = data->dtpda_cpu;
- err.dteda_action = (int)DT_REC(uint64_t, 1);
+ err.dteda_action = stid;
err.dteda_offset = (int)DT_REC(uint64_t, 2);
err.dteda_fault = (int)DT_REC(uint64_t, 3);
err.dteda_addr = DT_REC(uint64_t, 4);
- faultstr = dtrace_faultstr(dtp, err.dteda_fault);
- len = sizeof(where) + sizeof(offinfo) + strlen(faultstr) +
- strlen(errpd->prv) + strlen(errpd->mod) + strlen(errpd->fun) +
- strlen(errpd->prb) + slop;
-
- str = (char *)alloca(len);
-
- if (err.dteda_action == 0)
- sprintf(where, "predicate");
- else
- sprintf(where, "action #%d", err.dteda_action);
-
if (err.dteda_offset != -1)
- sprintf(offinfo, " at BPF pc %d", err.dteda_offset);
+ asprintf(&offinfo, " at BPF pc %d", err.dteda_offset);
else
- offinfo[0] = 0;
+ offinfo = "";
switch (err.dteda_fault) {
case DTRACEFLT_BADADDR:
@@ -184,32 +173,38 @@ dt_handle_err(dtrace_hdl_t *dtp, dtrace_probedata_t *data)
case DTRACEFLT_BADALIGN:
case DTRACEFLT_BADSTACK:
case DTRACEFLT_BADSIZE:
- sprintf(details, " (0x%llx)", (unsigned long long)err.dteda_addr);
+ asprintf(&details, " (0x%llx)", (unsigned long long)err.dteda_addr);
break;
case DTRACEFLT_BADINDEX:
- sprintf(details, " (%ld)", (int64_t)err.dteda_addr);
+ asprintf(&details, " (%ld)", (int64_t)err.dteda_addr);
break;
default:
no_addr:
- details[0] = 0;
+ details = "";
}
- snprintf(str, len, "error on enabled probe ID %u (ID %u: %s:%s:%s:%s): "
- "%s%s in %s%s",
- epid, errpd->id, errpd->prv, errpd->mod, errpd->fun,
- errpd->prb, dtrace_faultstr(dtp, err.dteda_fault), details,
- where, offinfo);
+ stp = dtp->dt_stmts[stid];
+ assert(stp != NULL);
+ asprintf(&str, "error in %s for probe ID %u (%s:%s:%s:%s): %s%s%s",
+ stp->dtsd_clause->di_name, errpd->id, errpd->prv, errpd->mod,
+ errpd->fun, errpd->prb, dtrace_faultstr(dtp, err.dteda_fault),
+ details, offinfo);
err.dteda_msg = str;
if (dtp->dt_errhdlr == NULL)
- return dt_set_errno(dtp, EDT_ERRABORT);
+ rc = dt_set_errno(dtp, EDT_ERRABORT);
+ else if ((*dtp->dt_errhdlr)(&err, dtp->dt_errarg) == DTRACE_HANDLE_ABORT)
+ rc = dt_set_errno(dtp, EDT_ERRABORT);
- if ((*dtp->dt_errhdlr)(&err, dtp->dt_errarg) == DTRACE_HANDLE_ABORT)
- return dt_set_errno(dtp, EDT_ERRABORT);
+ free(str);
+ if (offinfo[0] != 0)
+ free(offinfo);
+ if (details[0] != 0)
+ free(details);
- return 0;
+ return rc;
}
int
@@ -237,10 +232,10 @@ dt_handle_liberr(dtrace_hdl_t *dtp, const dtrace_probedata_t *data,
const char *faultstr)
{
dtrace_probedesc_t *errpd = data->dtpda_pdesc;
+ dtrace_stmtdesc_t *stp;
dtrace_errdata_t err;
- const int slop = 80;
char *str;
- int len;
+ int rc = 0;
err.dteda_ddesc = data->dtpda_ddesc;
err.dteda_pdesc = errpd;
@@ -250,25 +245,23 @@ dt_handle_liberr(dtrace_hdl_t *dtp, const dtrace_probedata_t *data,
err.dteda_fault = DTRACEFLT_LIBRARY;
err.dteda_addr = 0; /* == NULL */
- len = strlen(faultstr) + strlen(errpd->prv) + strlen(errpd->mod) +
- strlen(errpd->fun) + strlen(errpd->prb) + slop;
-
- str = alloca(len);
-
- snprintf(str, len,
- "error on enabled probe ID %u (ID %u: %s:%s:%s:%s): %s",
- data->dtpda_epid, errpd->id, errpd->prv, errpd->mod,
+ stp = dtp->dt_stmts[data->dtpda_stid];
+ assert(stp != NULL);
+ asprintf(&str,
+ "error in %s for probe ID %u (%s:%s:%s:%s): %s",
+ stp->dtsd_clause->di_name, errpd->id, errpd->prv, errpd->mod,
errpd->fun, errpd->prb, faultstr);
err.dteda_msg = str;
if (dtp->dt_errhdlr == NULL)
- return dt_set_errno(dtp, EDT_ERRABORT);
+ rc = dt_set_errno(dtp, EDT_ERRABORT);
+ else if ((*dtp->dt_errhdlr)(&err, dtp->dt_errarg) == DTRACE_HANDLE_ABORT)
+ rc = dt_set_errno(dtp, EDT_ERRABORT);
- if ((*dtp->dt_errhdlr)(&err, dtp->dt_errarg) == DTRACE_HANDLE_ABORT)
- return dt_set_errno(dtp, EDT_ERRABORT);
+ free(str);
- return 0;
+ return rc;
}
#define DROPTAG(x) x, #x
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index c13812c88..340dc1960 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -266,10 +266,11 @@ struct dtrace_hdl {
const char *dt_errtag; /* tag used with last call to dt_set_errmsg() */
dt_pcb_t *dt_pcb; /* pointer to current parsing control block */
ulong_t dt_gen; /* compiler generation number */
- uint_t dt_clause_nextid; /* next ID to use for programs */
+ uint_t dt_stmt_nextid; /* next ID to use for statements */
dt_list_t dt_programs; /* linked list of dtrace_prog_t's */
dt_list_t dt_xlators; /* linked list of dt_xlator_t's */
dt_list_t dt_enablings; /* list of (to be) enabled probes */
+ dtrace_stmtdesc_t **dt_stmts; /* array of stmts */
struct dt_xlator **dt_xlatormap; /* dt_xlator_t's indexed by dx_id */
id_t dt_xlatorid; /* next dt_xlator_t id to assign */
dt_ident_t *dt_externs; /* linked list of external symbol identifiers */
@@ -336,10 +337,6 @@ struct dtrace_hdl {
ctf_id_t dt_type_symaddr; /* cached CTF identifier for _symaddr type */
ctf_id_t dt_type_usymaddr; /* cached CTF ident. for _usymaddr type */
ctf_id_t dt_type_void; /* cached CTF identifier for void type */
- dtrace_epid_t dt_nextepid; /* next enabled probe ID to assign */
- size_t dt_maxprobe; /* max enabled probe ID */
- dtrace_datadesc_t **dt_ddesc; /* probe data descriptions */
- dtrace_probedesc_t **dt_pdesc; /* probe descriptions for enabled prbs */
size_t dt_maxagg; /* max aggregation ID */
dtrace_aggdesc_t **dt_adesc; /* aggregation descriptions */
struct dt_aggregate *dt_aggregate; /* aggregate */
@@ -599,7 +596,7 @@ enum {
EDT_DOFFSET, /* record data offset error */
EDT_DALIGN, /* record data alignment error */
EDT_DSIZE, /* record data size error */
- EDT_BADEPID, /* invalid enabled probe id */
+ EDT_BADSTID, /* invalid statement id */
EDT_BADOPTNAME, /* invalid dtrace_setopt option name */
EDT_BADOPTVAL, /* invalid dtrace_setopt option value */
EDT_BADOPTCTX, /* invalid dtrace_setopt option context */
@@ -766,11 +763,7 @@ extern dtrace_datadesc_t *dt_datadesc_hold(dtrace_datadesc_t *ddp);
extern void dt_datadesc_release(dtrace_hdl_t *, dtrace_datadesc_t *);
extern dtrace_datadesc_t *dt_datadesc_create(dtrace_hdl_t *);
extern int dt_datadesc_finalize(dtrace_hdl_t *, dtrace_datadesc_t *);
-extern dtrace_epid_t dt_epid_add(dtrace_hdl_t *, dtrace_datadesc_t *,
- dtrace_id_t);
-extern int dt_epid_lookup(dtrace_hdl_t *, dtrace_epid_t, dtrace_datadesc_t **,
- dtrace_probedesc_t **);
-extern void dt_epid_destroy(dtrace_hdl_t *);
+extern int dt_stid_lookup(dtrace_hdl_t *, dtrace_stid_t, dtrace_datadesc_t **);
typedef void (*dt_cg_gap_f)(dt_pcb_t *, int);
extern uint32_t dt_rec_add(dtrace_hdl_t *, dt_cg_gap_f, dtrace_actkind_t,
uint32_t, uint16_t, dt_pfargv_t *, uint64_t);
diff --git a/libdtrace/dt_map.c b/libdtrace/dt_map.c
index 60a2eca2e..9baf94d9a 100644
--- a/libdtrace/dt_map.c
+++ b/libdtrace/dt_map.c
@@ -85,98 +85,21 @@ dt_datadesc_finalize(dtrace_hdl_t *dtp, dtrace_datadesc_t *ddp)
return 0;
}
-/*
- * Associate a probe data description and probe description with an enabled
- * probe ID. This means that the given ID refers to the program matching the
- * probe data description being attached to the probe that matches the probe
- * description.
- */
-dtrace_epid_t
-dt_epid_add(dtrace_hdl_t *dtp, dtrace_datadesc_t *ddp, dtrace_id_t prid)
-{
- dtrace_id_t max = dtp->dt_maxprobe;
- dtrace_epid_t epid;
-
- epid = dtp->dt_nextepid++;
- if (epid >= max || dtp->dt_ddesc == NULL) {
- dtrace_id_t nmax = max ? (max << 1) : 2;
- dtrace_datadesc_t **nddesc;
- dtrace_probedesc_t **npdesc;
-
- nddesc = dt_calloc(dtp, nmax, sizeof(void *));
- npdesc = dt_calloc(dtp, nmax, sizeof(void *));
- if (nddesc == NULL || npdesc == NULL) {
- dt_free(dtp, nddesc);
- dt_free(dtp, npdesc);
- return dt_set_errno(dtp, EDT_NOMEM);
- }
-
- if (dtp->dt_ddesc != NULL) {
- size_t osize = max * sizeof(void *);
-
- memcpy(nddesc, dtp->dt_ddesc, osize);
- dt_free(dtp, dtp->dt_ddesc);
- memcpy(npdesc, dtp->dt_pdesc, osize);
- dt_free(dtp, dtp->dt_pdesc);
- }
-
- dtp->dt_ddesc = nddesc;
- dtp->dt_pdesc = npdesc;
- dtp->dt_maxprobe = nmax;
- }
-
- if (dtp->dt_ddesc[epid] != NULL)
- return epid;
-
- dtp->dt_ddesc[epid] = dt_datadesc_hold(ddp);
- dtp->dt_pdesc[epid] = (dtrace_probedesc_t *)dtp->dt_probes[prid]->desc;
-
- return epid;
-}
-
int
-dt_epid_lookup(dtrace_hdl_t *dtp, dtrace_epid_t epid, dtrace_datadesc_t **ddp,
- dtrace_probedesc_t **pdp)
+dt_stid_lookup(dtrace_hdl_t *dtp, dtrace_stid_t stid, dtrace_datadesc_t **ddp)
{
- if (epid >= dtp->dt_maxprobe ||
- dtp->dt_ddesc[epid] == NULL || dtp->dt_pdesc[epid] == NULL)
- return -1;
-
- *ddp = dtp->dt_ddesc[epid];
- *pdp = dtp->dt_pdesc[epid];
-
- return 0;
-}
-
-void
-dt_epid_destroy(dtrace_hdl_t *dtp)
-{
- size_t i;
-
- assert((dtp->dt_pdesc != NULL && dtp->dt_ddesc != NULL &&
- dtp->dt_maxprobe > 0) || (dtp->dt_pdesc == NULL &&
- dtp->dt_ddesc == NULL && dtp->dt_maxprobe == 0));
-
- if (dtp->dt_pdesc == NULL)
- return;
+ dtrace_difo_t *rdp;
+ dtrace_stmtdesc_t *stp;
- for (i = 0; i < dtp->dt_maxprobe; i++) {
- if (dtp->dt_ddesc[i] == NULL) {
- assert(dtp->dt_pdesc[i] == NULL);
- continue;
- }
-
- dt_datadesc_release(dtp, dtp->dt_ddesc[i]);
- assert(dtp->dt_pdesc[i] != NULL);
- }
+ if (stid >= dtp->dt_stmt_nextid)
+ return -1;
- free(dtp->dt_pdesc);
- dtp->dt_pdesc = NULL;
+ stp = dtp->dt_stmts[stid];
+ assert(stp != NULL);
+ rdp = dt_dlib_get_func_difo(dtp, stp->dtsd_clause);
+ *ddp = rdp->dtdo_ddesc;
- free(dtp->dt_ddesc);
- dtp->dt_ddesc = NULL;
- dtp->dt_nextepid = 0;
- dtp->dt_maxprobe = 0;
+ return (*ddp == NULL) ? -1 : 0;
}
uint32_t
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index 77ffb6d2b..848141ddc 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -170,7 +170,7 @@ static const dt_ident_t _dtrace_globals[] = {
{ "discard", DT_IDENT_ACTFUNC, 0, DT_ACT_DISCARD, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "void(int)" },
{ "epid", DT_IDENT_SCALAR, 0, DIF_VAR_EPID, DT_ATTR_STABCMN, DT_VERS_1_0,
- &dt_idops_type, "uint_t" },
+ &dt_idops_type, "uint64_t" },
{ "errno", DT_IDENT_SCALAR, 0, DIF_VAR_ERRNO, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_type, "int" },
{ "execname", DT_IDENT_SCALAR, 0, DIF_VAR_EXECNAME,
@@ -739,8 +739,6 @@ dt_vopen(int version, int flags, int *errp,
dt_proc_hash_create(dtp);
dt_proc_signal_init(dtp);
dtp->dt_proc_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
- dtp->dt_nextepid = 1;
- dtp->dt_maxprobe = 0;
if (dt_aggregate_init(dtp) == -1)
return set_open_errno(dtp, errp, dtrace_errno(dtp));
dtp->dt_vmax = DT_VERS_LATEST;
@@ -1303,7 +1301,6 @@ dtrace_close(dtrace_hdl_t *dtp)
if (dtp->dt_poll_fd != -1)
close(dtp->dt_poll_fd);
- dt_epid_destroy(dtp);
dt_aggid_destroy(dtp);
dt_buffered_destroy(dtp);
dt_aggregate_destroy(dtp);
diff --git a/libdtrace/dt_program.c b/libdtrace/dt_program.c
index 0e2c1e2af..a7c11bbae 100644
--- a/libdtrace/dt_program.c
+++ b/libdtrace/dt_program.c
@@ -100,7 +100,7 @@ dtrace_program_info(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
/*
* If there aren't any actions, account for the fact that
- * recording the epid will generate a record.
+ * the default action will generate a record.
*/
dp = dt_dlib_get_func_difo(dtp, stp->ds_desc->dtsd_clause);
if (dp != NULL)
@@ -165,6 +165,13 @@ dt_prog_stmt(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp,
dtrace_probedesc_t *pdp = &sdp->dtsd_ecbdesc->dted_probe;
int rc;
+ if (dtp->dt_stmts == NULL) {
+ dtp->dt_stmts = dt_calloc(dtp, dtp->dt_stmt_nextid, sizeof(dtrace_stmtdesc_t *));
+ if (dtp->dt_stmts == NULL)
+ return dt_set_errno(dtp, EDT_NOMEM);
+ }
+ dtp->dt_stmts[sdp->dtsd_id] = sdp;
+
st.cnt = cnt;
st.sdp = sdp;
rc = dt_probe_iter(dtp, pdp, (dt_probe_f *)dt_stmt_probe, NULL, &st);
diff --git a/libdtrace/dtrace.h b/libdtrace/dtrace.h
index 09a87977f..0f716cd40 100644
--- a/libdtrace/dtrace.h
+++ b/libdtrace/dtrace.h
@@ -150,6 +150,7 @@ typedef struct dtrace_stmtdesc {
dtrace_attribute_t dtsd_descattr; /* probedesc attributes */
dtrace_attribute_t dtsd_stmtattr; /* statement attributes */
int dtsd_clauseflags; /* clause flags */
+ int dtsd_id; /* index in dtp->dt_stmts */
} dtrace_stmtdesc_t;
/* dtsd clause flags */
@@ -189,7 +190,7 @@ typedef enum {
typedef struct dtrace_probedata {
dtrace_hdl_t *dtpda_handle; /* handle to DTrace library */
- dtrace_epid_t dtpda_epid; /* enabled probe ID */
+ dtrace_stid_t dtpda_stid; /* statement ID */
dtrace_datadesc_t *dtpda_ddesc; /* probe data description */
dtrace_probedesc_t *dtpda_pdesc; /* probe description */
unsigned int dtpda_cpu; /* CPU for data */
diff --git a/test/demo/builtin/eipd.d b/test/demo/builtin/eipd.d
deleted file mode 100644
index 659b09406..000000000
--- a/test/demo/builtin/eipd.d
+++ /dev/null
@@ -1,4 +0,0 @@
-BEGIN {
- trace(epid);
- exit(0);
-}
diff --git a/test/demo/dtrace/error.r b/test/demo/dtrace/error.r
index d3904f47a..3c434721a 100644
--- a/test/demo/dtrace/error.r
+++ b/test/demo/dtrace/error.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/demo/dtrace/error.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/demo/spec/specopen.d b/test/demo/spec/specopen.d
index 528d6c254..c510045b8 100644
--- a/test/demo/spec/specopen.d
+++ b/test/demo/spec/specopen.d
@@ -2,7 +2,7 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
@@ -33,8 +33,7 @@ fbt:::
/self->spec/
{
/*
- * A speculate() with no other actions speculates the default action:
- * tracing the EPID.
+ * A speculate() with no other actions speculates the default action.
*/
speculate(self->spec);
}
diff --git a/test/stress/buffering/tst.resize3-manual.d b/test/stress/buffering/tst.resize3-manual.d
index 99589beb0..56c8575dc 100644
--- a/test/stress/buffering/tst.resize3-manual.d
+++ b/test/stress/buffering/tst.resize3-manual.d
@@ -31,7 +31,7 @@ BEGIN
BEGIN
{
speculate(spec);
- trace(epid);
+ trace(12345678);
}
BEGIN
diff --git a/test/stress/buffering/tst.resize3-manual.r b/test/stress/buffering/tst.resize3-manual.r
index 43b647c7e..3a1fd5da6 100644
--- a/test/stress/buffering/tst.resize3-manual.r
+++ b/test/stress/buffering/tst.resize3-manual.r
@@ -1,5 +1,5 @@
FUNCTION:NAME
- :BEGIN 3
+ :BEGIN 12345678
:BEGIN
-- @@stderr --
diff --git a/test/stress/buffering/tst.resize3.d b/test/stress/buffering/tst.resize3.d
index 59fe0b4ae..464bf5660 100644
--- a/test/stress/buffering/tst.resize3.d
+++ b/test/stress/buffering/tst.resize3.d
@@ -27,7 +27,7 @@ BEGIN
BEGIN
{
speculate(spec);
- trace(epid);
+ trace(12345678);
}
BEGIN
diff --git a/test/stress/buffering/tst.resize3.r b/test/stress/buffering/tst.resize3.r
index 9c4711589..33384c717 100644
--- a/test/stress/buffering/tst.resize3.r
+++ b/test/stress/buffering/tst.resize3.r
@@ -1,5 +1,5 @@
FUNCTION:NAME
- :BEGIN 3
+ :BEGIN 12345678
:BEGIN
-- @@stderr --
diff --git a/test/unittest/actions/setopt/tst.badopt.r b/test/unittest/actions/setopt/tst.badopt.r
index 29e39fd43..e2f6d2c3d 100644
--- a/test/unittest/actions/setopt/tst.badopt.r
+++ b/test/unittest/actions/setopt/tst.badopt.r
@@ -1,16 +1,16 @@
-- @@stderr --
-dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "Nixon" to "1": Invalid option name
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): couldn't set option "Nixon" to "1": Invalid option name
-dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "Harding" to "1": Invalid option name
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): couldn't set option "Harding" to "1": Invalid option name
-dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "Hoover" to "1": Invalid option name
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): couldn't set option "Hoover" to "1": Invalid option name
-dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "Bush" to "1": Invalid option name
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): couldn't set option "Bush" to "1": Invalid option name
-dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "quiet" to "um, no": Invalid value for specified option
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): couldn't set option "quiet" to "um, no": Invalid value for specified option
-dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "aggrate" to "0.5hz": Invalid value for specified option
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): couldn't set option "aggrate" to "0.5hz": Invalid value for specified option
-dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): couldn't set option "bufsize" to "1m": Operation illegal when tracing is active
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): couldn't set option "bufsize" to "1m": Operation illegal when tracing is active
diff --git a/test/unittest/arrays/tst.declared-bounds.runtime_out.r b/test/unittest/arrays/tst.declared-bounds.runtime_out.r
index 4917528d5..9ab1ab8da 100644
--- a/test/unittest/arrays/tst.declared-bounds.runtime_out.r
+++ b/test/unittest/arrays/tst.declared-bounds.runtime_out.r
@@ -1,3 +1,3 @@
expected run-time error
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): index out of bounds (8) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): index out of bounds (8) at BPF pc NNN
diff --git a/test/unittest/codegen/err.deref_0.r b/test/unittest/codegen/err.deref_0.r
index 07c1dc52e..812ca4332 100644
--- a/test/unittest/codegen/err.deref_0.r
+++ b/test/unittest/codegen/err.deref_0.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address (0) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address (0) at BPF pc NNN
diff --git a/test/unittest/codegen/err.deref_1.r b/test/unittest/codegen/err.deref_1.r
index a2ca8ac48..01ca10375 100644
--- a/test/unittest/codegen/err.deref_1.r
+++ b/test/unittest/codegen/err.deref_1.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address (1) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address (1) at BPF pc NNN
diff --git a/test/unittest/codegen/err.deref_i0.r b/test/unittest/codegen/err.deref_i0.r
index 07c1dc52e..812ca4332 100644
--- a/test/unittest/codegen/err.deref_i0.r
+++ b/test/unittest/codegen/err.deref_i0.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address (0) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address (0) at BPF pc NNN
diff --git a/test/unittest/codegen/err.deref_i1.r b/test/unittest/codegen/err.deref_i1.r
index a2ca8ac48..01ca10375 100644
--- a/test/unittest/codegen/err.deref_i1.r
+++ b/test/unittest/codegen/err.deref_i1.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address (1) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address (1) at BPF pc NNN
diff --git a/test/unittest/codegen/err.deref_string-assoc.r b/test/unittest/codegen/err.deref_string-assoc.r
index 082779925..5d4a36fff 100644
--- a/test/unittest/codegen/err.deref_string-assoc.r
+++ b/test/unittest/codegen/err.deref_string-assoc.r
@@ -1,3 +1,3 @@
66
-- @@stderr --
-dtrace: error on enabled probe ID 4 (ID 1: dtrace:::BEGIN): invalid address (1) in action #2 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address (1) at BPF pc NNN
diff --git a/test/unittest/codegen/err.deref_string-gvar.r b/test/unittest/codegen/err.deref_string-gvar.r
index 082779925..5d4a36fff 100644
--- a/test/unittest/codegen/err.deref_string-gvar.r
+++ b/test/unittest/codegen/err.deref_string-gvar.r
@@ -1,3 +1,3 @@
66
-- @@stderr --
-dtrace: error on enabled probe ID 4 (ID 1: dtrace:::BEGIN): invalid address (1) in action #2 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address (1) at BPF pc NNN
diff --git a/test/unittest/codegen/err.deref_string-lvar.r b/test/unittest/codegen/err.deref_string-lvar.r
index 082779925..5d4a36fff 100644
--- a/test/unittest/codegen/err.deref_string-lvar.r
+++ b/test/unittest/codegen/err.deref_string-lvar.r
@@ -1,3 +1,3 @@
66
-- @@stderr --
-dtrace: error on enabled probe ID 4 (ID 1: dtrace:::BEGIN): invalid address (1) in action #2 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address (1) at BPF pc NNN
diff --git a/test/unittest/codegen/err.deref_string-tvar.r b/test/unittest/codegen/err.deref_string-tvar.r
index 082779925..5d4a36fff 100644
--- a/test/unittest/codegen/err.deref_string-tvar.r
+++ b/test/unittest/codegen/err.deref_string-tvar.r
@@ -1,3 +1,3 @@
66
-- @@stderr --
-dtrace: error on enabled probe ID 4 (ID 1: dtrace:::BEGIN): invalid address (1) in action #2 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address (1) at BPF pc NNN
diff --git a/test/unittest/codegen/err.str_NULL_plus_offset-assoc.r b/test/unittest/codegen/err.str_NULL_plus_offset-assoc.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/codegen/err.str_NULL_plus_offset-assoc.r
+++ b/test/unittest/codegen/err.str_NULL_plus_offset-assoc.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/codegen/err.str_NULL_plus_offset-lvar.r b/test/unittest/codegen/err.str_NULL_plus_offset-lvar.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/codegen/err.str_NULL_plus_offset-lvar.r
+++ b/test/unittest/codegen/err.str_NULL_plus_offset-lvar.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/codegen/err.str_NULL_plus_offset-tvar.r b/test/unittest/codegen/err.str_NULL_plus_offset-tvar.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/codegen/err.str_NULL_plus_offset-tvar.r
+++ b/test/unittest/codegen/err.str_NULL_plus_offset-tvar.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/codegen/err.str_NULL_plus_offset.r b/test/unittest/codegen/err.str_NULL_plus_offset.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/codegen/err.str_NULL_plus_offset.r
+++ b/test/unittest/codegen/err.str_NULL_plus_offset.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/disasm/tst.vartab-bvar.r b/test/unittest/disasm/tst.vartab-bvar.r
index 06d7c52bb..53e5f6180 100644
--- a/test/unittest/disasm/tst.vartab-bvar.r
+++ b/test/unittest/disasm/tst.vartab-bvar.r
@@ -4,7 +4,7 @@ curthread scl glb r D type (pointer) (size 8)
timestamp scl glb r D type (integer) (size 8)
vtimestamp scl glb r D type (integer) (size 8)
ipl scl glb r D type (integer) (size 4)
-epid scl glb r D type (integer) (size 4)
+epid scl glb r D type (integer) (size 8)
id scl glb r D type (integer) (size 4)
arg0 scl glb r D type (integer) (size 8)
arg1 scl glb r D type (integer) (size 8)
diff --git a/test/unittest/drops/drp.DTRACEDROP_DBLERROR.r b/test/unittest/drops/drp.DTRACEDROP_DBLERROR.r
index 9fa54dd94..364e08606 100644
--- a/test/unittest/drops/drp.DTRACEDROP_DBLERROR.r
+++ b/test/unittest/drops/drp.DTRACEDROP_DBLERROR.r
@@ -4,4 +4,4 @@
-- @@stderr --
dtrace: script 'test/unittest/drops/drp.DTRACEDROP_DBLERROR.d' matched 3 probes
dtrace: [DTRACEDROP_DBLERROR] 1 error in ERROR probe enabling
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/error/tst.DTRACEFLT_BADADDR.null_ptr_field.d b/test/unittest/error/tst.DTRACEFLT_BADADDR.null_ptr_field.d
index df3ded2d1..8b7a4d63f 100644
--- a/test/unittest/error/tst.DTRACEFLT_BADADDR.null_ptr_field.d
+++ b/test/unittest/error/tst.DTRACEFLT_BADADDR.null_ptr_field.d
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
@@ -15,13 +15,13 @@
BEGIN
{
- myepid = epid;
+ myid = id;
trace(((struct task_struct *)NULL)->pid);
exit(1);
}
ERROR
{
- exit(arg1 != myepid || arg2 != 1 || arg4 != DTRACEFLT_BADADDR ||
+ exit(arg1 != myid || arg2 != 0 || arg4 != DTRACEFLT_BADADDR ||
arg5 != 0);
}
diff --git a/test/unittest/error/tst.DTRACEFLT_BADADDR.null_ptr_field.r b/test/unittest/error/tst.DTRACEFLT_BADADDR.null_ptr_field.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/error/tst.DTRACEFLT_BADADDR.null_ptr_field.r
+++ b/test/unittest/error/tst.DTRACEFLT_BADADDR.null_ptr_field.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/error/tst.DTRACEFLT_BADADDR.r b/test/unittest/error/tst.DTRACEFLT_BADADDR.r
index b9f5f43c8..ec23cd453 100644
--- a/test/unittest/error/tst.DTRACEFLT_BADADDR.r
+++ b/test/unittest/error/tst.DTRACEFLT_BADADDR.r
@@ -1,6 +1,6 @@
-The arguments are 3 1 1 0
+The arguments are 1 1 1 0
The value of arg4 should be 1
The value of arg5 should be 0
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/error/tst.DTRACEFLT_BADADDR2.r b/test/unittest/error/tst.DTRACEFLT_BADADDR2.r
index 6c5fa119c..712678d82 100644
--- a/test/unittest/error/tst.DTRACEFLT_BADADDR2.r
+++ b/test/unittest/error/tst.DTRACEFLT_BADADDR2.r
@@ -1,6 +1,6 @@
-The arguments are 3 1 1 16384
+The arguments are 1 1 1 16384
The value of arg4 should be 1
The value of arg5 should be 16384
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/error/tst.DTRACEFLT_DIVZERO.div.d b/test/unittest/error/tst.DTRACEFLT_DIVZERO.div.d
index bcd5e9aab..b1d154239 100644
--- a/test/unittest/error/tst.DTRACEFLT_DIVZERO.div.d
+++ b/test/unittest/error/tst.DTRACEFLT_DIVZERO.div.d
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
@@ -13,9 +13,14 @@
#pragma D option quiet
+BEGIN { myid = id } /* clause 0 */
+BEGIN { myid = id } /* clause 1 */
+BEGIN { myid = id } /* clause 2 */
+BEGIN { myid = id } /* clause 3 */
+
BEGIN
{
- myepid = epid;
+ myid = id;
i = 1;
j = 2;
j = i / (j - 2);
@@ -24,6 +29,6 @@ BEGIN
ERROR
{
- exit(arg1 != myepid || arg2 != 1 || arg4 != DTRACEFLT_DIVZERO ||
+ exit(arg1 != myid || arg2 != 4 || arg4 != DTRACEFLT_DIVZERO ||
arg5 != 0);
}
diff --git a/test/unittest/error/tst.DTRACEFLT_DIVZERO.div.r b/test/unittest/error/tst.DTRACEFLT_DIVZERO.div.r
index e6d6afa2f..45a787e5c 100644
--- a/test/unittest/error/tst.DTRACEFLT_DIVZERO.div.r
+++ b/test/unittest/error/tst.DTRACEFLT_DIVZERO.div.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): divide-by-zero in action #1 at BPF pc NNN
+dtrace: error in dt_clause_4 for probe ID 1 (dtrace:::BEGIN): divide-by-zero at BPF pc NNN
diff --git a/test/unittest/error/tst.DTRACEFLT_DIVZERO.mod.d b/test/unittest/error/tst.DTRACEFLT_DIVZERO.mod.d
index 105523f82..69452d8c5 100644
--- a/test/unittest/error/tst.DTRACEFLT_DIVZERO.mod.d
+++ b/test/unittest/error/tst.DTRACEFLT_DIVZERO.mod.d
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
@@ -13,9 +13,14 @@
#pragma D option quiet
+BEGIN { myid = id; } /* clause 0 */
+BEGIN { myid = id; } /* clause 1 */
+BEGIN { myid = id; } /* clause 2 */
+BEGIN { myid = id; } /* clause 3 */
+
BEGIN
{
- myepid = epid;
+ myid = id;
i = 1;
j = 2;
j = i % (j - 2);
@@ -24,6 +29,6 @@ BEGIN
ERROR
{
- exit(arg1 != myepid || arg2 != 1 || arg4 != DTRACEFLT_DIVZERO ||
+ exit(arg1 != myid || arg2 != 4 || arg4 != DTRACEFLT_DIVZERO ||
arg5 != 0);
}
diff --git a/test/unittest/error/tst.DTRACEFLT_DIVZERO.mod.r b/test/unittest/error/tst.DTRACEFLT_DIVZERO.mod.r
index e6d6afa2f..45a787e5c 100644
--- a/test/unittest/error/tst.DTRACEFLT_DIVZERO.mod.r
+++ b/test/unittest/error/tst.DTRACEFLT_DIVZERO.mod.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): divide-by-zero in action #1 at BPF pc NNN
+dtrace: error in dt_clause_4 for probe ID 1 (dtrace:::BEGIN): divide-by-zero at BPF pc NNN
diff --git a/test/unittest/error/tst.DTRACEFLT_UNKNOWN.r b/test/unittest/error/tst.DTRACEFLT_UNKNOWN.r
index 1e4fdd644..caa5570f7 100644
--- a/test/unittest/error/tst.DTRACEFLT_UNKNOWN.r
+++ b/test/unittest/error/tst.DTRACEFLT_UNKNOWN.r
@@ -1,5 +1,5 @@
-The arguments are 3 1 PC 1 64
+The arguments are 1 1 PC 1 64
The value of arg4 = 0
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/error/tst.clause_scope-begin-ended.r b/test/unittest/error/tst.clause_scope-begin-ended.r
index 8d57382ee..e806cc809 100644
--- a/test/unittest/error/tst.clause_scope-begin-ended.r
+++ b/test/unittest/error/tst.clause_scope-begin-ended.r
@@ -2,4 +2,4 @@ Error fired
Clause executed
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/error/tst.clause_scope-begin.r b/test/unittest/error/tst.clause_scope-begin.r
index 8d57382ee..e806cc809 100644
--- a/test/unittest/error/tst.clause_scope-begin.r
+++ b/test/unittest/error/tst.clause_scope-begin.r
@@ -2,4 +2,4 @@ Error fired
Clause executed
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/error/tst.clause_scope-regular.r b/test/unittest/error/tst.clause_scope-regular.r
index fff6fe1e9..d1b71add9 100644
--- a/test/unittest/error/tst.clause_scope-regular.r
+++ b/test/unittest/error/tst.clause_scope-regular.r
@@ -2,4 +2,4 @@ Error fired
Clause executed
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID nnn: profile:::tick-10ms): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID nnn (profile:::tick-10ms): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/error/tst.clause_scope-regular.r.p b/test/unittest/error/tst.clause_scope-regular.r.p
index 7659601b7..f7a200c46 100755
--- a/test/unittest/error/tst.clause_scope-regular.r.p
+++ b/test/unittest/error/tst.clause_scope-regular.r.p
@@ -1,3 +1,7 @@
-#!/bin/sed -f
+#!/usr/bin/awk -f
+
# This report has a variable probe ID in it.
-s/ID [0-9][0-9]*: profile/ID nnn: profile/
+{
+ sub("for probe ID [0-9][0-9]* .profile", "for probe ID nnn (profile");
+ print;
+}
diff --git a/test/unittest/error/tst.error.r b/test/unittest/error/tst.error.r
index 0d29bcc8d..d9f80037e 100644
--- a/test/unittest/error/tst.error.r
+++ b/test/unittest/error/tst.error.r
@@ -1,4 +1,4 @@
Error fired
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/error/tst.errorend.r b/test/unittest/error/tst.errorend.r
index 73abf6976..9c07fa700 100644
--- a/test/unittest/error/tst.errorend.r
+++ b/test/unittest/error/tst.errorend.r
@@ -2,4 +2,4 @@ Error fired
End fired after exit
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_2 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-bcopy-before-beyond.r b/test/unittest/funcs/alloca/err.alloca-bcopy-before-beyond.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-bcopy-before-beyond.r
+++ b/test/unittest/funcs/alloca/err.alloca-bcopy-before-beyond.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-bcopy-before-bottom.r b/test/unittest/funcs/alloca/err.alloca-bcopy-before-bottom.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-bcopy-before-bottom.r
+++ b/test/unittest/funcs/alloca/err.alloca-bcopy-before-bottom.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-bcopy-beyond-top.r b/test/unittest/funcs/alloca/err.alloca-bcopy-beyond-top.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-bcopy-beyond-top.r
+++ b/test/unittest/funcs/alloca/err.alloca-bcopy-beyond-top.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-bcopy-crossing-bottom.r b/test/unittest/funcs/alloca/err.alloca-bcopy-crossing-bottom.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-bcopy-crossing-bottom.r
+++ b/test/unittest/funcs/alloca/err.alloca-bcopy-crossing-bottom.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-bcopy-crossing-top.r b/test/unittest/funcs/alloca/err.alloca-bcopy-crossing-top.r
index 4257f5679..fab8ca7f5 100644
--- a/test/unittest/funcs/alloca/err.alloca-bcopy-crossing-top.r
+++ b/test/unittest/funcs/alloca/err.alloca-bcopy-crossing-top.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid size ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid size ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-crossing-clauses.r b/test/unittest/funcs/alloca/err.alloca-crossing-clauses.r
index f5ff855de..6bea5653f 100644
--- a/test/unittest/funcs/alloca/err.alloca-crossing-clauses.r
+++ b/test/unittest/funcs/alloca/err.alloca-crossing-clauses.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 4 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #2 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-load-before-bottom.r b/test/unittest/funcs/alloca/err.alloca-load-before-bottom.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-load-before-bottom.r
+++ b/test/unittest/funcs/alloca/err.alloca-load-before-bottom.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-load-beyond-top.r b/test/unittest/funcs/alloca/err.alloca-load-beyond-top.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-load-beyond-top.r
+++ b/test/unittest/funcs/alloca/err.alloca-load-beyond-top.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-load-crossing-bottom.r b/test/unittest/funcs/alloca/err.alloca-load-crossing-bottom.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-load-crossing-bottom.r
+++ b/test/unittest/funcs/alloca/err.alloca-load-crossing-bottom.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-null-deref-lvalue.r b/test/unittest/funcs/alloca/err.alloca-null-deref-lvalue.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-null-deref-lvalue.r
+++ b/test/unittest/funcs/alloca/err.alloca-null-deref-lvalue.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-null-deref.r b/test/unittest/funcs/alloca/err.alloca-null-deref.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-null-deref.r
+++ b/test/unittest/funcs/alloca/err.alloca-null-deref.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-scratch-exceeding-bcopy.r b/test/unittest/funcs/alloca/err.alloca-scratch-exceeding-bcopy.r
index 4257f5679..fab8ca7f5 100644
--- a/test/unittest/funcs/alloca/err.alloca-scratch-exceeding-bcopy.r
+++ b/test/unittest/funcs/alloca/err.alloca-scratch-exceeding-bcopy.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid size ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid size ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-store-before-bottom.r b/test/unittest/funcs/alloca/err.alloca-store-before-bottom.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-store-before-bottom.r
+++ b/test/unittest/funcs/alloca/err.alloca-store-before-bottom.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-store-beyond-top.r b/test/unittest/funcs/alloca/err.alloca-store-beyond-top.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-store-beyond-top.r
+++ b/test/unittest/funcs/alloca/err.alloca-store-beyond-top.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/alloca/err.alloca-store-crossing-bottom.r b/test/unittest/funcs/alloca/err.alloca-store-crossing-bottom.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/alloca/err.alloca-store-crossing-bottom.r
+++ b/test/unittest/funcs/alloca/err.alloca-store-crossing-bottom.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/bcopy/err.badbcopy1.r b/test/unittest/funcs/bcopy/err.badbcopy1.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/bcopy/err.badbcopy1.r
+++ b/test/unittest/funcs/bcopy/err.badbcopy1.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/bcopy/err.badbcopy4.r b/test/unittest/funcs/bcopy/err.badbcopy4.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/bcopy/err.badbcopy4.r
+++ b/test/unittest/funcs/bcopy/err.badbcopy4.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/bcopy/err.badbcopy5.r b/test/unittest/funcs/bcopy/err.badbcopy5.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/bcopy/err.badbcopy5.r
+++ b/test/unittest/funcs/bcopy/err.badbcopy5.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/bcopy/err.badbcopy6.r b/test/unittest/funcs/bcopy/err.badbcopy6.r
index 4257f5679..fab8ca7f5 100644
--- a/test/unittest/funcs/bcopy/err.badbcopy6.r
+++ b/test/unittest/funcs/bcopy/err.badbcopy6.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid size ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid size ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/bcopy/err.badbcopy7.r b/test/unittest/funcs/bcopy/err.badbcopy7.r
index 4257f5679..fab8ca7f5 100644
--- a/test/unittest/funcs/bcopy/err.badbcopy7.r
+++ b/test/unittest/funcs/bcopy/err.badbcopy7.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid size ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid size ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/bcopy/err.badbcopy8.r b/test/unittest/funcs/bcopy/err.badbcopy8.r
index 4257f5679..fab8ca7f5 100644
--- a/test/unittest/funcs/bcopy/err.badbcopy8.r
+++ b/test/unittest/funcs/bcopy/err.badbcopy8.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid size ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid size ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/copyin/err.badaddr.r b/test/unittest/funcs/copyin/err.badaddr.r
index ba4a46953..7b0c59496 100644
--- a/test/unittest/funcs/copyin/err.badaddr.r
+++ b/test/unittest/funcs/copyin/err.badaddr.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/copyin/err.badaddr.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/copyin/err.null_arg1.r b/test/unittest/funcs/copyin/err.null_arg1.r
index a806d1077..270dc9ce9 100644
--- a/test/unittest/funcs/copyin/err.null_arg1.r
+++ b/test/unittest/funcs/copyin/err.null_arg1.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/copyin/err.null_arg1.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/copyinstr/err.badaddr.r b/test/unittest/funcs/copyinstr/err.badaddr.r
index 0f566d6e1..6f3419796 100644
--- a/test/unittest/funcs/copyinstr/err.badaddr.r
+++ b/test/unittest/funcs/copyinstr/err.badaddr.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/copyinstr/err.badaddr.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/copyinstr/err.null_arg1.r b/test/unittest/funcs/copyinstr/err.null_arg1.r
index cdd7c22c5..cac3de0ef 100644
--- a/test/unittest/funcs/copyinstr/err.null_arg1.r
+++ b/test/unittest/funcs/copyinstr/err.null_arg1.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/copyinstr/err.null_arg1.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/copyinto/err.badaddr.r b/test/unittest/funcs/copyinto/err.badaddr.r
index 11861e1fb..c86debc07 100644
--- a/test/unittest/funcs/copyinto/err.badaddr.r
+++ b/test/unittest/funcs/copyinto/err.badaddr.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/copyinto/err.badaddr.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/copyinto/err.badsize.r b/test/unittest/funcs/copyinto/err.badsize.r
index ec4b062ec..1be8abf4a 100644
--- a/test/unittest/funcs/copyinto/err.badsize.r
+++ b/test/unittest/funcs/copyinto/err.badsize.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/copyinto/err.badsize.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid size ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid size ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/copyinto/err.null_arg1.r b/test/unittest/funcs/copyinto/err.null_arg1.r
index f568ee5c1..215e0f19a 100644
--- a/test/unittest/funcs/copyinto/err.null_arg1.r
+++ b/test/unittest/funcs/copyinto/err.null_arg1.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/copyinto/err.null_arg1.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/err.badalloca.r b/test/unittest/funcs/err.badalloca.r
index 302243300..078630b65 100644
--- a/test/unittest/funcs/err.badalloca.r
+++ b/test/unittest/funcs/err.badalloca.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 4 (ID NNN: profile:::tick-1): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID NNN (profile:::tick-1): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/err.badalloca.r.p b/test/unittest/funcs/err.badalloca.r.p
index d7a88a396..93d0acfbd 100755
--- a/test/unittest/funcs/err.badalloca.r.p
+++ b/test/unittest/funcs/err.badalloca.r.p
@@ -1,3 +1,7 @@
-#!/bin/sed -f
+#!/usr/bin/awk -f
-s/(ID [0-9]*/(ID NNN/g
+# This report has a variable probe ID in it.
+{
+ sub("for probe ID [0-9]* .profile", "for probe ID NNN (profile");
+ print;
+}
diff --git a/test/unittest/funcs/err.link_ntopbadaddr.r b/test/unittest/funcs/err.link_ntopbadaddr.r
index b798b5e05..5acdfe612 100644
--- a/test/unittest/funcs/err.link_ntopbadaddr.r
+++ b/test/unittest/funcs/err.link_ntopbadaddr.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/err.link_ntopbadarg.r b/test/unittest/funcs/err.link_ntopbadarg.r
index e386a67c5..32c13ddec 100644
--- a/test/unittest/funcs/err.link_ntopbadarg.r
+++ b/test/unittest/funcs/err.link_ntopbadarg.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): illegal operation in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): illegal operation at BPF pc NNN
diff --git a/test/unittest/funcs/inet_ntoa6/err.inet_ntoa6.arg1_null.r b/test/unittest/funcs/inet_ntoa6/err.inet_ntoa6.arg1_null.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/inet_ntoa6/err.inet_ntoa6.arg1_null.r
+++ b/test/unittest/funcs/inet_ntoa6/err.inet_ntoa6.arg1_null.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/inet_ntoa6/err.inet_ntoa6.arg1_null_const.r b/test/unittest/funcs/inet_ntoa6/err.inet_ntoa6.arg1_null_const.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/inet_ntoa6/err.inet_ntoa6.arg1_null_const.r
+++ b/test/unittest/funcs/inet_ntoa6/err.inet_ntoa6.arg1_null_const.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/strlen/tst.null.r b/test/unittest/funcs/strlen/tst.null.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/strlen/tst.null.r
+++ b/test/unittest/funcs/strlen/tst.null.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/strtok/tst.strtok_null.r b/test/unittest/funcs/strtok/tst.strtok_null.r
index 03226aa12..319af487b 100644
--- a/test/unittest/funcs/strtok/tst.strtok_null.r
+++ b/test/unittest/funcs/strtok/tst.strtok_null.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/strtok/tst.strtok_null.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/strtok/tst.strtok_nulldel.r b/test/unittest/funcs/strtok/tst.strtok_nulldel.r
index 70f8e4e2d..82bbba199 100644
--- a/test/unittest/funcs/strtok/tst.strtok_nulldel.r
+++ b/test/unittest/funcs/strtok/tst.strtok_nulldel.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/strtok/tst.strtok_nulldel.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/strtok/tst.strtok_nullstr.r b/test/unittest/funcs/strtok/tst.strtok_nullstr.r
index a57b24693..1183b2bd5 100644
--- a/test/unittest/funcs/strtok/tst.strtok_nullstr.r
+++ b/test/unittest/funcs/strtok/tst.strtok_nullstr.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/strtok/tst.strtok_nullstr.d' matched 2 probes
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/strtok/tst.strtok_nullstr2.r b/test/unittest/funcs/strtok/tst.strtok_nullstr2.r
index d7df3acac..082e0e0ce 100644
--- a/test/unittest/funcs/strtok/tst.strtok_nullstr2.r
+++ b/test/unittest/funcs/strtok/tst.strtok_nullstr2.r
@@ -4,4 +4,4 @@
-- @@stderr --
dtrace: script 'test/unittest/funcs/strtok/tst.strtok_nullstr2.d' matched 4 probes
-dtrace: error on enabled probe ID 4 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #2 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/funcs/substr/err.substr_null_arg1.r b/test/unittest/funcs/substr/err.substr_null_arg1.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/funcs/substr/err.substr_null_arg1.r
+++ b/test/unittest/funcs/substr/err.substr_null_arg1.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/pointers/err.AllocaOverrun.r b/test/unittest/pointers/err.AllocaOverrun.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/pointers/err.AllocaOverrun.r
+++ b/test/unittest/pointers/err.AllocaOverrun.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/pointers/err.BadAlign.r b/test/unittest/pointers/err.BadAlign.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/pointers/err.BadAlign.r
+++ b/test/unittest/pointers/err.BadAlign.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/pointers/err.InvalidAddress2.r b/test/unittest/pointers/err.InvalidAddress2.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/pointers/err.InvalidAddress2.r
+++ b/test/unittest/pointers/err.InvalidAddress2.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/pointers/err.InvalidAddress4.r b/test/unittest/pointers/err.InvalidAddress4.r
index 187543b63..fa9c63a9e 100644
--- a/test/unittest/pointers/err.InvalidAddress4.r
+++ b/test/unittest/pointers/err.InvalidAddress4.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address ({ptr}) in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): invalid address ({ptr}) at BPF pc NNN
diff --git a/test/unittest/speculation/err.CommitWithInvalid.r b/test/unittest/speculation/err.CommitWithInvalid.r
index fc072417d..0449b2421 100644
--- a/test/unittest/speculation/err.CommitWithInvalid.r
+++ b/test/unittest/speculation/err.CommitWithInvalid.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 4 (ID 1: dtrace:::BEGIN): illegal operation in action #2 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): illegal operation at BPF pc NNN
diff --git a/test/unittest/speculation/err.DiscardWithInvalid.r b/test/unittest/speculation/err.DiscardWithInvalid.r
index fc072417d..0449b2421 100644
--- a/test/unittest/speculation/err.DiscardWithInvalid.r
+++ b/test/unittest/speculation/err.DiscardWithInvalid.r
@@ -1,3 +1,3 @@
-- @@stderr --
-dtrace: error on enabled probe ID 4 (ID 1: dtrace:::BEGIN): illegal operation in action #2 at BPF pc NNN
+dtrace: error in dt_clause_1 for probe ID 1 (dtrace:::BEGIN): illegal operation at BPF pc NNN
diff --git a/test/unittest/speculation/tst.SpecSizeVariations.r b/test/unittest/speculation/tst.SpecSizeVariations.r
index 51f0596c6..2748b307d 100644
--- a/test/unittest/speculation/tst.SpecSizeVariations.r
+++ b/test/unittest/speculation/tst.SpecSizeVariations.r
@@ -11,26 +11,6 @@ Speculative buffer ID: 1
123456706
counts: 1 1
-Speculative buffer ID: 1
-123456700
-123456701
-123456702
-123456703
-123456704
-123456705
-123456706
-counts: 1 1
-
-Speculative buffer ID: 1
-123456700
-123456701
-123456702
-123456703
-123456704
-123456705
-123456706
-counts: 2 1
-
Speculative buffer ID: 1
123456700
123456701
@@ -64,5 +44,3 @@ counts: 2 1
dtrace: 2 speculative drops
dtrace: 1 speculative drop
dtrace: 1 speculative drop
-dtrace: 1 speculative drop
-dtrace: 1 speculative drop
diff --git a/test/unittest/speculation/tst.SpecSizeVariations.sh b/test/unittest/speculation/tst.SpecSizeVariations.sh
index 75e527d9f..79995b597 100755
--- a/test/unittest/speculation/tst.SpecSizeVariations.sh
+++ b/test/unittest/speculation/tst.SpecSizeVariations.sh
@@ -9,7 +9,7 @@
dtrace=$1
-for x in 63 64 79 80 143 144; do
+for x in 71 72 159 160; do
$dtrace $dt_flags -xspecsize=$x -qn '
BEGIN
{
diff --git a/test/unittest/speculation/tst.negcommit.r b/test/unittest/speculation/tst.negcommit.r
index 69f246a01..cf8fb6f87 100644
--- a/test/unittest/speculation/tst.negcommit.r
+++ b/test/unittest/speculation/tst.negcommit.r
@@ -3,4 +3,4 @@
-- @@stderr --
dtrace: script 'test/unittest/speculation/tst.negcommit.d' matched 2 probes
-dtrace: error on enabled probe ID 2 (ID 1: dtrace:::BEGIN): illegal operation in action #1 at BPF pc NNN
+dtrace: error in dt_clause_0 for probe ID 1 (dtrace:::BEGIN): illegal operation at BPF pc NNN
diff --git a/test/unittest/variables/bvar/tst.arg3-ERROR-b.sh b/test/unittest/variables/bvar/tst.arg3-ERROR-b.sh
index 94a9ab9ac..2f6e51c3b 100755
--- a/test/unittest/variables/bvar/tst.arg3-ERROR-b.sh
+++ b/test/unittest/variables/bvar/tst.arg3-ERROR-b.sh
@@ -59,7 +59,7 @@ awk 'BEGIN {
next;
}
- /error on enabled probe/ {
+ /error in dt_clause_/ {
if (!($NF in sites)) {
print;
print " No call to dt_probe_error found at PC " $NF;
diff --git a/test/unittest/variables/bvar/tst.arg3-ERROR.sh b/test/unittest/variables/bvar/tst.arg3-ERROR.sh
index 4f2c70f38..38cb38df9 100755
--- a/test/unittest/variables/bvar/tst.arg3-ERROR.sh
+++ b/test/unittest/variables/bvar/tst.arg3-ERROR.sh
@@ -120,7 +120,7 @@ done
# Do a sanity check on DTrace's error output.
-awk '/^dtrace: error on enabled probe ID [0-9]* \(ID 1: dtrace:::BEGIN): invalid address \(0x40) in action #[0-9] at BPF pc [0-9]*$/ { print $NF }' \
+awk '/^dtrace: error in dt_clause_[1-4] for probe ID 1 \(dtrace:::BEGIN): invalid address \(0x40) at BPF pc [0-9]*$/ { print $NF }' \
disasm.out > err_pcs.txt.chk1
if ! diff -q err_pcs.txt err_pcs.txt.chk1; then
echo ERROR: problem with DTrace error output
--
2.43.5
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v2 05/19] Split dt_pid_create_probes() into pid and USDT functions
2024-09-24 20:25 [PATCH v7 03/19] Deprecate enabled probe ID (epid) eugene.loh
@ 2024-09-24 20:25 ` eugene.loh
2024-09-24 20:25 ` [PATCH v3 07/19] Create the BPF usdt_prids map eugene.loh
` (4 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: eugene.loh @ 2024-09-24 20:25 UTC (permalink / raw)
To: dtrace, dtrace-devel
From: Eugene Loh <eugene.loh@oracle.com>
The function dt_pid_create_probes() creates both pid and usdt probes.
Once the dtrace session has started, however, we only need to watch
for new usdt probes.
Therefore, reorganize dt_pid_create_probes():
*) Rename
dt_pid_create_pid_probes()
to
dt_pid_create_pid_probes_proc()
and rename
dt_pid_create_usdt_probes()
to
dt_pid_create_usdt_probes_proc()
since these functions create probes for a specified process.
*) Break dt_pid_create_probes() into two functions:
dt_pid_create_pid_probes()
dt_pid_create_usdt_probes()
*) Make dt_pid_create_usdt_probes() available in dt_pid.h.
Also, start building support for wildcard USDT pid specifications.
Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
libdtrace/dt_pid.c | 137 +++++++++++++++++++++++++++++++++------------
libdtrace/dt_pid.h | 2 +
2 files changed, 102 insertions(+), 37 deletions(-)
diff --git a/libdtrace/dt_pid.c b/libdtrace/dt_pid.c
index 996543b1f..62060b592 100644
--- a/libdtrace/dt_pid.c
+++ b/libdtrace/dt_pid.c
@@ -605,9 +605,12 @@ dt_pid_fix_mod(dt_pid_probe_t *pp, dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
return pmp;
}
+/*
+ * Create pid probes for the specified process.
+ */
static int
-dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
- dt_pcb_t *pcb, dt_proc_t *dpr)
+dt_pid_create_pid_probes_proc(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
+ dt_pcb_t *pcb, dt_proc_t *dpr)
{
dt_pid_probe_t pp;
int ret = 0;
@@ -702,6 +705,7 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
return ret;
}
+
/*
* Read a file into a buffer and return it.
*/
@@ -780,24 +784,21 @@ validate_dof_record(const char *path, const dof_parsed_t *parsed,
/*
* Create underlying probes relating to the probespec passed on input.
*
- * If dpr is set, just set up probes relating to mappings found in that one
- * process. (dpr must in this case be locked.)
+ * dpr must be set and locked. Just set up probes relating to mappings found
+ * in this one process.
*
* Return 0 on success or -1 on error. (Failure to create specific underlying
* probes is not an error.)
*/
static int
-dt_pid_create_usdt_probes(dtrace_hdl_t *dtp, dt_proc_t *dpr, dtrace_probedesc_t *pdp,
- dt_pcb_t *pcb)
+dt_pid_create_usdt_probes_proc(dtrace_hdl_t *dtp, dt_proc_t *dpr,
+ dtrace_probedesc_t *pdp, dt_pcb_t *pcb)
{
const dt_provider_t *pvp;
int ret = 0;
char *probepath = NULL;
glob_t probeglob = {0};
- /*
- * Systemwide probing: not yet implemented.
- */
assert(dpr != NULL && dpr->dpr_proc);
assert(MUTEX_HELD(&dpr->dpr_lock));
@@ -1094,64 +1095,126 @@ dt_pid_get_pid(const dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb,
return pid;
}
+/*
+ * Create pid probes. Return 0 on success (even if no probes are
+ * created, since there might still be USDT probes) and -1 on error.
+ */
int
-dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb)
+dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb)
{
+ pid_t pid;
char provname[DTRACE_PROVNAMELEN];
dt_proc_t *dpr;
- pid_t pid;
- int err = 0;
+ int err;
assert(pcb != NULL);
- if ((pid = dt_pid_get_pid(pdp, dtp, pcb, NULL)) == -1)
+ /* Exclude pid0 from being specifically requested. */
+ if (strcmp(pdp->prv, "pid0") == 0) {
+ dt_pid_error(dtp, pcb, NULL, D_PROC_BADPID,
+ "pid0 does not contain a valid pid");
return -1;
+ }
+ /* Extract the pid. */
+ pid = dt_pid_get_pid(pdp, dtp, pcb, NULL);
+ if (pid <= 0)
+ return 0;
+
+ /* Check whether pid$pid matches the probe description. */
snprintf(provname, sizeof(provname), "pid%d", (int)pid);
+ if (gmatch(provname, pdp->prv) == 0)
+ return 0;
- if (gmatch(provname, pdp->prv) != 0) {
- if (dt_proc_grab_lock(dtp, pid, DTRACE_PROC_WAITING) < 0) {
- dt_pid_error(dtp, pcb, NULL, D_PROC_GRAB,
- "failed to grab process %d", (int)pid);
- return -1;
- }
+ /* Grab the process. */
+ if (dt_proc_grab_lock(dtp, pid, DTRACE_PROC_WAITING) < 0) {
+ dt_pid_error(dtp, pcb, NULL, D_PROC_GRAB,
+ "failed to grab process %d", (int)pid);
+ return -1;
+ }
+ dpr = dt_proc_lookup(dtp, pid);
+ assert(dpr != NULL);
- dpr = dt_proc_lookup(dtp, pid);
- assert(dpr != NULL);
+ /* Create the pid probes for this process. */
+ err = dt_pid_create_pid_probes_proc(pdp, dtp, pcb, dpr);
+ dt_proc_release_unlock(dtp, pid);
- err = dt_pid_create_pid_probes(pdp, dtp, pcb, dpr);
- dt_proc_release_unlock(dtp, pid);
+ return err;
+}
+
+int
+dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb)
+{
+ glob_t globbuf;
+ char *globpat = NULL;
+ int err = 0, i, nmatches = 0;
+
+ assert(pcb != NULL);
+
+ /* If it's strictly a pid provider, we're done. */
+ if (strncmp(pdp->prv, "pid", 3) == 0 && isdigit(pdp->prv[3])) {
+ const char *p = &pdp->prv[4];
+
+ while (isdigit(*p))
+ p++;
+ if (*p == '\0')
+ return 0;
}
- /*
- * If it's not strictly a pid provider, we might match a USDT provider.
- */
- if (strcmp(provname, pdp->prv) != 0) {
+ /* Look for USDT probes. */
+ asprintf(&globpat, "%s/probes/*/%s", dtp->dt_dofstash_path, pdp->prv[0] ? pdp->prv : "*");
+ nmatches = glob(globpat, 0, NULL, &globbuf) ? 0 : globbuf.gl_pathc;
+ for (i = 0; i < nmatches; i++) {
+ char *s = globbuf.gl_pathv[i]
+ + strlen(dtp->dt_dofstash_path)
+ + strlen("/probes/");
+ pid_t pid;
+ dt_proc_t *dpr;
+ dtrace_probedesc_t pdptmp;
+
+ /* Pull out the pid. */
+ pid = atoll(s);
+
+ /* Check, since dtprobed takes a while to clean up dead processes. */
+ if (!Pexists(pid))
+ continue;
+
+ /* Grab the process. */
if (dt_proc_grab_lock(dtp, pid, DTRACE_PROC_WAITING |
DTRACE_PROC_SHORTLIVED) < 0) {
dt_pid_error(dtp, pcb, NULL, D_PROC_GRAB,
"failed to grab process %d", (int)pid);
return -1;
}
-
dpr = dt_proc_lookup(dtp, pid);
assert(dpr != NULL);
- err = dt_pid_create_usdt_probes(dtp, dpr, pdp, pcb);
+ /* Create USDT probes for this process. */
+ pdptmp.prv = strchr(s, '/') + 1;
+ pdptmp.mod = pdp->mod[0] == '\0' ? "*" : pdp->mod;
+ pdptmp.fun = pdp->fun[0] == '\0' ? "*" : pdp->fun;
+ pdptmp.prb = pdp->prb[0] == '\0' ? "*" : pdp->prb;
+ if (dt_pid_create_usdt_probes_proc(dtp, dpr, &pdptmp, pcb))
+ err = 1;
- /*
- * Put the module name in its canonical form.
- */
- dt_pid_fix_mod(NULL, pdp, dtp, dpr->dpr_pid);
+ dt_pid_fix_mod(NULL, &pdptmp, dtp, dpr->dpr_pid);
dt_proc_release_unlock(dtp, pid);
}
-
- /* (USDT systemwide probing goes here.) */
+ free(globpat);
+ globfree(&globbuf);
return err ? -1 : 0;
}
+int
+dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb)
+{
+ if (dt_pid_create_pid_probes(pdp, dtp, pcb))
+ return -1;
+ return dt_pid_create_usdt_probes(pdp, dtp, pcb);
+}
+
int
dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr)
{
@@ -1179,7 +1242,7 @@ dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr)
pd.fun = strdup(pd.fun); /* we may change it */
if (gmatch(provname, pdp->prv) != 0 &&
- dt_pid_create_pid_probes(&pd, dtp, NULL, dpr) != 0)
+ dt_pid_create_pid_probes_proc(&pd, dtp, NULL, dpr) != 0)
ret = 1;
/*
@@ -1187,7 +1250,7 @@ dt_pid_create_probes_module(dtrace_hdl_t *dtp, dt_proc_t *dpr)
* a USDT provider.
*/
if (strcmp(provname, pdp->prv) != 0) {
- if (dt_pid_create_usdt_probes(dtp, dpr, pdp, NULL) < 0)
+ if (dt_pid_create_usdt_probes_proc(dtp, dpr, pdp, NULL) < 0)
ret = 1;
else
dt_pid_fix_mod(NULL, pdp, dtp, dpr->dpr_pid);
diff --git a/libdtrace/dt_pid.h b/libdtrace/dt_pid.h
index 497c77510..9277c6bc0 100644
--- a/libdtrace/dt_pid.h
+++ b/libdtrace/dt_pid.h
@@ -16,6 +16,8 @@
extern "C" {
#endif
+extern int dt_pid_create_usdt_probes(dtrace_probedesc_t *, dtrace_hdl_t *,
+ dt_pcb_t *);
extern int dt_pid_create_probes(dtrace_probedesc_t *, dtrace_hdl_t *,
dt_pcb_t *);
extern int dt_pid_create_probes_module(dtrace_hdl_t *, dt_proc_t *);
--
2.43.5
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v3 07/19] Create the BPF usdt_prids map
2024-09-24 20:25 [PATCH v7 03/19] Deprecate enabled probe ID (epid) eugene.loh
2024-09-24 20:25 ` [PATCH v2 05/19] Split dt_pid_create_probes() into pid and USDT functions eugene.loh
@ 2024-09-24 20:25 ` eugene.loh
2024-09-24 20:25 ` [PATCH v3 09/19] Use usdt_prids map to call clauses conditionally for USDT probes eugene.loh
` (3 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: eugene.loh @ 2024-09-24 20:25 UTC (permalink / raw)
To: dtrace, dtrace-devel
From: Eugene Loh <eugene.loh@oracle.com>
As USDT processes come and go, the overlying probes for an underlying
probe will change. Hence, we will move to a scheme in which an
underlying probe will walk all possible clauses it could call,
deciding at run time (using a bit mask for the overlying USDT probe)
which of the clauses to call.
In this patch, we create and update the BPF "usdt_prids" map. This
is a hash map, where:
*) the key (size: dtp->dt_usdt_pridsmap_ksz) comprises
- the PID of the firing process
- the PRID of the underlying probe
*) the value (size: dtp->dt_usdt_pridsmap_vsz) comprises
- the PRID over the overlying USDT probe
- a bit mask indicating which clauses should be called
As processes start up, we also add new overlying USDT probes,
requiring updates of the BPF "probes" and "strtab" maps and of
the list of enablings.
The underlying-probes "update" function is called sporadically.
The focus of this patch is the function. When it is called can
be tuned in future patches.
This patch guesses certain sizes very crudely. These sizes should
be handled more robustly in future patches:
*) The allocated size of the string table. For example,
new provider names have to be added as new processes
start.
*) The number of entries in the BPF "usdt_prids" map.
There is a little relief here in that, as processes
terminate, they can be removed from the map.
*) The size of the bit mask -- that is, the greatest
number of clauses an underlying probe might call.
This is relatively easy to extend; nevertheless,
that work is left for a future patch.
Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
libdtrace/dt_bpf.c | 42 +++++-
libdtrace/dt_cc.c | 2 +-
libdtrace/dt_dlibs.c | 1 +
libdtrace/dt_impl.h | 6 +
libdtrace/dt_prov_uprobe.c | 276 +++++++++++++++++++++++++++++++++++++
libdtrace/dt_work.c | 2 +
6 files changed, 327 insertions(+), 2 deletions(-)
diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
index ad11d178e..0987279bc 100644
--- a/libdtrace/dt_bpf.c
+++ b/libdtrace/dt_bpf.c
@@ -841,7 +841,8 @@ gmap_create_strtab(dtrace_hdl_t *dtp)
int fd, rc, err;
dtp->dt_strlen = dt_strtab_size(dtp->dt_ccstab);
- dtp->dt_rooffset = P2ROUNDUP(dtp->dt_strlen, 8);
+ dtp->dt_strmax = dtp->dt_strlen + 1000; // FIXME pad some arbitrary amount to account for new USDT probes as new processes start
+ dtp->dt_rooffset = P2ROUNDUP(dtp->dt_strmax, 8);
dtp->dt_rosize = dt_rodata_size(dtp->dt_rodata);
dtp->dt_zerooffset = P2ROUNDUP(dtp->dt_rooffset + dtp->dt_rosize, 8);
dtp->dt_zerosize = 0;
@@ -899,6 +900,7 @@ gmap_create_strtab(dtrace_hdl_t *dtp)
if (rc == -1)
return dt_bpf_error(dtp, "cannot update BPF map 'strtab': %s\n",
strerror(err));
+ dtp->dt_strtabmap_fd = fd;
return 0;
}
@@ -936,6 +938,43 @@ gmap_create_probes(dtrace_hdl_t *dtp)
dtp, "cannot update BPF map 'probes': %s\n",
strerror(errno));
}
+ dtp->dt_probesmap_fd = fd;
+
+ return 0;
+}
+
+/*
+ * Create the 'usdt_prids' BPF map.
+ *
+ * USDT-PRID information map. This is a global hash map for use
+ * with USDT probes. It is indexed by (pid, underlying probe ID).
+ * The value is a probe ID for the overlying USDT probe and a bit
+ * mask indicating which clauses to execute for this pid.
+ *
+ * WIP. Just make up some sizes for now.
+ *
+ * How big is a probe ID? Sometimes, it's a dtrace_id_t.
+ * And uts/common/sys/dtrace_types.h gives us "typedef uint32_t dtrace_id_t".
+ * Meanwhile, libdtrace/dt_impl.h has "uint32_t dt_probe_id".
+ * So either uint32_t or dtrace_id_t is fine.
+ *
+ * How big should our bit mask be? Start with 8*sizeof(long long) bits.
+ *
+ * How many entries should we allow? Start with 1000.
+ *
+ * Note that for a given (pid, PRID) key, there can be at most one
+ * overlying USDT probe.
+ */
+static int
+gmap_create_usdt_prids(dtrace_hdl_t *dtp)
+{
+ dtp->dt_usdt_pridsmap_fd = create_gmap(dtp, "usdt_prids", BPF_MAP_TYPE_HASH,
+ dtp->dt_usdt_pridsmap_ksz, dtp->dt_usdt_pridsmap_vsz, 1000);
+ if (dtp->dt_usdt_pridsmap_fd == -1)
+ return -1;
+
+ /* Populate the newly created map. FIXME: this is probably not the right place for this. */
+ dt_uprobe.update(dtp, NULL);
return 0;
}
@@ -1045,6 +1084,7 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
CREATE_MAP(scratchmem)
CREATE_MAP(strtab)
CREATE_MAP(probes)
+ CREATE_MAP(usdt_prids)
CREATE_MAP(gvars)
CREATE_MAP(lvars)
CREATE_MAP(dvars)
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index 4202771a9..12104fc21 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -1045,7 +1045,7 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
nrp->dofr_data = 0; /* FIXME */
continue;
case DT_CONST_STBSZ:
- nrp->dofr_data = dtp->dt_strlen;
+ nrp->dofr_data = dtp->dt_strmax;
continue;
case DT_CONST_STRSZ:
nrp->dofr_data =
diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
index ba4d4abef..924cf11e4 100644
--- a/libdtrace/dt_dlibs.c
+++ b/libdtrace/dt_dlibs.c
@@ -66,6 +66,7 @@ static const dt_ident_t dt_bpf_symbols[] = {
DT_BPF_SYMBOL(lvars, DT_IDENT_PTR),
DT_BPF_SYMBOL(mem, DT_IDENT_PTR),
DT_BPF_SYMBOL(probes, DT_IDENT_PTR),
+ DT_BPF_SYMBOL(usdt_prids, DT_IDENT_PTR),
DT_BPF_SYMBOL(scratchmem, DT_IDENT_PTR),
DT_BPF_SYMBOL(specs, DT_IDENT_PTR),
DT_BPF_SYMBOL(state, DT_IDENT_PTR),
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index 340dc1960..1d1248766 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -282,6 +282,7 @@ struct dtrace_hdl {
dt_strtab_t *dt_ccstab; /* global string table (during compilation) */
dt_rodata_t *dt_rodata; /* global read-only data */
uint_t dt_strlen; /* global string table (runtime) size */
+ uint_t dt_strmax; /* global string table (runtime) size, allocated */
uint_t dt_rooffset; /* read-only data offset */
uint_t dt_rosize; /* read-only data size */
uint_t dt_zerooffset; /* zero region, offset */
@@ -389,6 +390,11 @@ struct dtrace_hdl {
int dt_aggmap_fd; /* file descriptor for the 'aggs' BPF map */
int dt_genmap_fd; /* file descriptor for the 'agggen' BPF map */
int dt_cpumap_fd; /* file descriptor for the 'cpuinfo' BPF map */
+ int dt_strtabmap_fd; /* file descriptor for the 'strtab' BPF map */
+ int dt_probesmap_fd; /* file descriptor for the 'probes' BPF map */
+ int dt_usdt_pridsmap_fd; /* file descriptor for the 'usdt_prids' BPF map */
+ int dt_usdt_pridsmap_ksz; /* 'usdt_prids' BPF map key size */
+ int dt_usdt_pridsmap_vsz; /* 'usdt_prids' BPF map value size */
dtrace_handle_err_f *dt_errhdlr; /* error handler, if any */
void *dt_errarg; /* error handler argument */
dtrace_handle_drop_f *dt_drophdlr; /* drop handler, if any */
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index bb172ace2..9ff44316b 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -37,8 +37,10 @@
#include "dt_list.h"
#include "dt_provider_tp.h"
#include "dt_probe.h"
+#include "dt_program.h"
#include "dt_pid.h"
#include "dt_string.h"
+#include "port.h"
/* Provider name for the underlying probes. */
static const char prvname[] = "uprobe";
@@ -63,6 +65,15 @@ typedef struct list_probe {
dt_probe_t *probe;
} list_probe_t;
+typedef struct usdt_prids_map_key {
+ pid_t pid;
+ dtrace_id_t uprid;
+} usdt_prids_map_key_t;
+typedef struct usdt_prids_map_val {
+ dtrace_id_t prid;
+ long long mask;
+} usdt_prids_map_val_t;
+
static const dtrace_pattr_t pattr = {
{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
@@ -77,6 +88,9 @@ dt_provimpl_t dt_usdt;
static int populate(dtrace_hdl_t *dtp)
{
+ dtp->dt_usdt_pridsmap_ksz = sizeof(usdt_prids_map_key_t);
+ dtp->dt_usdt_pridsmap_vsz = sizeof(usdt_prids_map_val_t);
+
if (dt_provider_create(dtp, dt_uprobe.name, &dt_uprobe, &pattr,
NULL) == NULL ||
dt_provider_create(dtp, dt_uprobe_is_enabled.name,
@@ -123,6 +137,267 @@ static void probe_destroy(dtrace_hdl_t *dtp, void *datap)
free_probe_list(dtp, datap);
}
+/*
+ * Clean up the BPF "usdt_prids" map.
+ */
+static int
+purge_BPFmap(dtrace_hdl_t *dtp)
+{
+ int fd = dtp->dt_usdt_pridsmap_fd;
+ usdt_prids_map_key_t key, nxt;
+ usdt_prids_map_val_t val;
+
+ /* Initialize key to a pid/uprid that cannot be found. */
+ key.pid = 0;
+ key.uprid = 0;
+
+ /* Loop over all entries. */
+ while (dt_bpf_map_next_key(fd, &key, &nxt) == 0) {
+ memcpy(&key, &nxt, sizeof(usdt_prids_map_key_t));
+
+ if (dt_bpf_map_lookup(fd, &key, &val) == -1)
+ return dt_set_errno(dtp, EDT_BPF);
+
+ /* Check if the process is still running. */
+ if (!Pexists(key.pid)) {
+ dt_bpf_map_delete(fd, &key); // FIXME: bpf_map_next_key() iteration restarts each time we delete an elem!!!
+ continue;
+ }
+
+ /*
+ * FIXME. There might be another case, where the process
+ * is still running, but some of its USDT probes are gone?
+ * So maybe we have to check for the existence of one of
+ * dtrace_probedesc_t *pdp = dtp->dt_probes[val.prid]->desc;
+ * char *prv = ...pdp->prv minus the numerial part;
+ *
+ * /run/dtrace/probes/$pid/$pdp->prv/$pdp->mod/$pdp->fun/$pdp->prb
+ * /run/dtrace/stash/dof-pid/$pid/0/parsed/$prv:$pdp->mod:$pdp->fun:$pdp->prb
+ * /run/dtrace/stash/dof-pid/$pid/.../parsed/$prv:$pdp->mod:$pdp->fun:$pdp->prb
+ */
+ }
+
+ return 0;
+}
+
+/*
+ * Grow the string table map. It includes the string table (which might
+ * grow due to new USDT probes). It also includes the read-only data and
+ * the block of zeros, but these remain fixed.
+ *
+ * FIXME Is there a danger of the BPF map update colliding with map reads?
+ */
+static int
+grow_strtab(dtrace_hdl_t *dtp)
+{
+ size_t sz = dtp->dt_zerooffset + dtp->dt_zerosize;
+ char *strtab;
+ uint8_t *buf, *end;
+ size_t strsize = dtp->dt_options[DTRACEOPT_STRSIZE];
+ uint32_t key = 0;
+ int rc, err;
+
+ strtab = dt_zalloc(dtp, sz);
+#if 0
+ // FIXME do something
+ if (strtab == NULL)
+ return dt_set_errno(dtp, EDT_NOMEM);
+#endif
+
+ /* Copy the string table data. */
+ dt_strtab_write(dtp->dt_ccstab, (dt_strtab_write_f *)dt_strtab_copystr, strtab);
+
+ /* Loop over the string table and truncate strings that are too long. */
+ buf = (uint8_t *)strtab;
+ end = buf + dtp->dt_strlen;
+ while (buf < end) {
+ uint_t len = strlen((char *)buf);
+
+ if (len > strsize)
+ buf[strsize] = '\0';
+
+ buf += len + 1;
+ }
+
+ /* Copy the read-only data. */
+ dt_rodata_write(dtp->dt_rodata, (dt_rodata_copy_f *)dt_rodata_copy, strtab + dtp->dt_rooffset);
+
+ rc = dt_bpf_map_update(dtp->dt_strtabmap_fd, &key, strtab);
+ err = errno;
+ dt_free(dtp, strtab);
+
+ // FIXME do something
+ if (rc == -1) {
+ strerror(err);
+ return -1;
+ // return dt_bpf_error(dtp, "cannot update BPF map 'strtab': %s\n", strerror(err));
+ }
+
+ return 0;
+}
+
+/*
+ * Update the uprobe provider.
+ */
+static void update_uprobe(dtrace_hdl_t *dtp, void *datap)
+{
+ dt_probe_t *prp;
+ dt_probe_t *prp_next;
+ int i, prid = dtp->dt_probe_id;
+ uint_t old_strlen = dtp->dt_strlen;
+ dt_pcb_t pcb;
+
+ /* Clear stale pids. */
+ purge_BPFmap(dtp);
+
+ /* Update dt_probes[] and dt_enablings. */
+ /*
+ * pcb is only used inside of dt_pid_error() to get:
+ * pcb->pcb_region
+ * pcb->pcb_filetag
+ * pcb->pcb_fileptr
+ * While pcb cannot be NULL, these other things apparently can be.
+ */
+ memset(&pcb, 0, sizeof(dt_pcb_t));
+ for (i = 0; i < dtp->dt_stmt_nextid; i++) {
+ dtrace_stmtdesc_t *stp;
+
+ stp = dtp->dt_stmts[i];
+ assert(stp != NULL);
+ dt_pid_create_usdt_probes(&stp->dtsd_ecbdesc->dted_probe, dtp, &pcb);
+ }
+
+ while (prid < dtp->dt_probe_id) {
+ dt_bpf_probe_t pinfo;
+ const dtrace_probedesc_t *pdp = dtp->dt_probes[prid]->desc;
+ int fd = dtp->dt_probesmap_fd;
+
+ dt_probe_enable(dtp, dtp->dt_probes[prid]);
+
+ pinfo.prv = dt_strtab_index(dtp->dt_ccstab, pdp->prv);
+ pinfo.mod = dt_strtab_index(dtp->dt_ccstab, pdp->mod);
+ pinfo.fun = dt_strtab_index(dtp->dt_ccstab, pdp->fun);
+ pinfo.prb = dt_strtab_index(dtp->dt_ccstab, pdp->prb);
+
+ if (dt_bpf_map_update(fd, &pdp->id, &pinfo) == -1)
+ assert(0); // FIXME do something here
+
+ prid++;
+ }
+
+ /* Grow the strtab if it has gotten bigger. */
+ dtp->dt_strlen = dt_strtab_size(dtp->dt_ccstab);
+
+ if (dtp->dt_strlen > dtp->dt_strmax)
+ assert(0); // FIXME handle this more gracefully
+ if (dtp->dt_strlen > old_strlen)
+ grow_strtab(dtp);
+
+ /* Review enablings. */
+ for (prp = dt_list_next(&dtp->dt_enablings); prp != NULL; prp = prp_next) {
+ pid_t pid;
+ list_probe_t *pup;
+
+ prp_next = dt_list_next(prp);
+
+ /* Make sure it is an overlying USDT probe. */
+ if (prp->prov->impl != &dt_usdt)
+ continue;
+
+ /* FIXME passing in NULL pcb and dpr wreaks havoc on error reporting? */
+ /*
+ * Nick writes:
+ * This is a general problem with running compiler-adjacent things outside
+ * compile time. I think we should adjust dt_pid_error() so that it works
+ * with NULL pcb and dpr at once, probably by using the code path for
+ * pcb != NULL and augmenting it so that it passes in NULL for the region and
+ * filename args and 0 for the lineno if pcb is NULL. (dt_set_errmsg can
+ * already handle this case.)
+ */
+ pid = dt_pid_get_pid(prp->desc, dtp, NULL, NULL);
+
+ if (!Pexists(pid)) {
+ /* Remove from enablings. */
+ dt_list_delete(&dtp->dt_enablings, prp);
+
+ /* Make it evident from the probe that it is not in enablings. */
+ ((dt_list_t *)prp)->dl_prev = NULL;
+ ((dt_list_t *)prp)->dl_next = NULL;
+
+ /* Free up its list of underlying probes. */
+ while ((pup = dt_list_next(prp->prv_data)) != NULL) {
+ dt_list_delete(prp->prv_data, pup);
+ dt_free(dtp, pup);
+ }
+ dt_free(dtp, prp->prv_data);
+ prp->prv_data = NULL;
+
+ /* Free up BPF "probes" map entry. */
+ dt_bpf_map_delete(dtp->dt_probesmap_fd, &prp->desc->id);
+
+ continue;
+ }
+
+ for (pup = prp->prv_data; pup != NULL; pup = dt_list_next(pup)) {
+ dt_probe_t *uprp = pup->probe;
+ long long mask = 0, bit = 1;
+ usdt_prids_map_key_t key;
+ usdt_prids_map_val_t val, oval;
+ dt_uprobe_t *upp = uprp->prv_data;
+
+ /*
+ * For is-enabled probes, the bit mask does not matter.
+ * It is possible that we have this underlying probe due to
+ * an overlying pid-offset probe and that we will not know
+ * until later, when some new pid is created, that we also
+ * have an overlying USDT is-enabled probe, but missing this
+ * optimization opportunity is okay.
+ */
+ if (uprp->prov->impl == &dt_uprobe && !(upp->flags & PP_IS_ENABLED)) {
+ int n;
+
+ for (n = 0; n < dtp->dt_stmt_nextid; n++) {
+ dtrace_stmtdesc_t *stp;
+
+ stp = dtp->dt_stmts[n];
+ assert(stp != NULL);
+
+ if (dt_gmatch(prp->desc->prv, stp->dtsd_ecbdesc->dted_probe.prv) &&
+ dt_gmatch(prp->desc->mod, stp->dtsd_ecbdesc->dted_probe.mod) &&
+ dt_gmatch(prp->desc->fun, stp->dtsd_ecbdesc->dted_probe.fun) &&
+ dt_gmatch(prp->desc->prb, stp->dtsd_ecbdesc->dted_probe.prb))
+ mask |= bit;
+
+ bit <<= 1;
+ }
+ }
+
+ key.pid = pid;
+ key.uprid = uprp->desc->id;
+
+ val.prid = prp->desc->id;
+ val.mask = mask;
+
+ /* linux/bpf.h says error is -1, but it could be -2 */
+ if (dt_bpf_map_lookup(dtp->dt_usdt_pridsmap_fd, &key, &oval) < 0) {
+ /*
+ * Set the map entry.
+ */
+ // FIXME Check return value, but how should errors be handled?
+ dt_bpf_map_update(dtp->dt_usdt_pridsmap_fd, &key, &val);
+ } else if (val.prid != oval.prid || val.mask != oval.mask) {
+ /*
+ * This can happen when two overlying probes map to the same underlying probe for the same pid.
+ * E.g., pid:::entry and pid:::0, or pid:::$offset and usdt:::.
+ */
+ } else {
+ /*
+ * Nothing to do, it already is in the map.
+ */
+ }
+ }
+ }
+}
/*
* Look up or create an underlying (real) probe, corresponding directly to a
@@ -782,6 +1057,7 @@ dt_provimpl_t dt_uprobe = {
.probe_info = &probe_info,
.detach = &detach,
.probe_destroy = &probe_destroy_underlying,
+ .update = &update_uprobe,
};
/*
diff --git a/libdtrace/dt_work.c b/libdtrace/dt_work.c
index 40913a0f1..ef39b3a68 100644
--- a/libdtrace/dt_work.c
+++ b/libdtrace/dt_work.c
@@ -368,6 +368,8 @@ dtrace_work(dtrace_hdl_t *dtp, FILE *fp, dtrace_consume_probe_f *pfunc,
dtrace_workstatus_t rval;
int gen;
+dt_uprobe.update(dtp, NULL);
+
switch (dtrace_status(dtp)) {
case DTRACE_STATUS_EXITED:
case DTRACE_STATUS_STOPPED:
--
2.43.5
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v3 09/19] Use usdt_prids map to call clauses conditionally for USDT probes
2024-09-24 20:25 [PATCH v7 03/19] Deprecate enabled probe ID (epid) eugene.loh
2024-09-24 20:25 ` [PATCH v2 05/19] Split dt_pid_create_probes() into pid and USDT functions eugene.loh
2024-09-24 20:25 ` [PATCH v3 07/19] Create the BPF usdt_prids map eugene.loh
@ 2024-09-24 20:25 ` eugene.loh
2024-09-24 20:25 ` [PATCH v3 11/19] Support USDT wildcard provider descriptions eugene.loh
` (2 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: eugene.loh @ 2024-09-24 20:25 UTC (permalink / raw)
To: dtrace, dtrace-devel
From: Eugene Loh <eugene.loh@oracle.com>
This version supports only up to 64 clauses for an underlying
probe, but it can be extended to more clauses.
Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
libdtrace/dt_prov_uprobe.c | 164 +++++++++++++++++++++++++++----------
1 file changed, 121 insertions(+), 43 deletions(-)
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index 7559be09a..510e2dfa1 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -691,11 +691,16 @@ static void enable_usdt(dtrace_hdl_t *dtp, dt_probe_t *prp)
*/
static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
{
+ dtrace_hdl_t *dtp = pcb->pcb_hdl;
dt_irlist_t *dlp = &pcb->pcb_ir;
const dt_probe_t *uprp = pcb->pcb_probe;
const dt_uprobe_t *upp = uprp->prv_data;
const list_probe_t *pop;
uint_t lbl_exit = pcb->pcb_exitlbl;
+ dt_ident_t *usdt_prids = dt_dlib_get_map(dtp, "usdt_prids");
+ int n;
+
+ assert(usdt_prids != NULL);
dt_cg_tramp_prologue(pcb); // call this only once... is PRID set/relocated correctly?
@@ -707,14 +712,17 @@ static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
dt_cg_tramp_copy_regs(pcb); // call this only once for all clauses?
/*
- * Loop over overlying probes, calling clauses for those that match:
+ * pid probes.
+ *
+ * Loop over overlying pid probes, calling clauses for those that match:
*
- * for overlying probes (that match except possibly for pid)
+ * for overlying pid probes (that match except possibly for pid)
* if (pid matches) {
* dctx->mst->prid = PRID1;
* < any number of clause calls >
* }
*/
+
for (pop = dt_list_next(&upp->probes); pop != NULL;
pop = dt_list_next(pop)) {
const dt_probe_t *prp = pop->probe;
@@ -722,6 +730,9 @@ static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
pid_t pid;
dt_ident_t *idp;
+ if (prp->prov->impl != &dt_pid)
+ continue;
+
pid = dt_pid_get_pid(prp->desc, pcb->pcb_hdl, pcb, NULL);
assert(pid != -1);
@@ -753,6 +764,91 @@ static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
BPF_NOP());
}
+ /*
+ * USDT
+ */
+
+ /* In some cases, we know there are no USDT probes. */ // FIXME: add more checks
+ if (upp->flags & PP_IS_RETURN)
+ goto out;
+
+ dt_cg_tramp_copy_args_from_regs(pcb, 0);
+
+ /*
+ * Retrieve the PID of the process that caused the probe to fire.
+ */
+ emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_current_pid_tgid));
+ emit(dlp, BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32));
+
+ /*
+ * Look up in the BPF 'usdt_prids' map. Space for the look-up key
+ * will be used on the BPF stack:
+ *
+ * offset value
+ *
+ * -sizeof(usdt_prids_map_key_t) pid (in %r0)
+ *
+ * -sizeof(usdt_prids_map_key_t) + sizeof(pid_t)
+ * ==
+ * -sizeof(dtrace_id_t) underlying-probe prid
+ */
+ emit(dlp, BPF_STORE(BPF_W, BPF_REG_9, (int)(-sizeof(usdt_prids_map_key_t)), BPF_REG_0));
+ emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_9, (int)(-sizeof(dtrace_id_t)), uprp->desc->id));
+ dt_cg_xsetx(dlp, usdt_prids, DT_LBL_NONE, BPF_REG_1, usdt_prids->di_id);
+ emit(dlp, BPF_MOV_REG(BPF_REG_2, BPF_REG_9));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, (int)(-sizeof(usdt_prids_map_key_t))));
+ emit(dlp, BPF_CALL_HELPER(BPF_FUNC_map_lookup_elem));
+ emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, lbl_exit));
+
+ /* Read the PRID from the table lookup and store to mst->prid. */
+ emit(dlp, BPF_LOAD(BPF_W, BPF_REG_1, BPF_REG_0, 0));
+ emit(dlp, BPF_STORE(BPF_W, BPF_REG_7, DMST_PRID, BPF_REG_1));
+
+ /* Read the bit mask from the table lookup in %r6. */ // FIXME someday, extend this past 64 bits
+ emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_6, BPF_REG_0, offsetof(usdt_prids_map_val_t, mask)));
+
+ /*
+ * Hold the bit mask in %r6 between clause calls.
+ */
+ for (n = 0; n < dtp->dt_stmt_nextid; n++) {
+ dtrace_stmtdesc_t *stp;
+ dt_ident_t *idp;
+ uint_t lbl_next = dt_irlist_label(dlp);
+
+ stp = dtp->dt_stmts[n];
+ assert(stp != NULL);
+ idp = stp->dtsd_clause;
+
+ /* If the lowest %r6 bit is 0, skip over this clause. */
+ emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_6));
+ emit(dlp, BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 1));
+ emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_1, 0, lbl_next));
+
+ /*
+ * if (*dctx.act != act) // ldw %r0, [%r9 + DCTX_ACT]
+ * goto exit; // ldw %r0, [%r0 + 0]
+ * // jne %r0, act, lbl_exit
+ */
+ emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_9, DCTX_ACT));
+ emit(dlp, BPF_LOAD(BPF_W, BPF_REG_0, BPF_REG_0, 0));
+ emit(dlp, BPF_BRANCH_IMM(BPF_JNE, BPF_REG_0, DT_ACTIVITY_ACTIVE, lbl_exit));
+
+ /* dctx.mst->scratch_top = 8 */
+ emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_7, DMST_SCRATCH_TOP, 8));
+
+ /* Call clause. */
+ emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_9));
+ emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
+
+ /* Finished this clause. */
+ emitl(dlp, lbl_next,
+ BPF_NOP());
+
+ /* Right-shift %r6. */
+ emit(dlp, BPF_ALU64_IMM(BPF_RSH, BPF_REG_6, 1));
+ }
+
+out:
dt_cg_tramp_return(pcb);
return 0;
@@ -798,10 +894,9 @@ static int trampoline_is_enabled(dt_pcb_t *pcb, uint_t exitlbl)
{
dt_irlist_t *dlp = &pcb->pcb_ir;
const dt_probe_t *uprp = pcb->pcb_probe;
- const dt_uprobe_t *upp = uprp->prv_data;
- const list_probe_t *pop;
- uint_t lbl_assign = dt_irlist_label(dlp);
- uint_t lbl_exit = pcb->pcb_exitlbl;
+ dt_ident_t *usdt_prids = dt_dlib_get_map(pcb->pcb_hdl, "usdt_prids");
+
+ assert(usdt_prids != NULL);
dt_cg_tramp_prologue(pcb);
@@ -810,7 +905,6 @@ static int trampoline_is_enabled(dt_pcb_t *pcb, uint_t exitlbl)
* // (%r7 = dctx->mst)
* // (%r8 = dctx->ctx)
*/
-
dt_cg_tramp_copy_regs(pcb);
/*
@@ -828,46 +922,30 @@ static int trampoline_is_enabled(dt_pcb_t *pcb, uint_t exitlbl)
emit(dlp, BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32));
/*
- * Generate a composite conditional clause, as above, except that rather
- * than emitting call_clauses, we emit copyouts instead, using
- * copyout_val() above:
+ * Look up in the BPF 'usdt_prids' map. Space for the look-up key
+ * will be used on the BPF stack:
*
- * if (pid == PID1) {
- * goto assign;
- * } else if (pid == PID2) {
- * goto assign;
- * } else if (pid == ...) {
- * goto assign;
- * }
- * goto exit;
- * assign:
- * *arg0 = 1;
- * goto exit;
+ * offset value
*
- * It is valid and safe to use %r0 to hold the pid value because there
- * are no assignments to %r0 possible in between the conditional
- * statements.
+ * -sizeof(usdt_prids_map_key_t) pid (in %r0)
+ *
+ * -sizeof(usdt_prids_map_key_t) + sizeof(pid_t)
+ * ==
+ * -sizeof(dtrace_id_t) underlying-probe prid
*/
- for (pop = dt_list_next(&upp->probes); pop != NULL;
- pop = dt_list_next(pop)) {
- const dt_probe_t *prp = pop->probe;
- pid_t pid;
- dt_ident_t *idp;
+ emit(dlp, BPF_STORE(BPF_W, BPF_REG_9, (int)(-sizeof(usdt_prids_map_key_t)), BPF_REG_0));
+ emit(dlp, BPF_STORE_IMM(BPF_W, BPF_REG_9, (int)(-sizeof(dtrace_id_t)), uprp->desc->id));
+ dt_cg_xsetx(dlp, usdt_prids, DT_LBL_NONE, BPF_REG_1, usdt_prids->di_id);
+ emit(dlp, BPF_MOV_REG(BPF_REG_2, BPF_REG_9));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, (int)(-sizeof(usdt_prids_map_key_t))));
+ emit(dlp, BPF_CALL_HELPER(BPF_FUNC_map_lookup_elem));
+ emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, pcb->pcb_exitlbl));
- pid = dt_pid_get_pid(prp->desc, pcb->pcb_hdl, pcb, NULL);
- assert(pid != -1);
-
- idp = dt_dlib_add_probe_var(pcb->pcb_hdl, prp);
- assert(idp != NULL);
-
- /*
- * Check whether this pid-provider probe serves the current
- * process, and copy out a 1 into arg 0 if so.
- */
- emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, pid, lbl_assign));
- }
- emit(dlp, BPF_JUMP(lbl_exit));
- copyout_val(pcb, lbl_assign, 1, 0);
+ /*
+ * If we succeeded, then we use copyout_val() above to assign:
+ * *arg0 = 1;
+ */
+ copyout_val(pcb, DT_LBL_NONE, 1, 0);
dt_cg_tramp_return(pcb);
--
2.43.5
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v3 11/19] Support USDT wildcard provider descriptions
2024-09-24 20:25 [PATCH v7 03/19] Deprecate enabled probe ID (epid) eugene.loh
` (2 preceding siblings ...)
2024-09-24 20:25 ` [PATCH v3 09/19] Use usdt_prids map to call clauses conditionally for USDT probes eugene.loh
@ 2024-09-24 20:25 ` eugene.loh
2024-10-24 16:38 ` Kris Van Hees
2024-09-24 20:25 ` [PATCH v2 14/19] Ignore clauses in USDT trampoline if we know they are impossible eugene.loh
2024-09-24 20:25 ` [PATCH v2 15/19] Ignore clauses: some clauses are impossible regardless of uprp eugene.loh
5 siblings, 1 reply; 14+ messages in thread
From: eugene.loh @ 2024-09-24 20:25 UTC (permalink / raw)
To: dtrace, dtrace-devel
From: Eugene Loh <eugene.loh@oracle.com>
To look for pid probes, whose pid values must be specified explicitly,
we can require that the provider description should end in a digit.
For USDT probes, however, there can be wildcard descriptions. This
includes a blank provider description as well as a description that
ends in an '*'.
So, in dt_setcontext(), expand the criteria appropriately. And
modify dt_pid_create_probes() accordingly.
This is rudimentary support. We still need to:
- handle globs in dt_pid_create_probes_module()
- add process monitoring / inotify
Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
libdtrace/dt_cc.c | 5 +++--
test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh | 1 -
test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh | 1 -
test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh | 1 -
test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh | 1 -
test/unittest/usdt/tst.forker.sh | 1 -
6 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index 12104fc21..62482a70f 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -273,8 +273,9 @@ dt_setcontext(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp)
* On an error, dt_pid_create_probes() will set the error message
* and tag -- we just have to longjmp() out of here.
*/
- if (pdp->prv && pdp->prv[0] &&
- isdigit(pdp->prv[strlen(pdp->prv) - 1]) &&
+ if (pdp->prv &&
+ (pdp->prv[0] == '\0' || isdigit(pdp->prv[strlen(pdp->prv) - 1]) ||
+ pdp->prv[strlen(pdp->prv) - 1] == '*') &&
((pvp = dt_provider_lookup(dtp, pdp->prv)) == NULL ||
pvp->pv_flags & DT_PROVIDER_PID) &&
dt_pid_create_probes((dtrace_probedesc_t *)pdp, dtp, yypcb) != 0) {
diff --git a/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh
index bd0552dca..99ae995eb 100755
--- a/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh
+++ b/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh
@@ -5,7 +5,6 @@
# Licensed under the Universal Permissive License v 1.0 as shown at
# http://oss.oracle.com/licenses/upl.
#
-# @@xfail: dtv2
##
#
diff --git a/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh
index 7b9c6a5fc..5ae087fbf 100755
--- a/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh
+++ b/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh
@@ -5,7 +5,6 @@
# Licensed under the Universal Permissive License v 1.0 as shown at
# http://oss.oracle.com/licenses/upl.
#
-# @@xfail: dtv2
##
#
diff --git a/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh
index f9b1d8bf8..5c0509d89 100755
--- a/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh
+++ b/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh
@@ -5,7 +5,6 @@
# Licensed under the Universal Permissive License v 1.0 as shown at
# http://oss.oracle.com/licenses/upl.
#
-# @@xfail: dtv2
##
#
diff --git a/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh
index 644da2ac2..6eae82ed9 100755
--- a/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh
+++ b/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh
@@ -5,7 +5,6 @@
# Licensed under the Universal Permissive License v 1.0 as shown at
# http://oss.oracle.com/licenses/upl.
#
-# @@xfail: dtv2
##
#
diff --git a/test/unittest/usdt/tst.forker.sh b/test/unittest/usdt/tst.forker.sh
index 7cfa9eb5f..92513eb5d 100755
--- a/test/unittest/usdt/tst.forker.sh
+++ b/test/unittest/usdt/tst.forker.sh
@@ -7,7 +7,6 @@
#
#
# @@timeout: 120
-# @@xfail: dtv2 USDT wildcard
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
--
2.43.5
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v3 11/19] Support USDT wildcard provider descriptions
2024-09-24 20:25 ` [PATCH v3 11/19] Support USDT wildcard provider descriptions eugene.loh
@ 2024-10-24 16:38 ` Kris Van Hees
2024-10-25 5:56 ` Eugene Loh
0 siblings, 1 reply; 14+ messages in thread
From: Kris Van Hees @ 2024-10-24 16:38 UTC (permalink / raw)
To: eugene.loh; +Cc: dtrace, dtrace-devel
On Tue, Sep 24, 2024 at 04:25:52PM -0400, eugene.loh@oracle.com wrote:
> From: Eugene Loh <eugene.loh@oracle.com>
>
> To look for pid probes, whose pid values must be specified explicitly,
> we can require that the provider description should end in a digit.
>
> For USDT probes, however, there can be wildcard descriptions. This
> includes a blank provider description as well as a description that
> ends in an '*'.
What about 'test*1234' or 'test*12*' or 'test*1*2*4'? All should match
'test_prov1234', right?
> So, in dt_setcontext(), expand the criteria appropriately. And
> modify dt_pid_create_probes() accordingly.
>
> This is rudimentary support. We still need to:
> - handle globs in dt_pid_create_probes_module()
> - add process monitoring / inotify
>
> Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
> ---
> libdtrace/dt_cc.c | 5 +++--
> test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh | 1 -
> test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh | 1 -
> test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh | 1 -
> test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh | 1 -
> test/unittest/usdt/tst.forker.sh | 1 -
> 6 files changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
> index 12104fc21..62482a70f 100644
> --- a/libdtrace/dt_cc.c
> +++ b/libdtrace/dt_cc.c
> @@ -273,8 +273,9 @@ dt_setcontext(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp)
> * On an error, dt_pid_create_probes() will set the error message
> * and tag -- we just have to longjmp() out of here.
> */
> - if (pdp->prv && pdp->prv[0] &&
> - isdigit(pdp->prv[strlen(pdp->prv) - 1]) &&
> + if (pdp->prv &&
> + (pdp->prv[0] == '\0' || isdigit(pdp->prv[strlen(pdp->prv) - 1]) ||
> + pdp->prv[strlen(pdp->prv) - 1] == '*') &&
> ((pvp = dt_provider_lookup(dtp, pdp->prv)) == NULL ||
> pvp->pv_flags & DT_PROVIDER_PID) &&
> dt_pid_create_probes((dtrace_probedesc_t *)pdp, dtp, yypcb) != 0) {
First of all, I am not sure that combining pid and USDT probe handling here
by means of dt_pid_create_probes() makes sense under the new scheme. In fact,
dt_pid_create_probes() may no longer be needed because handling them separately
seems better.
Then there are two cases:
- For pid probes, a provider name must have been supplied and it must have a
digit as last character. So, for pid probes you can keep the original code
aside from replacing dt_pid_create_probes() with dt_pid_create_pid_probes().
- For USDT probes, there aren't any restrictions, other than the ones already
done in dt_pid_create_usdt_probes(). So, a call to that function should be
done here without any conditional.
> diff --git a/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh
> index bd0552dca..99ae995eb 100755
> --- a/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh
> +++ b/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh
> @@ -5,7 +5,6 @@
> # Licensed under the Universal Permissive License v 1.0 as shown at
> # http://oss.oracle.com/licenses/upl.
> #
> -# @@xfail: dtv2
>
> ##
> #
> diff --git a/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh
> index 7b9c6a5fc..5ae087fbf 100755
> --- a/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh
> +++ b/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh
> @@ -5,7 +5,6 @@
> # Licensed under the Universal Permissive License v 1.0 as shown at
> # http://oss.oracle.com/licenses/upl.
> #
> -# @@xfail: dtv2
>
> ##
> #
> diff --git a/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh
> index f9b1d8bf8..5c0509d89 100755
> --- a/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh
> +++ b/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh
> @@ -5,7 +5,6 @@
> # Licensed under the Universal Permissive License v 1.0 as shown at
> # http://oss.oracle.com/licenses/upl.
> #
> -# @@xfail: dtv2
>
> ##
> #
> diff --git a/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh
> index 644da2ac2..6eae82ed9 100755
> --- a/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh
> +++ b/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh
> @@ -5,7 +5,6 @@
> # Licensed under the Universal Permissive License v 1.0 as shown at
> # http://oss.oracle.com/licenses/upl.
> #
> -# @@xfail: dtv2
>
> ##
> #
> diff --git a/test/unittest/usdt/tst.forker.sh b/test/unittest/usdt/tst.forker.sh
> index 7cfa9eb5f..92513eb5d 100755
> --- a/test/unittest/usdt/tst.forker.sh
> +++ b/test/unittest/usdt/tst.forker.sh
> @@ -7,7 +7,6 @@
> #
> #
> # @@timeout: 120
> -# @@xfail: dtv2 USDT wildcard
>
> if [ $# != 1 ]; then
> echo expected one argument: '<'dtrace-path'>'
> --
> 2.43.5
>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v3 11/19] Support USDT wildcard provider descriptions
2024-10-24 16:38 ` Kris Van Hees
@ 2024-10-25 5:56 ` Eugene Loh
2024-10-25 12:48 ` Kris Van Hees
0 siblings, 1 reply; 14+ messages in thread
From: Eugene Loh @ 2024-10-25 5:56 UTC (permalink / raw)
To: dtrace, dtrace-devel
On 10/24/24 12:38, Kris Van Hees wrote:
> On Tue, Sep 24, 2024 at 04:25:52PM -0400, eugene.loh@oracle.com wrote:
>> From: Eugene Loh <eugene.loh@oracle.com>
>>
>> To look for pid probes, whose pid values must be specified explicitly,
>> we can require that the provider description should end in a digit.
>>
>> For USDT probes, however, there can be wildcard descriptions. This
>> includes a blank provider description as well as a description that
>> ends in an '*'.
> What about 'test*1234' or 'test*12*' or 'test*1*2*4'? All should match
> 'test_prov1234', right?
Right. "test*1234" and "test*1*2*4" already end in a digit, so were
already included.
"test*12*" ends in an '*' and so is added by the patch.
>> So, in dt_setcontext(), expand the criteria appropriately. And
>> modify dt_pid_create_probes() accordingly.
>>
>> This is rudimentary support. We still need to:
>> - handle globs in dt_pid_create_probes_module()
>> - add process monitoring / inotify
>>
>> Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
>>
>> diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
>> index 12104fc21..62482a70f 100644
>> --- a/libdtrace/dt_cc.c
>> +++ b/libdtrace/dt_cc.c
>> @@ -273,8 +273,9 @@ dt_setcontext(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp)
>> * On an error, dt_pid_create_probes() will set the error message
>> * and tag -- we just have to longjmp() out of here.
>> */
>> - if (pdp->prv && pdp->prv[0] &&
>> - isdigit(pdp->prv[strlen(pdp->prv) - 1]) &&
>> + if (pdp->prv &&
>> + (pdp->prv[0] == '\0' || isdigit(pdp->prv[strlen(pdp->prv) - 1]) ||
>> + pdp->prv[strlen(pdp->prv) - 1] == '*') &&
>> ((pvp = dt_provider_lookup(dtp, pdp->prv)) == NULL ||
>> pvp->pv_flags & DT_PROVIDER_PID) &&
>> dt_pid_create_probes((dtrace_probedesc_t *)pdp, dtp, yypcb) != 0) {
> First of all, I am not sure that combining pid and USDT probe handling here
> by means of dt_pid_create_probes() makes sense under the new scheme. In fact,
> dt_pid_create_probes() may no longer be needed because handling them separately
> seems better.
>
> Then there are two cases:
>
> - For pid probes, a provider name must have been supplied and it must have a
> digit as last character. So, for pid probes you can keep the original code
> aside from replacing dt_pid_create_probes() with dt_pid_create_pid_probes().
>
> - For USDT probes, there aren't any restrictions, other than the ones already
> done in dt_pid_create_usdt_probes(). So, a call to that function should be
> done here without any conditional.
Okay, though I don't really understand the dt_setcontext() logic. E.g.,
we test pdp->prv!=NULL. If it could be NULL, then we should still check
before calling dt_pid_create_usdt_probes(). Stuff like that. But I made
your suggested change and it passed tests... so good enough for me.
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v3 11/19] Support USDT wildcard provider descriptions
2024-10-25 5:56 ` Eugene Loh
@ 2024-10-25 12:48 ` Kris Van Hees
0 siblings, 0 replies; 14+ messages in thread
From: Kris Van Hees @ 2024-10-25 12:48 UTC (permalink / raw)
To: Eugene Loh; +Cc: dtrace, dtrace-devel
On Fri, Oct 25, 2024 at 01:56:34AM -0400, Eugene Loh wrote:
> On 10/24/24 12:38, Kris Van Hees wrote:
>
> > On Tue, Sep 24, 2024 at 04:25:52PM -0400, eugene.loh@oracle.com wrote:
> > > From: Eugene Loh <eugene.loh@oracle.com>
> > >
> > > To look for pid probes, whose pid values must be specified explicitly,
> > > we can require that the provider description should end in a digit.
> > >
> > > For USDT probes, however, there can be wildcard descriptions. This
> > > includes a blank provider description as well as a description that
> > > ends in an '*'.
> > What about 'test*1234' or 'test*12*' or 'test*1*2*4'? All should match
> > 'test_prov1234', right?
>
> Right. "test*1234" and "test*1*2*4" already end in a digit, so were already
> included.
> "test*12*" ends in an '*' and so is added by the patch.
Err, duh. I should have seen that - should have had more coffee.
> > > So, in dt_setcontext(), expand the criteria appropriately. And
> > > modify dt_pid_create_probes() accordingly.
> > >
> > > This is rudimentary support. We still need to:
> > > - handle globs in dt_pid_create_probes_module()
> > > - add process monitoring / inotify
> > >
> > > Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
> > >
> > > diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
> > > index 12104fc21..62482a70f 100644
> > > --- a/libdtrace/dt_cc.c
> > > +++ b/libdtrace/dt_cc.c
> > > @@ -273,8 +273,9 @@ dt_setcontext(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp)
> > > * On an error, dt_pid_create_probes() will set the error message
> > > * and tag -- we just have to longjmp() out of here.
> > > */
> > > - if (pdp->prv && pdp->prv[0] &&
> > > - isdigit(pdp->prv[strlen(pdp->prv) - 1]) &&
> > > + if (pdp->prv &&
> > > + (pdp->prv[0] == '\0' || isdigit(pdp->prv[strlen(pdp->prv) - 1]) ||
> > > + pdp->prv[strlen(pdp->prv) - 1] == '*') &&
> > > ((pvp = dt_provider_lookup(dtp, pdp->prv)) == NULL ||
> > > pvp->pv_flags & DT_PROVIDER_PID) &&
> > > dt_pid_create_probes((dtrace_probedesc_t *)pdp, dtp, yypcb) != 0) {
> > First of all, I am not sure that combining pid and USDT probe handling here
> > by means of dt_pid_create_probes() makes sense under the new scheme. In fact,
> > dt_pid_create_probes() may no longer be needed because handling them separately
> > seems better.
> >
> > Then there are two cases:
> >
> > - For pid probes, a provider name must have been supplied and it must have a
> > digit as last character. So, for pid probes you can keep the original code
> > aside from replacing dt_pid_create_probes() with dt_pid_create_pid_probes().
> >
> > - For USDT probes, there aren't any restrictions, other than the ones already
> > done in dt_pid_create_usdt_probes(). So, a call to that function should be
> > done here without any conditional.
>
> Okay, though I don't really understand the dt_setcontext() logic. E.g., we
> test pdp->prv!=NULL. If it could be NULL, then we should still check before
> calling dt_pid_create_usdt_probes(). Stuff like that. But I made your
> suggested change and it passed tests... so good enough for me.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 14/19] Ignore clauses in USDT trampoline if we know they are impossible
2024-09-24 20:25 [PATCH v7 03/19] Deprecate enabled probe ID (epid) eugene.loh
` (3 preceding siblings ...)
2024-09-24 20:25 ` [PATCH v3 11/19] Support USDT wildcard provider descriptions eugene.loh
@ 2024-09-24 20:25 ` eugene.loh
2024-09-24 20:25 ` [PATCH v2 15/19] Ignore clauses: some clauses are impossible regardless of uprp eugene.loh
5 siblings, 0 replies; 14+ messages in thread
From: eugene.loh @ 2024-09-24 20:25 UTC (permalink / raw)
To: dtrace, dtrace-devel
From: Eugene Loh <eugene.loh@oracle.com>
An underlying probe might have to call all sorts of clauses if new
USDT processes start up. Currently, the underlying probe trampoline
simply loops over all clauses, deciding whether to call a clause
based on a run-time bit mask.
While this approach works, it can mean, e.g., that clauses are being
loaded unnecessarily into BPF programs, bloating code. It also means
that the trampoline is looping over unnecessarily many clauses.
Meanwhile, it is possible to know in certain cases that a clause
could never be called for a particular underlying probe. The
heuristics can be tricky, but that challenge can be faced incrementally.
Introduce an ignore_clause() function that, for an underlying probe,
determines whether some clause (denoted by index) can safely be
ignored.
The same ignore_clause() function should be called both during code
generation of the trampoline as well as during the construction of
the bit mask. Further, for a given clause n and underlying probe upp,
the function should always give the same output. The set of ignored
clauses should remain fixed over the lifetime of an underlying probe.
For now, conservatively, ignore_clause() ignores nothing. Later
patches will introduce heuristics for ignoring clauses.
Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
libdtrace/dt_prov_uprobe.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index d08bd2e14..51ad3b55f 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -232,6 +232,17 @@ grow_strtab(dtrace_hdl_t *dtp)
return 0;
}
+/*
+ * Judge whether clause "n" could ever be called as a USDT probe
+ * for this underlying probe.
+ */
+static int
+ignore_clause(dtrace_hdl_t *dtp, int n, const dt_probe_t *uprp)
+{
+ /* To be safe, ignore nothing. */
+ return 0;
+}
+
/*
* Update the uprobe provider.
*/
@@ -358,6 +369,9 @@ static void update_uprobe(dtrace_hdl_t *dtp, void *datap)
stp = dtp->dt_stmts[n];
assert(stp != NULL);
+ if (ignore_clause(dtp, n, uprp))
+ continue;
+
if (dt_gmatch(prp->desc->prv, stp->dtsd_ecbdesc->dted_probe.prv) &&
dt_gmatch(prp->desc->mod, stp->dtsd_ecbdesc->dted_probe.mod) &&
dt_gmatch(prp->desc->fun, stp->dtsd_ecbdesc->dted_probe.fun) &&
@@ -814,11 +828,16 @@ static int trampoline(dt_pcb_t *pcb, uint_t exitlbl)
for (n = 0; n < dtp->dt_stmt_nextid; n++) {
dtrace_stmtdesc_t *stp;
dt_ident_t *idp;
- uint_t lbl_next = dt_irlist_label(dlp);
+ uint_t lbl_next;
stp = dtp->dt_stmts[n];
assert(stp != NULL);
+
+ if (ignore_clause(dtp, n, uprp))
+ continue;
+
idp = stp->dtsd_clause;
+ lbl_next = dt_irlist_label(dlp);
/* If the lowest %r6 bit is 0, skip over this clause. */
emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_6));
--
2.43.5
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH v2 15/19] Ignore clauses: some clauses are impossible regardless of uprp
2024-09-24 20:25 [PATCH v7 03/19] Deprecate enabled probe ID (epid) eugene.loh
` (4 preceding siblings ...)
2024-09-24 20:25 ` [PATCH v2 14/19] Ignore clauses in USDT trampoline if we know they are impossible eugene.loh
@ 2024-09-24 20:25 ` eugene.loh
2024-10-23 20:28 ` Kris Van Hees
5 siblings, 1 reply; 14+ messages in thread
From: eugene.loh @ 2024-09-24 20:25 UTC (permalink / raw)
To: dtrace, dtrace-devel
From: Eugene Loh <eugene.loh@oracle.com>
In ignore_clauses, for an underlying probe uprp, we try to
decide if we can safely ignore clause n.
Meanwhile, for some clauses, the probe description tells us the
clause will not be called for any USDT probe, regardless of the
underlying probe. For example, "syscall::write:" can safely be
ignored, for all uprp.
Add a dtsd_usdt variable to each statement to track status:
USDT_FLAG_UNINITIALIZED not yet initialized
USDT_FLAG_POSSIBLE clause could possibly be called
for some USDT probe
USDT_FLAG_IGNORE clause can safely be ignored for
all USDT probes
Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
---
libdtrace/dt_prov_uprobe.c | 56 ++++++++++++++++++++++++++++++++++++--
libdtrace/dtrace.h | 1 +
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index 51ad3b55f..938c5784a 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -27,6 +27,7 @@
*/
#include <sys/types.h>
#include <assert.h>
+#include <ctype.h>
#include <errno.h>
#include <string.h>
@@ -232,6 +233,10 @@ grow_strtab(dtrace_hdl_t *dtp)
return 0;
}
+#define USDT_FLAG_UNINITIALIZED 0
+#define USDT_FLAG_POSSIBLE 1
+#define USDT_FLAG_IGNORE 2
+
/*
* Judge whether clause "n" could ever be called as a USDT probe
* for this underlying probe.
@@ -239,7 +244,53 @@ grow_strtab(dtrace_hdl_t *dtp)
static int
ignore_clause(dtrace_hdl_t *dtp, int n, const dt_probe_t *uprp)
{
- /* To be safe, ignore nothing. */
+ dtrace_probedesc_t *pdp = &dtp->dt_stmts[n]->dtsd_ecbdesc->dted_probe;
+ int *usdt_stat = &dtp->dt_stmts[n]->dtsd_usdt;
+
+ /*
+ * Some clauses could never be called for a USDT probe,
+ * regardless of the underlying probe uprp. Cache this
+ * status in dt_stmts[n]->dtsd_usdt (pointed to by usdt_stat).
+ */
+ if (*usdt_stat == USDT_FLAG_UNINITIALIZED) {
+ char lastchar = pdp->prv[strlen(pdp->prv) - 1];
+
+ /*
+ * If the last char in the provider description is
+ * neither '*' nor a digit, it cannot be a USDT probe.
+ */
+ if (lastchar != '*' && !isdigit(lastchar)) {
+ *usdt_stat = USDT_FLAG_IGNORE;
+ return 1;
+ }
+
+ /*
+ * If the provider description is "pid[0-9]*", it
+ * is a pid probe, not USDT.
+ */
+ if (strncmp(pdp->prv, "pid", 3) == 0) {
+ int i, l = strlen(pdp->prv);
+
+ for (i = 3; i < l; i++)
+ if (!isdigit((pdp->prv[i])))
+ break;
+
+ if (i == l) {
+ *usdt_stat = USDT_FLAG_IGNORE;
+ return 1;
+ }
+ }
+
+ /* Otherwise, it is possibly a USDT probe. */
+ *usdt_stat = USDT_FLAG_POSSIBLE;
+ }
+ if (*usdt_stat == USDT_FLAG_IGNORE)
+ return 1;
+
+ /*
+ * If USDT_FLAG_POSSIBLE, try to use uprp.
+ */
+
return 0;
}
@@ -271,7 +322,8 @@ static void update_uprobe(dtrace_hdl_t *dtp, void *datap)
stp = dtp->dt_stmts[i];
assert(stp != NULL);
- dt_pid_create_usdt_probes(&stp->dtsd_ecbdesc->dted_probe, dtp, &pcb);
+ if (stp->dtsd_usdt != USDT_FLAG_IGNORE)
+ dt_pid_create_usdt_probes(&stp->dtsd_ecbdesc->dted_probe, dtp, &pcb);
}
while (prid < dtp->dt_probe_id) {
diff --git a/libdtrace/dtrace.h b/libdtrace/dtrace.h
index 0f716cd40..f99fb5b6e 100644
--- a/libdtrace/dtrace.h
+++ b/libdtrace/dtrace.h
@@ -151,6 +151,7 @@ typedef struct dtrace_stmtdesc {
dtrace_attribute_t dtsd_stmtattr; /* statement attributes */
int dtsd_clauseflags; /* clause flags */
int dtsd_id; /* index in dtp->dt_stmts */
+ int dtsd_usdt; /* flags describing USDT use, see dt_prov_uprobe.c */
} dtrace_stmtdesc_t;
/* dtsd clause flags */
--
2.43.5
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH v2 15/19] Ignore clauses: some clauses are impossible regardless of uprp
2024-09-24 20:25 ` [PATCH v2 15/19] Ignore clauses: some clauses are impossible regardless of uprp eugene.loh
@ 2024-10-23 20:28 ` Kris Van Hees
2024-10-24 19:30 ` Eugene Loh
0 siblings, 1 reply; 14+ messages in thread
From: Kris Van Hees @ 2024-10-23 20:28 UTC (permalink / raw)
To: eugene.loh; +Cc: dtrace, dtrace-devel
On Tue, Sep 24, 2024 at 04:25:54PM -0400, eugene.loh@oracle.com wrote:
> From: Eugene Loh <eugene.loh@oracle.com>
>
> In ignore_clauses, for an underlying probe uprp, we try to
> decide if we can safely ignore clause n.
>
> Meanwhile, for some clauses, the probe description tells us the
> clause will not be called for any USDT probe, regardless of the
> underlying probe. For example, "syscall::write:" can safely be
> ignored, for all uprp.
>
> Add a dtsd_usdt variable to each statement to track status:
>
> USDT_FLAG_UNINITIALIZED not yet initialized
>
> USDT_FLAG_POSSIBLE clause could possibly be called
> for some USDT probe
>
> USDT_FLAG_IGNORE clause can safely be ignored for
> all USDT probes
I think it would be better to use the dtsd_clauseflags member for this.
You can add dt_stmt_set_flag() and dt_stmt_test_flag() (or similar names)
to set and test for specific bits in the dtsd_clauseflags member using
DT_CLSFLAG_* constants. You should be OK with just 2, one to indicate
POSSIBLE and one to indicate IGNORE (neither being set obviously meansnot
yet initialized).
I don't really know what symbol names would be best... perhaps for now use
DT_CLSFLAG_USDT_INCLUDE and DT_CLSFLAG_USDT_EXCLUDE?
Main thing I would like to accomplish here is simply to access flags on the
statements through functions rather than accessing them directly.
>
> Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
> ---
> libdtrace/dt_prov_uprobe.c | 56 ++++++++++++++++++++++++++++++++++++--
> libdtrace/dtrace.h | 1 +
> 2 files changed, 55 insertions(+), 2 deletions(-)
>
> diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
> index 51ad3b55f..938c5784a 100644
> --- a/libdtrace/dt_prov_uprobe.c
> +++ b/libdtrace/dt_prov_uprobe.c
> @@ -27,6 +27,7 @@
> */
> #include <sys/types.h>
> #include <assert.h>
> +#include <ctype.h>
> #include <errno.h>
> #include <string.h>
>
> @@ -232,6 +233,10 @@ grow_strtab(dtrace_hdl_t *dtp)
> return 0;
> }
>
> +#define USDT_FLAG_UNINITIALIZED 0
> +#define USDT_FLAG_POSSIBLE 1
> +#define USDT_FLAG_IGNORE 2
> +
> /*
> * Judge whether clause "n" could ever be called as a USDT probe
> * for this underlying probe.
> @@ -239,7 +244,53 @@ grow_strtab(dtrace_hdl_t *dtp)
> static int
> ignore_clause(dtrace_hdl_t *dtp, int n, const dt_probe_t *uprp)
> {
> - /* To be safe, ignore nothing. */
> + dtrace_probedesc_t *pdp = &dtp->dt_stmts[n]->dtsd_ecbdesc->dted_probe;
> + int *usdt_stat = &dtp->dt_stmts[n]->dtsd_usdt;
> +
> + /*
> + * Some clauses could never be called for a USDT probe,
> + * regardless of the underlying probe uprp. Cache this
> + * status in dt_stmts[n]->dtsd_usdt (pointed to by usdt_stat).
> + */
> + if (*usdt_stat == USDT_FLAG_UNINITIALIZED) {
> + char lastchar = pdp->prv[strlen(pdp->prv) - 1];
> +
> + /*
> + * If the last char in the provider description is
> + * neither '*' nor a digit, it cannot be a USDT probe.
> + */
> + if (lastchar != '*' && !isdigit(lastchar)) {
> + *usdt_stat = USDT_FLAG_IGNORE;
> + return 1;
> + }
> +
> + /*
> + * If the provider description is "pid[0-9]*", it
> + * is a pid probe, not USDT.
> + */
> + if (strncmp(pdp->prv, "pid", 3) == 0) {
> + int i, l = strlen(pdp->prv);
> +
> + for (i = 3; i < l; i++)
> + if (!isdigit((pdp->prv[i])))
> + break;
> +
> + if (i == l) {
> + *usdt_stat = USDT_FLAG_IGNORE;
> + return 1;
> + }
> + }
> +
> + /* Otherwise, it is possibly a USDT probe. */
> + *usdt_stat = USDT_FLAG_POSSIBLE;
> + }
> + if (*usdt_stat == USDT_FLAG_IGNORE)
> + return 1;
> +
> + /*
> + * If USDT_FLAG_POSSIBLE, try to use uprp.
> + */
> +
> return 0;
> }
>
> @@ -271,7 +322,8 @@ static void update_uprobe(dtrace_hdl_t *dtp, void *datap)
>
> stp = dtp->dt_stmts[i];
> assert(stp != NULL);
> - dt_pid_create_usdt_probes(&stp->dtsd_ecbdesc->dted_probe, dtp, &pcb);
> + if (stp->dtsd_usdt != USDT_FLAG_IGNORE)
> + dt_pid_create_usdt_probes(&stp->dtsd_ecbdesc->dted_probe, dtp, &pcb);
> }
>
> while (prid < dtp->dt_probe_id) {
> diff --git a/libdtrace/dtrace.h b/libdtrace/dtrace.h
> index 0f716cd40..f99fb5b6e 100644
> --- a/libdtrace/dtrace.h
> +++ b/libdtrace/dtrace.h
> @@ -151,6 +151,7 @@ typedef struct dtrace_stmtdesc {
> dtrace_attribute_t dtsd_stmtattr; /* statement attributes */
> int dtsd_clauseflags; /* clause flags */
> int dtsd_id; /* index in dtp->dt_stmts */
> + int dtsd_usdt; /* flags describing USDT use, see dt_prov_uprobe.c */
> } dtrace_stmtdesc_t;
>
> /* dtsd clause flags */
> --
> 2.43.5
>
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v2 15/19] Ignore clauses: some clauses are impossible regardless of uprp
2024-10-23 20:28 ` Kris Van Hees
@ 2024-10-24 19:30 ` Eugene Loh
2024-10-24 21:12 ` [DTrace-devel] " Kris Van Hees
0 siblings, 1 reply; 14+ messages in thread
From: Eugene Loh @ 2024-10-24 19:30 UTC (permalink / raw)
To: dtrace, dtrace-devel
On 10/23/24 16:28, Kris Van Hees wrote:
> On Tue, Sep 24, 2024 at 04:25:54PM -0400, eugene.loh@oracle.com wrote:
>> From: Eugene Loh <eugene.loh@oracle.com>
>>
>> In ignore_clauses, for an underlying probe uprp, we try to
>> decide if we can safely ignore clause n.
>>
>> Meanwhile, for some clauses, the probe description tells us the
>> clause will not be called for any USDT probe, regardless of the
>> underlying probe. For example, "syscall::write:" can safely be
>> ignored, for all uprp.
>>
>> Add a dtsd_usdt variable to each statement to track status:
>>
>> USDT_FLAG_UNINITIALIZED not yet initialized
>>
>> USDT_FLAG_POSSIBLE clause could possibly be called
>> for some USDT probe
>>
>> USDT_FLAG_IGNORE clause can safely be ignored for
>> all USDT probes
> I think it would be better to use the dtsd_clauseflags member for this.
> You can add dt_stmt_set_flag() and dt_stmt_test_flag() (or similar names)
> to set and test for specific bits in the dtsd_clauseflags member using
> DT_CLSFLAG_* constants. You should be OK with just 2, one to indicate
> POSSIBLE and one to indicate IGNORE (neither being set obviously meansnot
> yet initialized).
>
> I don't really know what symbol names would be best... perhaps for now use
> DT_CLSFLAG_USDT_INCLUDE and DT_CLSFLAG_USDT_EXCLUDE?
>
> Main thing I would like to accomplish here is simply to access flags on the
> statements through functions rather than accessing them directly.
I'd like to push back here.
First of all, the patch exposes only dtsd_usdt at the dtrace.h level.
That variable can hide whatever it is that USDT wants to do with it.
Your proposal would expose at least USDT_INCLUDE/EXCLUDE (or
POSSIBLE/IGNORE or whatever we want to call them) in dtrace.h, and I do
not know if future USDT would have even more stuff it wants to play
with, meaning even more changes outside of the provider.
Second, you say the main point is to access flags through functions
rather than directly, but to date we've been accessing flags directly.
The set/test functions would be new. If we want to stop the direct
accesses, that would seem to be a different patch.
Thoughts?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [DTrace-devel] [PATCH v2 15/19] Ignore clauses: some clauses are impossible regardless of uprp
2024-10-24 19:30 ` Eugene Loh
@ 2024-10-24 21:12 ` Kris Van Hees
2024-10-24 21:53 ` Eugene Loh
0 siblings, 1 reply; 14+ messages in thread
From: Kris Van Hees @ 2024-10-24 21:12 UTC (permalink / raw)
To: Eugene Loh; +Cc: dtrace, dtrace-devel
On Thu, Oct 24, 2024 at 03:30:13PM -0400, Eugene Loh via DTrace-devel wrote:
>
> On 10/23/24 16:28, Kris Van Hees wrote:
> > On Tue, Sep 24, 2024 at 04:25:54PM -0400, eugene.loh@oracle.com wrote:
> > > From: Eugene Loh <eugene.loh@oracle.com>
> > >
> > > In ignore_clauses, for an underlying probe uprp, we try to
> > > decide if we can safely ignore clause n.
> > >
> > > Meanwhile, for some clauses, the probe description tells us the
> > > clause will not be called for any USDT probe, regardless of the
> > > underlying probe. For example, "syscall::write:" can safely be
> > > ignored, for all uprp.
> > >
> > > Add a dtsd_usdt variable to each statement to track status:
> > >
> > > USDT_FLAG_UNINITIALIZED not yet initialized
> > >
> > > USDT_FLAG_POSSIBLE clause could possibly be called
> > > for some USDT probe
> > >
> > > USDT_FLAG_IGNORE clause can safely be ignored for
> > > all USDT probes
> > I think it would be better to use the dtsd_clauseflags member for this.
> > You can add dt_stmt_set_flag() and dt_stmt_test_flag() (or similar names)
> > to set and test for specific bits in the dtsd_clauseflags member using
> > DT_CLSFLAG_* constants. You should be OK with just 2, one to indicate
> > POSSIBLE and one to indicate IGNORE (neither being set obviously meansnot
> > yet initialized).
> >
> > I don't really know what symbol names would be best... perhaps for now use
> > DT_CLSFLAG_USDT_INCLUDE and DT_CLSFLAG_USDT_EXCLUDE?
> >
> > Main thing I would like to accomplish here is simply to access flags on the
> > statements through functions rather than accessing them directly.
>
> I'd like to push back here.
>
> First of all, the patch exposes only dtsd_usdt at the dtrace.h level. That
> variable can hide whatever it is that USDT wants to do with it. Your
> proposal would expose at least USDT_INCLUDE/EXCLUDE (or POSSIBLE/IGNORE or
> whatever we want to call them) in dtrace.h, and I do not know if future USDT
> would have even more stuff it wants to play with, meaning even more changes
> outside of the provider.
My objection is primarily with adding a member to the statement struct for a
particular provider. Especially when there is no need for that. There is a
flags member already that can be used for these purposes.
We never know whether there might be future needs that might require changes
but that is not really a reason to make changes now that are not needed.
> Second, you say the main point is to access flags through functions rather
> than directly, but to date we've been accessing flags directly. The
> set/test functions would be new. If we want to stop the direct accesses,
> that would seem to be a different patch.
My point here is that doing this from *providers* is a bit different than
accessing things from the libdtrace core. Providers have been written to be
more separated from the core of libdtrace, or at least I have been trying to
do so. This particular use case seems to be a perfect situation where using
accessor functions makes a lot of sense. Especially because you are changing
data in structures that are at the core of libdtrace - not just usiing it.
Alternatively, I'd propose simply not doing this caching of state concerning
which clauses to ignore, and having clause_ignore() determine it for a given
statement without using cached information (since these flags really amount to
caching of information for optinization purposes). Perhaps that is the better
option right now?
Kris
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [DTrace-devel] [PATCH v2 15/19] Ignore clauses: some clauses are impossible regardless of uprp
2024-10-24 21:12 ` [DTrace-devel] " Kris Van Hees
@ 2024-10-24 21:53 ` Eugene Loh
0 siblings, 0 replies; 14+ messages in thread
From: Eugene Loh @ 2024-10-24 21:53 UTC (permalink / raw)
To: Kris Van Hees; +Cc: dtrace, dtrace-devel
On 10/24/24 17:12, Kris Van Hees wrote:
> Alternatively, I'd propose simply not doing this caching of state concerning
> which clauses to ignore, and having clause_ignore() determine it for a given
> statement without using cached information (since these flags really amount to
> caching of information for optinization purposes). Perhaps that is the better
> option right now?
I guess that's okay, but at this point I'm inclined to do the
caching/optimization thing. I'll do it as you suggest.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-10-25 12:48 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-24 20:25 [PATCH v7 03/19] Deprecate enabled probe ID (epid) eugene.loh
2024-09-24 20:25 ` [PATCH v2 05/19] Split dt_pid_create_probes() into pid and USDT functions eugene.loh
2024-09-24 20:25 ` [PATCH v3 07/19] Create the BPF usdt_prids map eugene.loh
2024-09-24 20:25 ` [PATCH v3 09/19] Use usdt_prids map to call clauses conditionally for USDT probes eugene.loh
2024-09-24 20:25 ` [PATCH v3 11/19] Support USDT wildcard provider descriptions eugene.loh
2024-10-24 16:38 ` Kris Van Hees
2024-10-25 5:56 ` Eugene Loh
2024-10-25 12:48 ` Kris Van Hees
2024-09-24 20:25 ` [PATCH v2 14/19] Ignore clauses in USDT trampoline if we know they are impossible eugene.loh
2024-09-24 20:25 ` [PATCH v2 15/19] Ignore clauses: some clauses are impossible regardless of uprp eugene.loh
2024-10-23 20:28 ` Kris Van Hees
2024-10-24 19:30 ` Eugene Loh
2024-10-24 21:12 ` [DTrace-devel] " Kris Van Hees
2024-10-24 21:53 ` Eugene Loh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox