[DTrace-devel] [PATCH] Fix -Z

Kris Van Hees kris.van.hees at oracle.com
Tue Jun 2 22:37:19 PDT 2020


The -Z option primarily exists to be able to start tracing based on probes
that may not exist yet.  A typical example would be tracing based on USDT
probes that are not provided yet by any running executable.  We need to be
able to start a tracing session, and as executables with USDT probes are
invoked, DTrace will attach the specified actions to the probes.

Clearly, this requires support in areas that we currently have not touched.
I am therefore inclined to keep the current behaviour (the 'no representative
probe' error message) because any alternative behaviour isn't really any
better.

We will need to revisit this -Z option once we have more of the infrastructure
that it depends on ironed out.

On Wed, Jun 03, 2020 at 01:18:09AM -0400, eugene.loh at oracle.com wrote:
> 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
> 
> 
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel



More information about the DTrace-devel mailing list