[DTrace-devel] [PATCH] Fix -Z
eugene.loh at oracle.com
eugene.loh at oracle.com
Tue Jun 2 22:18:09 PDT 2020
From: Eugene Loh <eugene.loh at oracle.com>
By default, each probe description should match at least one probe.
The dtrace command supports a -Z option, however, that permits probe
descriptions that match zero probes.
But libdtrace had a funny way of handling this case. Function
dt_setcontext() would call dt_probe_info(), and if no probe were
found, the function would check for the -Z setting. If it were
missing, an error would be flagged. Otherwise, compilation would
proceed, even generating code for the clause that might have no
probes.
While this works for legacy DTrace, DTrace v2 needs to know what
provider-specific trampoline code to generate. There is no known
trampoline, and so the command fails. E.g.,
# dtrace -Zn foo
dtrace: invalid probe specifier foo: [Future feature]
- probe description :::foo has no representative probe
Fix the code by returning in the case of no probe with -Z,
eliminating probe descriptions that match zero probes.
This patch does not address the special case where no probe
description matches any probes:
case legacy DTrace DTrace v2
(and this patch)
dtrace (no args) print usage message print usage message
dtrace -Z hang hang
dtrace -Zn FOO "matched 0 probes" "failed to create BPF map"
hang abort
Before "fixing" this special case, the desired behavior should be defined.
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
libdtrace/dt_cc.c | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index 5319c173..99ad2f44 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -1608,6 +1608,8 @@ dt_compile_one_clause(dtrace_hdl_t *dtp, dt_node_t *cnp, dt_node_t *pnp)
yylineno = pnp->dn_line;
dt_setcontext(dtp, pnp->dn_desc);
+ if (dtrace_errno(dtp) == EDT_NOPROBE)
+ return;
(void) dt_node_cook(cnp, DT_IDFLG_REF);
if (DT_TREEDUMP_PASS(dtp, 2)) {
@@ -1636,14 +1638,24 @@ dt_compile_one_clause(dtrace_hdl_t *dtp, dt_node_t *cnp, dt_node_t *pnp)
static void
dt_compile_clause(dtrace_hdl_t *dtp, dt_node_t *cnp)
{
+ dt_node_t **pnpp;
dt_node_t *pnp;
/* Force the clause to return type 'int'. */
dt_node_type_assign(cnp, dtp->dt_ints[0].did_ctfp,
dtp->dt_ints[0].did_type);
- for (pnp = cnp->dn_pdescs; pnp != NULL; pnp = pnp->dn_list)
+ /* Loop over probe descriptors. Eliminate any that are NOPROBE. */
+ pnpp = &cnp->dn_pdescs;
+ for (pnp = cnp->dn_pdescs; pnp != NULL; pnp = pnp->dn_list) {
dt_compile_one_clause(dtp, cnp, pnp);
+ if (dtrace_errno(dtp) == EDT_NOPROBE) {
+ *pnpp = pnp->dn_list;
+ dt_node_free(pnp);
+ } else {
+ pnpp = &pnp->dn_list;
+ }
+ }
}
static void
@@ -1695,8 +1707,15 @@ dt_setcontext(dtrace_hdl_t *dtp, dtrace_probedesc_t *pdp)
* attributes. Otherwise set 'pap' to default Unstable attributes.
*/
if ((prp = dt_probe_info(dtp, pdp, &yypcb->pcb_pinfo)) == NULL) {
- pap = &_dtrace_prvdesc;
err = dtrace_errno(dtp);
+ if (err == EDT_NOPROBE) {
+ if (yypcb->pcb_cflags & DTRACE_C_ZDEFS)
+ return;
+ xyerror(D_PDESC_ZERO, "probe description %s:%s:%s:%s "
+ "does not match any probes\n",
+ pdp->prv, pdp->mod, pdp->fun, pdp->prb);
+ }
+ pap = &_dtrace_prvdesc;
memset(&yypcb->pcb_pinfo, 0, sizeof (dtrace_probeinfo_t));
yypcb->pcb_pinfo.dtp_attr = pap->dtpa_provider;
yypcb->pcb_pinfo.dtp_arga = pap->dtpa_args;
@@ -1705,12 +1724,6 @@ dt_setcontext(dtrace_hdl_t *dtp, dtrace_probedesc_t *pdp)
err = 0;
}
- if (err == EDT_NOPROBE && !(yypcb->pcb_cflags & DTRACE_C_ZDEFS)) {
- xyerror(D_PDESC_ZERO, "probe description %s:%s:%s:%s does not "
- "match any probes\n", pdp->prv, pdp->mod, pdp->fun,
- pdp->prb);
- }
-
if (err != EDT_NOPROBE && err != EDT_UNSTABLE && err != 0)
xyerror(D_PDESC_INVAL, "%s\n", dtrace_errmsg(dtp, err));
--
2.18.2
More information about the DTrace-devel
mailing list