[DTrace-devel] [PATCH] WIP Implement the printf action (and related actions)

Kris Van Hees kris.van.hees at oracle.com
Mon May 18 10:46:19 PDT 2020


This one isn't quite ready yet for review - feel free to look at it but please
know that it is still a work-in-progress.

On Mon, May 18, 2020 at 10:44:10AM -0700, Kris Van Hees wrote:
> A bug existed in the error reporting for multiple '*' specifiers in
> the field width.  It mistakenly reported it as "more than one '*'
> specified for the output precision" whereas it should refer to the
> "output width".
> 
> A series of unittests are included in test/unittest/actions/printf to
> ensure the correct operation of the printf-style actions.
> 
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
>  include/dtrace/metadesc.h                     |  2 +-
>  libdtrace/dt_cg.c                             | 73 +++++++++++++++++--
>  libdtrace/dt_consume.c                        | 15 ++++
>  libdtrace/dt_impl.h                           |  3 +-
>  libdtrace/dt_map.c                            |  4 +-
>  libdtrace/dt_printf.c                         |  9 ++-
>  .../actions/printf/err.D_PRINTF_AGG_CONV.d    | 21 ++++++
>  .../actions/printf/err.D_PRINTF_AGG_CONV.r    |  2 +
>  .../err.D_PRINTF_ARG_EXTRA.addr_width.d       | 22 ++++++
>  .../err.D_PRINTF_ARG_EXTRA.addr_width.r       |  2 +
>  .../err.D_PRINTF_ARG_EXTRA.too_many_vals.d    | 20 +++++
>  .../err.D_PRINTF_ARG_EXTRA.too_many_vals.r    |  2 +
>  .../actions/printf/err.D_PRINTF_ARG_FMT.d     | 20 +++++
>  .../actions/printf/err.D_PRINTF_ARG_FMT.r     |  4 +
>  .../err.D_PRINTF_ARG_PROTO.missing_val.d      | 20 +++++
>  .../err.D_PRINTF_ARG_PROTO.missing_val.r      |  2 +
>  .../printf/err.D_PRINTF_ARG_PROTO.prec.d      | 20 +++++
>  .../printf/err.D_PRINTF_ARG_PROTO.prec.r      |  2 +
>  .../err.D_PRINTF_ARG_PROTO.too_few_vals.d     | 20 +++++
>  .../err.D_PRINTF_ARG_PROTO.too_few_vals.r     |  2 +
>  .../err.D_PRINTF_ARG_PROTO.width-prec.d       | 20 +++++
>  .../err.D_PRINTF_ARG_PROTO.width-prec.r       |  2 +
>  .../printf/err.D_PRINTF_ARG_PROTO.width.d     | 20 +++++
>  .../printf/err.D_PRINTF_ARG_PROTO.width.r     |  2 +
>  .../printf/err.D_PRINTF_ARG_TYPE.agg.d        | 22 ++++++
>  .../printf/err.D_PRINTF_ARG_TYPE.agg.r        |  5 ++
>  .../printf/err.D_PRINTF_ARG_TYPE.mismatch.d   | 20 +++++
>  .../printf/err.D_PRINTF_ARG_TYPE.mismatch.r   |  5 ++
>  .../printf/err.D_PRINTF_ARG_TYPE.void.d       | 20 +++++
>  .../printf/err.D_PRINTF_ARG_TYPE.void.r       |  5 ++
>  .../printf/err.D_PRINTF_ARG_TYPE.width-prec.d | 20 +++++
>  .../printf/err.D_PRINTF_ARG_TYPE.width-prec.r |  5 ++
>  .../err.D_PRINTF_DYN_PROTO.missing_prec-2.d   | 21 ++++++
>  .../err.D_PRINTF_DYN_PROTO.missing_prec-2.r   |  2 +
>  .../err.D_PRINTF_DYN_PROTO.missing_prec.d     | 21 ++++++
>  .../err.D_PRINTF_DYN_PROTO.missing_prec.r     |  2 +
>  .../err.D_PRINTF_DYN_PROTO.missing_width-2.d  | 21 ++++++
>  .../err.D_PRINTF_DYN_PROTO.missing_width-2.r  |  2 +
>  .../err.D_PRINTF_DYN_PROTO.missing_width.d    | 21 ++++++
>  .../err.D_PRINTF_DYN_PROTO.missing_width.r    |  2 +
>  .../printf/err.D_PRINTF_DYN_TYPE.prec.d       | 21 ++++++
>  .../printf/err.D_PRINTF_DYN_TYPE.prec.r       |  5 ++
>  .../printf/err.D_PRINTF_DYN_TYPE.width-prec.d | 21 ++++++
>  .../printf/err.D_PRINTF_DYN_TYPE.width-prec.r |  5 ++
>  .../printf/err.D_PRINTF_DYN_TYPE.width.d      | 21 ++++++
>  .../printf/err.D_PRINTF_DYN_TYPE.width.r      |  5 ++
>  .../actions/printf/err.D_PRINTF_FMT_EMPTY.d   | 20 +++++
>  .../actions/printf/err.D_PRINTF_FMT_EMPTY.r   |  2 +
>  .../unittest/actions/printf/err.D_PROTO_ARG.d | 20 +++++
>  .../unittest/actions/printf/err.D_PROTO_ARG.r |  4 +
>  .../unittest/actions/printf/err.D_PROTO_LEN.d | 20 +++++
>  .../unittest/actions/printf/err.D_PROTO_LEN.r |  2 +
>  .../actions/printf/err.D_SYNTAX.double_prec.d | 20 +++++
>  .../actions/printf/err.D_SYNTAX.double_prec.r |  2 +
>  .../printf/err.D_SYNTAX.double_width.d        | 20 +++++
>  .../printf/err.D_SYNTAX.double_width.r        |  2 +
>  .../printf/err.D_SYNTAX.explicit_arg-2.d      | 21 ++++++
>  .../printf/err.D_SYNTAX.explicit_arg-2.r      |  2 +
>  .../printf/err.D_SYNTAX.explicit_arg-3.d      | 21 ++++++
>  .../printf/err.D_SYNTAX.explicit_arg-3.r      |  2 +
>  .../printf/err.D_SYNTAX.explicit_arg.d        | 21 ++++++
>  .../printf/err.D_SYNTAX.explicit_arg.r        |  2 +
>  .../printf/err.D_SYNTAX.missing_fmt-2.d       | 21 ++++++
>  .../printf/err.D_SYNTAX.missing_fmt-2.r       |  2 +
>  .../printf/err.D_SYNTAX.missing_fmt-3.d       | 21 ++++++
>  .../printf/err.D_SYNTAX.missing_fmt-3.r       |  2 +
>  .../actions/printf/err.D_SYNTAX.missing_fmt.d | 21 ++++++
>  .../actions/printf/err.D_SYNTAX.missing_fmt.r |  2 +
>  .../actions/printf/err.D_SYNTAX.pct_flags.d   | 21 ++++++
>  .../actions/printf/err.D_SYNTAX.pct_flags.r   |  2 +
>  .../actions/printf/err.D_SYNTAX.prec-width.d  | 20 +++++
>  .../actions/printf/err.D_SYNTAX.prec-width.r  |  2 +
>  .../printf/err.D_SYNTAX.unknown_conv.d        | 21 ++++++
>  .../printf/err.D_SYNTAX.unknown_conv.r        |  2 +
>  .../printf/err.D_PRINTF_AGG_CONV.aggfmt.d     |  1 -
>  .../printf/err.D_PRINTF_ARG_EXTRA.toomany.d   |  1 -
>  .../printf/err.D_PRINTF_ARG_EXTRA.widths.d    |  1 -
>  .../printf/err.D_PRINTF_ARG_PROTO.novalue.d   |  1 -
>  .../printf/err.D_PRINTF_ARG_TYPE.recursive.d  |  1 -
>  .../printf/err.D_PRINTF_DYN_PROTO.noprec.d    |  1 -
>  .../printf/err.D_PRINTF_DYN_PROTO.nowidth.d   |  1 -
>  .../printf/err.D_PRINTF_DYN_TYPE.badprec.d    |  1 -
>  .../printf/err.D_PRINTF_DYN_TYPE.badwidth.d   |  1 -
>  test/unittest/printf/err.D_SYNTAX.badconv1.d  |  1 -
>  test/unittest/printf/err.D_SYNTAX.badconv2.d  |  1 -
>  test/unittest/printf/err.D_SYNTAX.badconv3.d  |  1 -
>  86 files changed, 886 insertions(+), 25 deletions(-)
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_AGG_CONV.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_AGG_CONV.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.addr_width.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.addr_width.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.too_many_vals.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.too_many_vals.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_FMT.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_FMT.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.missing_val.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.missing_val.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.prec.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.prec.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.too_few_vals.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.too_few_vals.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width-prec.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width-prec.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.agg.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.agg.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.mismatch.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.mismatch.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.void.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.void.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.width-prec.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.width-prec.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec-2.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec-2.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width-2.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width-2.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.prec.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.prec.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width-prec.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width-prec.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width.r
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_FMT_EMPTY.d
>  create mode 100644 test/unittest/actions/printf/err.D_PRINTF_FMT_EMPTY.r
>  create mode 100644 test/unittest/actions/printf/err.D_PROTO_ARG.d
>  create mode 100644 test/unittest/actions/printf/err.D_PROTO_ARG.r
>  create mode 100644 test/unittest/actions/printf/err.D_PROTO_LEN.d
>  create mode 100644 test/unittest/actions/printf/err.D_PROTO_LEN.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.double_prec.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.double_prec.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.double_width.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.double_width.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-2.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-2.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-3.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-3.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.explicit_arg.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.explicit_arg.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-2.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-2.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-3.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-3.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.missing_fmt.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.missing_fmt.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.pct_flags.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.pct_flags.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.prec-width.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.prec-width.r
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.unknown_conv.d
>  create mode 100644 test/unittest/actions/printf/err.D_SYNTAX.unknown_conv.r
> 
> diff --git a/include/dtrace/metadesc.h b/include/dtrace/metadesc.h
> index a4961b08..7f530ba2 100644
> --- a/include/dtrace/metadesc.h
> +++ b/include/dtrace/metadesc.h
> @@ -37,7 +37,7 @@ typedef struct dtrace_recdesc {
>  	uint32_t dtrd_size;			/* size of record */
>  	uint32_t dtrd_offset;			/* offset in ECB's data */
>  	uint16_t dtrd_alignment;		/* required alignment */
> -	uint16_t dtrd_format;			/* format, if any */
> +	void *dtrd_format;			/* format, if any */
>  	uint64_t dtrd_arg;			/* action argument */
>  	uint64_t dtrd_uarg;			/* user argument */
>  } dtrace_recdesc_t;
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index e5d3ac73..f5d96652 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -15,6 +15,7 @@
>  #include <dt_impl.h>
>  #include <dt_grammar.h>
>  #include <dt_parser.h>
> +#include <dt_printf.h>
>  #include <dt_provider.h>
>  #include <dt_probe.h>
>  #include <dt_bpf_builtins.h>
> @@ -243,7 +244,8 @@ dt_cg_spill_load(int reg)
>  }
>  
>  static int
> -dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind, int act)
> +dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
> +		dt_pfargv_t *pfp, int act)
>  {
>  	dtrace_diftype_t	vtype;
>  	struct bpf_insn		instr;
> @@ -257,7 +259,7 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind, int act)
>  		int	sz = 8;
>  
>  		off = dt_rec_add(pcb->pcb_hdl, dt_cg_fill_gap, kind,
> -				 vtype.dtdt_size, vtype.dtdt_size, NULL,
> +				 vtype.dtdt_size, vtype.dtdt_size, pfp,
>  				 act);
>  
>  		switch (vtype.dtdt_size) {
> @@ -498,6 +500,67 @@ dt_cg_act_printa(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>  static void
>  dt_cg_act_printf(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>  {
> +	dt_node_t	*arg1, *anp;
> +	dt_pfargv_t	*pfp;
> +	char		n[DT_TYPE_NAMELEN];
> +	char		*str;
> +
> +	/*
> +	 * Ensure that the format string is a string constant.
> +	 */
> +	if (dnp->dn_args->dn_kind != DT_NODE_STRING) {
> +		dnerror(dnp, D_PRINTF_ARG_FMT,
> +			"%s( ) argument #1 is incompatible with prototype:\n"
> +			"\tprototype: string constant\n\t argument: %s\n",
> +			dnp->dn_ident->di_name,
> +			dt_node_type_name(dnp->dn_args, n, sizeof(n)));
> +	}
> +
> +	arg1 = dnp->dn_args->dn_list;
> +	yylineno = dnp->dn_line;
> +	str = dnp->dn_args->dn_string;
> +
> +	/*
> +	 * If this is an freopen(), we use an empty string to denote that
> +	 * stdout should be restored.  For other printf()-like actions, an
> +	 * empty format string is illegal:  an empty format string would
> +	 * result in malformed DOF, and the compiler thus flags an empty
> +	 * format string as a compile-time error.  To avoid propagating the
> +	 * freopen() special case throughout the system, we simply transpose
> +	 * an empty string into a sentinel string (DT_FREOPEN_RESTORE) that
> +	 * denotes that stdout should be restored.
> +	 */
> +	if (kind == DTRACEACT_FREOPEN) {
> +		if (strcmp(str, DT_FREOPEN_RESTORE) == 0) {
> +			/*
> +			 * Our sentinel is always an invalid argument to
> +			 * freopen(), but if it's been manually specified, we
> +			 * must fail now instead of when the freopen() is
> +			 * actually evaluated.
> +			 */
> +			dnerror(dnp, D_FREOPEN_INVALID,
> +				"%s( ) argument #1 cannot be \"%s\"\n",
> +				dnp->dn_ident->di_name, DT_FREOPEN_RESTORE);
> +		}
> +
> +		if (str[0] == '\0')
> +			str = DT_FREOPEN_RESTORE;
> +	}
> +
> +	/*
> +	 * Validate the format string and the datatypes of the arguments.
> +	 */
> +	pfp = dt_printf_create(pcb->pcb_hdl, str);
> +	dt_printf_validate(pfp, DT_PRINTF_EXACTLEN, dnp->dn_ident, 1,
> +			   DTRACEACT_AGGREGATION, arg1);
> +
> +	/*
> +	 * Generate code to store the arguments.  If no arguments are provided,
> +	 * we are printing a string constant, and no data needs to be written
> +	 * to the output buffer.
> +	 */
> +	for (anp = arg1; anp != NULL; anp = anp->dn_list)
> +		dt_cg_store_val(pcb, anp, kind, pfp, 0);
>  }
>  
>  static void
> @@ -593,7 +656,7 @@ dt_cg_act_trace(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>  	else if (arg->dn_flags & DT_NF_SIGNED)
>  		type = DT_NF_SIGNED;
>  
> -	if (dt_cg_store_val(pcb, arg, DTRACEACT_DIFEXPR, type) == -1)
> +	if (dt_cg_store_val(pcb, arg, DTRACEACT_DIFEXPR, NULL, type) == -1)
>  		dnerror(arg, D_PROTO_ARG,
>  			"trace( ) argument #1 is incompatible with prototype:\n"
>  			"\tprototype: scalar or string\n\t argument: %s\n",
> @@ -668,11 +731,11 @@ static const dt_cg_actdesc_t _dt_cg_actions[DT_ACT_MAX] = {
>  	[DT_ACT_IDX(DT_ACT_NORMALIZE)]		= { &dt_cg_act_normalize, },
>  	[DT_ACT_IDX(DT_ACT_DENORMALIZE)]	= { &dt_cg_act_denormalize, },
>  	[DT_ACT_IDX(DT_ACT_TRUNC)]		= { &dt_cg_act_trunc, },
> -	[DT_ACT_IDX(DT_ACT_SYSTEM)]		= { &dt_cg_act_system,
> +	[DT_ACT_IDX(DT_ACT_SYSTEM)]		= { &dt_cg_act_printf,
>  						    DTRACEACT_SYSTEM },
>  	[DT_ACT_IDX(DT_ACT_JSTACK)]		= { &dt_cg_act_jstack, },
>  	[DT_ACT_IDX(DT_ACT_FTRUNCATE)]		= { &dt_cg_act_ftruncate, },
> -	[DT_ACT_IDX(DT_ACT_FREOPEN)]		= { &dt_cg_act_freopen,
> +	[DT_ACT_IDX(DT_ACT_FREOPEN)]		= { &dt_cg_act_printf,
>  						    DTRACEACT_FREOPEN },
>  	[DT_ACT_IDX(DT_ACT_SYM)]		= { &dt_cg_act_symmod,
>  						    DTRACEACT_SYM },
> diff --git a/libdtrace/dt_consume.c b/libdtrace/dt_consume.c
> index 6c15b4a5..5a5eb3bb 100644
> --- a/libdtrace/dt_consume.c
> +++ b/libdtrace/dt_consume.c
> @@ -2414,6 +2414,21 @@ dt_consume_one(dtrace_hdl_t *dtp, FILE *fp, int cpu, char *buf,
>  			if (rval != DTRACE_CONSUME_THIS)
>  				return dt_set_errno(dtp, EDT_BADRVAL);
>  
> +			if (rec->dtrd_action == DTRACEACT_PRINTF) {
> +				int	nrecs;
> +
> +				nrecs = pdat->dtpda_ddesc->dtdd_nrecs - i;
> +				n = dtrace_fprintf(dtp, fp, rec->dtrd_format,
> +						   pdat, rec, nrecs, data,
> +						   size);
> +				if (n < 0)
> +					return -1;
> +				if (n > 0)
> +					i += n - 1;
> +
> +				continue;
> +			}
> +
>  			n = dt_print_trace(dtp, fp, rec, pdat->dtpda_data,
>  					   quiet);
>  
> diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
> index 8f360047..fde084c4 100644
> --- a/libdtrace/dt_impl.h
> +++ b/libdtrace/dt_impl.h
> @@ -48,6 +48,7 @@ extern "C" {
>  #include <dt_dof.h>
>  #include <dt_pcb.h>
>  #include <dt_pt_regs.h>
> +#include <dt_printf.h>
>  #include <dt_bpf_ctx.h>
>  #include <dt_debug.h>
>  #include <dt_version.h>
> @@ -792,7 +793,7 @@ extern int dt_epid_lookup(dtrace_hdl_t *, dtrace_epid_t, dtrace_datadesc_t **,
>  extern void dt_epid_destroy(dtrace_hdl_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, const char *, uint64_t);
> +			   uint32_t, uint16_t, dt_pfargv_t *, uint64_t);
>  extern int dt_aggid_lookup(dtrace_hdl_t *, dtrace_aggid_t, dtrace_aggdesc_t **);
>  extern void dt_aggid_destroy(dtrace_hdl_t *);
>  
> diff --git a/libdtrace/dt_map.c b/libdtrace/dt_map.c
> index 00668c70..ce11f7c9 100644
> --- a/libdtrace/dt_map.c
> +++ b/libdtrace/dt_map.c
> @@ -349,7 +349,7 @@ dt_epid_destroy(dtrace_hdl_t *dtp)
>  
>  uint32_t
>  dt_rec_add(dtrace_hdl_t *dtp, dt_cg_gap_f gapf, dtrace_actkind_t kind,
> -	   uint32_t size, uint16_t alignment, const char *fmt, uint64_t arg)
> +	   uint32_t size, uint16_t alignment, dt_pfargv_t *pfp, uint64_t arg)
>  {
>  	dt_pcb_t		*pcb = dtp->dt_pcb;
>  	uint32_t		off;
> @@ -387,7 +387,7 @@ dt_rec_add(dtrace_hdl_t *dtp, dt_cg_gap_f gapf, dtrace_actkind_t kind,
>  	rec->dtrd_size = size;
>  	rec->dtrd_offset = off;
>  	rec->dtrd_alignment = alignment;
> -	rec->dtrd_format = 0;	/* FIXME */
> +	rec->dtrd_format = pfp;
>  	rec->dtrd_arg = arg;
>  
>  	gap = off - pcb->pcb_bufoff;
> diff --git a/libdtrace/dt_printf.c b/libdtrace/dt_printf.c
> index e567c6f9..03ffa8bd 100644
> --- a/libdtrace/dt_printf.c
> +++ b/libdtrace/dt_printf.c
> @@ -812,11 +812,12 @@ dt_printf_create(dtrace_hdl_t *dtp, const char *s)
>  
>  			if (pfd->pfd_flags & n) {
>  				yywarn("format conversion #%u has more than "
> -				    "one '*' specified for the output %s\n",
> -				    pfv->pfv_argc, n ? "precision" : "width");
> +				       "one '*' specified for the output %s\n",
> +				       pfv->pfv_argc,
> +				       dot ? "precision" : "width");
>  
>  				dt_printf_destroy(pfv);
> -				return (dt_printf_error(dtp, EDT_COMPILER));
> +				return dt_printf_error(dtp, EDT_COMPILER);
>  			}
>  
>  			pfd->pfd_flags |= n;
> @@ -1162,7 +1163,7 @@ dt_printf_getint(dtrace_hdl_t *dtp, const dtrace_recdesc_t *recp,
>  
>  	addr = (uintptr_t)buf + recp->dtrd_offset;
>  
> -	if (addr + sizeof (int) > (uintptr_t)buf + len)
> +	if (addr + recp->dtrd_size > (uintptr_t)buf + len)
>  		return (dt_set_errno(dtp, EDT_DOFFSET));
>  
>  	if (addr & (recp->dtrd_alignment - 1))
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_AGG_CONV.d b/test/unittest/actions/printf/err.D_PRINTF_AGG_CONV.d
> new file mode 100644
> index 00000000..df24f0c9
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_AGG_CONV.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires an aggregation value for conversions
> + *	      with the '@' specifier.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%@d", 1);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_AGG_CONV.r b/test/unittest/actions/printf/err.D_PRINTF_AGG_CONV.r
> new file mode 100644
> index 00000000..28a613b4
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_AGG_CONV.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_AGG_CONV.d: [D_PRINTF_AGG_CONV] line 19: %@ conversion requires an aggregation and is not for use with printf( )
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.addr_width.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.addr_width.d
> new file mode 100644
> index 00000000..d336c95d
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.addr_width.d
> @@ -0,0 +1,22 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action provides a fixed field width for formatting
> + *	      addresses in hexadecimal format, so providing a field width with
> + *	      the '?' size specifier is not allowed.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%?d\n", 1, 2);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.addr_width.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.addr_width.r
> new file mode 100644
> index 00000000..f8647642
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.addr_width.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.addr_width.d: [D_PRINTF_ARG_EXTRA] line 20: printf( ) prototype mismatch: only 1 arguments required by this format string
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.too_many_vals.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.too_many_vals.d
> new file mode 100644
> index 00000000..a973025e
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.too_many_vals.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires values for all conversions.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%d", 1, 2, 3);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.too_many_vals.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.too_many_vals.r
> new file mode 100644
> index 00000000..8d388e34
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.too_many_vals.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_EXTRA.too_many_vals.d: [D_PRINTF_ARG_EXTRA] line 18: printf( ) prototype mismatch: only 1 arguments required by this format string
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_FMT.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_FMT.d
> new file mode 100644
> index 00000000..837778e4
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_FMT.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a string constant as first argument.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf(probename);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_FMT.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_FMT.r
> new file mode 100644
> index 00000000..172e49dc
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_FMT.r
> @@ -0,0 +1,4 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_FMT.d: [D_PRINTF_ARG_FMT] line 18: printf( ) argument #1 is incompatible with prototype:
> +	prototype: string constant
> +	 argument: string
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.missing_val.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.missing_val.d
> new file mode 100644
> index 00000000..2ac28478
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.missing_val.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a value for a conversion.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%d");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.missing_val.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.missing_val.r
> new file mode 100644
> index 00000000..d1cca78f
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.missing_val.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.missing_val.d: [D_PRINTF_ARG_PROTO] line 18: printf( ) prototype mismatch: conversion #1 (%d) is missing a corresponding value argument
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.prec.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.prec.d
> new file mode 100644
> index 00000000..bc6c8f23
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.prec.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a value for a conversion.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%.*d", 1);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.prec.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.prec.r
> new file mode 100644
> index 00000000..5765ab90
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.prec.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.prec.d: [D_PRINTF_ARG_PROTO] line 18: printf( ) prototype mismatch: conversion #1 (%d) is missing a corresponding value argument
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.too_few_vals.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.too_few_vals.d
> new file mode 100644
> index 00000000..87879a11
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.too_few_vals.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires values for all conversions.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%d %d %d %d %d", 1, 2, 3);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.too_few_vals.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.too_few_vals.r
> new file mode 100644
> index 00000000..d606a166
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.too_few_vals.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.too_few_vals.d: [D_PRINTF_ARG_PROTO] line 18: printf( ) prototype mismatch: conversion #4 (%d) is missing a corresponding value argument
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width-prec.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width-prec.d
> new file mode 100644
> index 00000000..94161432
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width-prec.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a value for a conversion.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%*.*d", 1, 2);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width-prec.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width-prec.r
> new file mode 100644
> index 00000000..b77107b5
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width-prec.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width-prec.d: [D_PRINTF_ARG_PROTO] line 18: printf( ) prototype mismatch: conversion #1 (%d) is missing a corresponding value argument
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width.d
> new file mode 100644
> index 00000000..02cda3d5
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a value for a conversion.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%*d", 1);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width.r
> new file mode 100644
> index 00000000..62553f63
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_PROTO.width.d: [D_PRINTF_ARG_PROTO] line 18: printf( ) prototype mismatch: conversion #1 (%d) is missing a corresponding value argument
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.agg.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.agg.d
> new file mode 100644
> index 00000000..da1481aa
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.agg.d
> @@ -0,0 +1,22 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +/* @@xfail: dtv2 */
> +
> +/*
> + * ASSERTION: The printf() action requires a value that matches the conversion.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	@a = count();
> +	printf("%d", @a);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.agg.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.agg.r
> new file mode 100644
> index 00000000..183f40ff
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.agg.r
> @@ -0,0 +1,5 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.agg.d: [D_PRINTF_ARG_TYPE] line 18: printf( ) argument #2 is incompatible with conversion #1 prototype:
> +	conversion: %d
> +	 prototype: char, short, int, long, or long long
> +	  argument: aggregation
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.mismatch.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.mismatch.d
> new file mode 100644
> index 00000000..fa53d6f9
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.mismatch.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a value that matches the conversion.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%d", "");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.mismatch.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.mismatch.r
> new file mode 100644
> index 00000000..4e7368db
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.mismatch.r
> @@ -0,0 +1,5 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.mismatch.d: [D_PRINTF_ARG_TYPE] line 18: printf( ) argument #2 is incompatible with conversion #1 prototype:
> +	conversion: %d
> +	 prototype: char, short, int, long, or long long
> +	  argument: string
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.void.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.void.d
> new file mode 100644
> index 00000000..c12e8014
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.void.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action does not accept void as a value.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%d", printf(""));
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.void.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.void.r
> new file mode 100644
> index 00000000..1c55bdae
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.void.r
> @@ -0,0 +1,5 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.void.d: [D_PRINTF_ARG_TYPE] line 18: printf( ) argument #2 is incompatible with conversion #1 prototype:
> +	conversion: %d
> +	 prototype: char, short, int, long, or long long
> +	  argument: void
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.width-prec.d b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.width-prec.d
> new file mode 100644
> index 00000000..5f3f628b
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.width-prec.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a value that matches the conversion.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%*.*d", 1, 2, "");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.width-prec.r b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.width-prec.r
> new file mode 100644
> index 00000000..750cc998
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.width-prec.r
> @@ -0,0 +1,5 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_ARG_TYPE.width-prec.d: [D_PRINTF_ARG_TYPE] line 18: printf( ) argument #4 is incompatible with conversion #1 prototype:
> +	conversion: %d
> +	 prototype: char, short, int, long, or long long
> +	  argument: string
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec-2.d b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec-2.d
> new file mode 100644
> index 00000000..3cd1be33
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec-2.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action verifies that a precision is provided if the
> + *	      conversion includes a precision specifier.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%*.*d", 1);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec-2.r b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec-2.r
> new file mode 100644
> index 00000000..830bf022
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec-2.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec-2.d: [D_PRINTF_DYN_PROTO] line 19: printf( ) prototype mismatch: conversion #1 (%d) is missing a corresponding ".*" argument
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec.d b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec.d
> new file mode 100644
> index 00000000..fef5b4c8
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action verifies that a precision is provided if the
> + *	      conversion includes a precision specifier.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%.*d");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec.r b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec.r
> new file mode 100644
> index 00000000..a793df36
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_prec.d: [D_PRINTF_DYN_PROTO] line 19: printf( ) prototype mismatch: conversion #1 (%d) is missing a corresponding ".*" argument
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width-2.d b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width-2.d
> new file mode 100644
> index 00000000..2082d7f8
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width-2.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action verifies that a width is provided if the
> + *	      conversion includes a width specifier.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%*.*d");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width-2.r b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width-2.r
> new file mode 100644
> index 00000000..e3297f38
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width-2.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width-2.d: [D_PRINTF_DYN_PROTO] line 19: printf( ) prototype mismatch: conversion #1 (%d) is missing a corresponding "*" argument
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width.d b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width.d
> new file mode 100644
> index 00000000..d81b11b3
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action verifies that a width is provided if the
> + *	      conversion includes a width specifier.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%*d");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width.r b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width.r
> new file mode 100644
> index 00000000..3a6223d4
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_DYN_PROTO.missing_width.d: [D_PRINTF_DYN_PROTO] line 19: printf( ) prototype mismatch: conversion #1 (%d) is missing a corresponding "*" argument
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.prec.d b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.prec.d
> new file mode 100644
> index 00000000..f8cf0240
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.prec.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires an integer value for the precision
> + *	      specifier.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%.*d", "", 1);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.prec.r b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.prec.r
> new file mode 100644
> index 00000000..eb8bf0eb
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.prec.r
> @@ -0,0 +1,5 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.prec.d: [D_PRINTF_DYN_TYPE] line 19: printf( ) argument #2 is incompatible with conversion #1 prototype:
> +	conversion: % .* d
> +	 prototype: int
> +	  argument: string
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width-prec.d b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width-prec.d
> new file mode 100644
> index 00000000..cdff86e1
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width-prec.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires an integer value for the width and
> + *	      precision specifiers.  The width specifier is checked first.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%*.*d", "", "", 1);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width-prec.r b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width-prec.r
> new file mode 100644
> index 00000000..4dd0c194
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width-prec.r
> @@ -0,0 +1,5 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width-prec.d: [D_PRINTF_DYN_TYPE] line 19: printf( ) argument #2 is incompatible with conversion #1 prototype:
> +	conversion: % * d
> +	 prototype: int
> +	  argument: string
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width.d b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width.d
> new file mode 100644
> index 00000000..0e0ff102
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires an integer value for the width
> + *	      specifier.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%*d", "", 1);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width.r b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width.r
> new file mode 100644
> index 00000000..af1f8da7
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width.r
> @@ -0,0 +1,5 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_DYN_TYPE.width.d: [D_PRINTF_DYN_TYPE] line 19: printf( ) argument #2 is incompatible with conversion #1 prototype:
> +	conversion: % * d
> +	 prototype: int
> +	  argument: string
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_FMT_EMPTY.d b/test/unittest/actions/printf/err.D_PRINTF_FMT_EMPTY.d
> new file mode 100644
> index 00000000..63898e52
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_FMT_EMPTY.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action format string cannot be empty.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PRINTF_FMT_EMPTY.r b/test/unittest/actions/printf/err.D_PRINTF_FMT_EMPTY.r
> new file mode 100644
> index 00000000..e379bd2c
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PRINTF_FMT_EMPTY.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PRINTF_FMT_EMPTY.d: [D_PRINTF_FMT_EMPTY] line 18: printf( ) format string is empty
> diff --git a/test/unittest/actions/printf/err.D_PROTO_ARG.d b/test/unittest/actions/printf/err.D_PROTO_ARG.d
> new file mode 100644
> index 00000000..f514ee3b
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PROTO_ARG.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a string as first argument.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf(1);
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PROTO_ARG.r b/test/unittest/actions/printf/err.D_PROTO_ARG.r
> new file mode 100644
> index 00000000..0fef262f
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PROTO_ARG.r
> @@ -0,0 +1,4 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PROTO_ARG.d: [D_PROTO_ARG] line 18: printf( ) argument #1 is incompatible with prototype:
> +	prototype: string
> +	 argument: int
> diff --git a/test/unittest/actions/printf/err.D_PROTO_LEN.d b/test/unittest/actions/printf/err.D_PROTO_LEN.d
> new file mode 100644
> index 00000000..a4b80046
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PROTO_LEN.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires at least one argument.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf();
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_PROTO_LEN.r b/test/unittest/actions/printf/err.D_PROTO_LEN.r
> new file mode 100644
> index 00000000..c8e8b347
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_PROTO_LEN.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_PROTO_LEN.d: [D_PROTO_LEN] line 18: printf( ) prototype mismatch: 0 args passed, at least 1 expected
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.double_prec.d b/test/unittest/actions/printf/err.D_SYNTAX.double_prec.d
> new file mode 100644
> index 00000000..81862265
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.double_prec.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action accepts only one precision per conversion.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%.*.*d");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.double_prec.r b/test/unittest/actions/printf/err.D_SYNTAX.double_prec.r
> new file mode 100644
> index 00000000..14bc1405
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.double_prec.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.double_prec.d: [D_SYNTAX] line 18: format conversion #1 has more than one '.' specified
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.double_width.d b/test/unittest/actions/printf/err.D_SYNTAX.double_width.d
> new file mode 100644
> index 00000000..7e8a9d9c
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.double_width.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action accepts only one width per conversion.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%**d");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.double_width.r b/test/unittest/actions/printf/err.D_SYNTAX.double_width.r
> new file mode 100644
> index 00000000..47aae46a
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.double_width.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.double_width.d: [D_SYNTAX] line 18: format conversion #1 has more than one '*' specified for the output width
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-2.d b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-2.d
> new file mode 100644
> index 00000000..7934f626
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-2.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: THe printf() action does not allow explicit argument specifiers.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + *
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%*1$d");
> +	exit(-1);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-2.r b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-2.r
> new file mode 100644
> index 00000000..4c72b01a
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-2.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-2.d: [D_SYNTAX] line 19: format conversion #1 uses unsupported positional format (%n$)
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-3.d b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-3.d
> new file mode 100644
> index 00000000..518d063e
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-3.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: THe printf() action does not allow explicit argument specifiers.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + *
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%.*1$d");
> +	exit(-1);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-3.r b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-3.r
> new file mode 100644
> index 00000000..3395f5b6
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-3.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.explicit_arg-3.d: [D_SYNTAX] line 19: format conversion #1 uses unsupported positional format (%n$)
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg.d b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg.d
> new file mode 100644
> index 00000000..990b067b
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: THe printf() action does not allow explicit argument specifiers.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + *
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%1$d");
> +	exit(-1);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg.r b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg.r
> new file mode 100644
> index 00000000..0292c7c4
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.explicit_arg.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.explicit_arg.d: [D_SYNTAX] line 19: format conversion #1 uses unsupported positional format (%n$)
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-2.d b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-2.d
> new file mode 100644
> index 00000000..b0a94be6
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-2.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a conversion format symbol in a
> + *	      conversion specification.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%*");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-2.r b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-2.r
> new file mode 100644
> index 00000000..5bbcde487
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-2.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-2.d: [D_SYNTAX] line 19: format conversion #1 name expected before end of format string
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-3.d b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-3.d
> new file mode 100644
> index 00000000..a8436b9e
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-3.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a conversion format symbol in a
> + *	      conversion specification.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%.*");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-3.r b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-3.r
> new file mode 100644
> index 00000000..c423bf1b
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-3.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.missing_fmt-3.d: [D_SYNTAX] line 19: format conversion #1 name expected before end of format string
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt.d b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt.d
> new file mode 100644
> index 00000000..846dbf8a
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action requires a conversion format symbol in a
> + *	      conversion specification.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt.r b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt.r
> new file mode 100644
> index 00000000..819c5f37
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.missing_fmt.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.missing_fmt.d: [D_SYNTAX] line 19: format conversion #1 name expected before end of format string
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.pct_flags.d b/test/unittest/actions/printf/err.D_SYNTAX.pct_flags.d
> new file mode 100644
> index 00000000..2f3c459d
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.pct_flags.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action "%%" conversion does not accept other format
> + *	      flags.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%-%");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.pct_flags.r b/test/unittest/actions/printf/err.D_SYNTAX.pct_flags.r
> new file mode 100644
> index 00000000..b33b0996
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.pct_flags.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.pct_flags.d: [D_SYNTAX] line 19: format conversion #1 cannot be combined with other format flags: %%
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.prec-width.d b/test/unittest/actions/printf/err.D_SYNTAX.prec-width.d
> new file mode 100644
> index 00000000..318aae1e
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.prec-width.d
> @@ -0,0 +1,20 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action does not allow precision before width.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%.**d");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.prec-width.r b/test/unittest/actions/printf/err.D_SYNTAX.prec-width.r
> new file mode 100644
> index 00000000..c6e35f98
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.prec-width.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.prec-width.d: [D_SYNTAX] line 18: format conversion #1 has more than one '*' specified for the output precision
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.unknown_conv.d b/test/unittest/actions/printf/err.D_SYNTAX.unknown_conv.d
> new file mode 100644
> index 00000000..fe705c2d
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.unknown_conv.d
> @@ -0,0 +1,21 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2020, 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.
> + */
> +
> +/*
> + * ASSERTION: The printf() action verifies that the conversion format symbol is
> + *	      valid.
> + *
> + * SECTION: Actions and Subroutines/printf()
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	printf("%z");
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/printf/err.D_SYNTAX.unknown_conv.r b/test/unittest/actions/printf/err.D_SYNTAX.unknown_conv.r
> new file mode 100644
> index 00000000..8b610590
> --- /dev/null
> +++ b/test/unittest/actions/printf/err.D_SYNTAX.unknown_conv.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/actions/printf/err.D_SYNTAX.unknown_conv.d: [D_SYNTAX] line 19: format conversion #1 is undefined: %z
> diff --git a/test/unittest/printf/err.D_PRINTF_AGG_CONV.aggfmt.d b/test/unittest/printf/err.D_PRINTF_AGG_CONV.aggfmt.d
> index c803bbf5..0df5614a 100644
> --- a/test/unittest/printf/err.D_PRINTF_AGG_CONV.aggfmt.d
> +++ b/test/unittest/printf/err.D_PRINTF_AGG_CONV.aggfmt.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_PRINTF_ARG_EXTRA.toomany.d b/test/unittest/printf/err.D_PRINTF_ARG_EXTRA.toomany.d
> index b8958d18..c26a8991 100644
> --- a/test/unittest/printf/err.D_PRINTF_ARG_EXTRA.toomany.d
> +++ b/test/unittest/printf/err.D_PRINTF_ARG_EXTRA.toomany.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_PRINTF_ARG_EXTRA.widths.d b/test/unittest/printf/err.D_PRINTF_ARG_EXTRA.widths.d
> index 6c885858..d6a1bd32 100644
> --- a/test/unittest/printf/err.D_PRINTF_ARG_EXTRA.widths.d
> +++ b/test/unittest/printf/err.D_PRINTF_ARG_EXTRA.widths.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_PRINTF_ARG_PROTO.novalue.d b/test/unittest/printf/err.D_PRINTF_ARG_PROTO.novalue.d
> index 264f30a7..394fa3fd 100644
> --- a/test/unittest/printf/err.D_PRINTF_ARG_PROTO.novalue.d
> +++ b/test/unittest/printf/err.D_PRINTF_ARG_PROTO.novalue.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_PRINTF_ARG_TYPE.recursive.d b/test/unittest/printf/err.D_PRINTF_ARG_TYPE.recursive.d
> index 6688401b..22274202 100644
> --- a/test/unittest/printf/err.D_PRINTF_ARG_TYPE.recursive.d
> +++ b/test/unittest/printf/err.D_PRINTF_ARG_TYPE.recursive.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_PRINTF_DYN_PROTO.noprec.d b/test/unittest/printf/err.D_PRINTF_DYN_PROTO.noprec.d
> index bcadbd58..9ab1f24e 100644
> --- a/test/unittest/printf/err.D_PRINTF_DYN_PROTO.noprec.d
> +++ b/test/unittest/printf/err.D_PRINTF_DYN_PROTO.noprec.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_PRINTF_DYN_PROTO.nowidth.d b/test/unittest/printf/err.D_PRINTF_DYN_PROTO.nowidth.d
> index 79070317..6b45f82e 100644
> --- a/test/unittest/printf/err.D_PRINTF_DYN_PROTO.nowidth.d
> +++ b/test/unittest/printf/err.D_PRINTF_DYN_PROTO.nowidth.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_PRINTF_DYN_TYPE.badprec.d b/test/unittest/printf/err.D_PRINTF_DYN_TYPE.badprec.d
> index 9d3a8e87..8681aa4a 100644
> --- a/test/unittest/printf/err.D_PRINTF_DYN_TYPE.badprec.d
> +++ b/test/unittest/printf/err.D_PRINTF_DYN_TYPE.badprec.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_PRINTF_DYN_TYPE.badwidth.d b/test/unittest/printf/err.D_PRINTF_DYN_TYPE.badwidth.d
> index dc70454f..a3dd62a3 100644
> --- a/test/unittest/printf/err.D_PRINTF_DYN_TYPE.badwidth.d
> +++ b/test/unittest/printf/err.D_PRINTF_DYN_TYPE.badwidth.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_SYNTAX.badconv1.d b/test/unittest/printf/err.D_SYNTAX.badconv1.d
> index 98eb22cd..8992112e 100644
> --- a/test/unittest/printf/err.D_SYNTAX.badconv1.d
> +++ b/test/unittest/printf/err.D_SYNTAX.badconv1.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_SYNTAX.badconv2.d b/test/unittest/printf/err.D_SYNTAX.badconv2.d
> index 19728b14..a2fcc0de 100644
> --- a/test/unittest/printf/err.D_SYNTAX.badconv2.d
> +++ b/test/unittest/printf/err.D_SYNTAX.badconv2.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> diff --git a/test/unittest/printf/err.D_SYNTAX.badconv3.d b/test/unittest/printf/err.D_SYNTAX.badconv3.d
> index 6728e172..61016f22 100644
> --- a/test/unittest/printf/err.D_SYNTAX.badconv3.d
> +++ b/test/unittest/printf/err.D_SYNTAX.badconv3.d
> @@ -4,7 +4,6 @@
>   * Licensed under the Universal Permissive License v 1.0 as shown at
>   * http://oss.oracle.com/licenses/upl.
>   */
> -/* @@xfail: dtv2 */
>  
>  /*
>   * ASSERTION:
> -- 
> 2.26.0
> 
> 
> _______________________________________________
> 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