[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