[DTrace-devel] [PATCH v4] trace: print alloca pointers as actual pointer values

Eugene Loh eugene.loh at oracle.com
Tue Sep 16 22:53:25 UTC 2025


Reviewed-by: Eugene Loh <eugene.loh at oracle.com>

On 9/16/25 14:26, Kris Van Hees wrote:
> Because alloca pointers are stored internally as offsets into the
> scratchmem area, they were printed as small integers.  They are
> now printed as actual pointer values into kernel space.
>
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
>   libdtrace/dt_cg.c                          | 46 ++++++++++++++++------
>   test/unittest/actions/trace/tst.alloca.d   | 24 +++++++++++
>   test/unittest/actions/trace/tst.alloca.r   |  1 +
>   test/unittest/actions/trace/tst.alloca.r.p | 11 ++++++
>   4 files changed, 71 insertions(+), 11 deletions(-)
>   create mode 100644 test/unittest/actions/trace/tst.alloca.d
>   create mode 100644 test/unittest/actions/trace/tst.alloca.r
>   create mode 100755 test/unittest/actions/trace/tst.alloca.r.p
>
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 7d542521..1f120e1d 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -1687,18 +1687,42 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
>   		align = vtype.dtdt_align;
>   
>   		/*
> -		 * A DEREF of a REF node does not get resolved in dt_cg_node()
> -		 * because the ref node already holds the pointer.  But for
> -		 * alloca pointers, that will be the offset into scratchmem so
> -		 * we still need to turn it into a real pointer here.
> +		 * Alloca pointers are stored as an offset into scratchmem, so
> +		 * they need to be converted into real pointers before we go on.
> +		 * An alloca pointer value either has the ALLOCA flag set, or
> +		 * the value node is a DEREF of an alloca pointer child.
> +		 * If the alloca pointer is a REF or ref-by-value is requested,
> +		 * we need to do bounds checking before turning the alloca
> +		 * pointer into a real pointer.
> +		 * If not, we should scalarize it so that the BPF verifier does
> +		 * not complain.
>   		 */
> -		if (dnp->dn_kind == DT_NODE_OP1 &&
> -		    dnp->dn_op == DT_TOK_DEREF && (dnp->dn_flags & DT_NF_REF) &&
> -		    (dnp->dn_child->dn_flags & DT_NF_ALLOCA)) {
> -			dt_cg_alloca_access_check(dlp, drp, dnp->dn_reg,
> -						  DT_ISIMM, size);
> -			dt_cg_alloca_ptr(dlp, drp, dnp->dn_reg, dnp->dn_reg);
> -			not_null = 1;
> +		if ((dnp->dn_flags & DT_NF_ALLOCA) ||
> +		    (dnp->dn_kind == DT_NODE_OP1 &&
> +		     dnp->dn_op == DT_TOK_DEREF &&
> +		     (dnp->dn_flags & DT_NF_REF) &&
> +		     (dnp->dn_child->dn_flags & DT_NF_ALLOCA))) {
> +			if ((dnp->dn_flags & DT_NF_REF) || (arg & DT_NF_REF)) {
> +				dt_cg_alloca_access_check(dlp, drp, dnp->dn_reg,
> +							  DT_ISIMM, size);
> +
> +				dt_cg_alloca_ptr(dlp, drp, dnp->dn_reg, dnp->dn_reg);
> +				not_null = 1;
> +			} else {
> +				int	reg;
> +
> +				dt_regset_xalloc(drp, BPF_REG_0);
> +				emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_FP, DT_STK_DCTX));
> +				if ((reg = dt_regset_alloc(drp)) == -1)
> +					longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> +				emit(dlp, BPF_LOAD(BPF_DW, reg, BPF_REG_0, DCTX_SCRATCHMEM));
> +				emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_0, DCTX_MST));
> +				emit(dlp, BPF_STORE(BPF_DW, BPF_REG_0, DMST_SCALARIZER, reg));
> +				emit(dlp, BPF_LOAD(BPF_DW, reg, BPF_REG_0, DMST_SCALARIZER));
> +				dt_regset_free(drp, BPF_REG_0);
> +				emit(dlp,  BPF_ALU64_REG(BPF_ADD, dnp->dn_reg, reg));
> +				dt_regset_free(drp, reg);
> +			}
>   		}
>   	}
>   
> diff --git a/test/unittest/actions/trace/tst.alloca.d b/test/unittest/actions/trace/tst.alloca.d
> new file mode 100644
> index 00000000..d2ff5152
> --- /dev/null
> +++ b/test/unittest/actions/trace/tst.alloca.d
> @@ -0,0 +1,24 @@
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	arr = (int *)alloca(5 * sizeof(int));
> +	idx = 4;
> +	arr[0] = 1;
> +	arr[1] = 22;
> +	arr[2] = 333;
> +	arr[3] = 4444;
> +	arr[4] = 55555;
> +	trace(arr);
> +	trace(" ");
> +	trace(*arr);
> +	trace(" ");
> +	trace(arr + 2);
> +	trace(" ");
> +	trace(*(arr + 2));
> +	trace(" ");
> +	trace(arr + idx);
> +	trace(" ");
> +	trace(*(arr + idx));
> +	exit(0);
> +}
> diff --git a/test/unittest/actions/trace/tst.alloca.r b/test/unittest/actions/trace/tst.alloca.r
> new file mode 100644
> index 00000000..e9bbf2f5
> --- /dev/null
> +++ b/test/unittest/actions/trace/tst.alloca.r
> @@ -0,0 +1 @@
> +OK 1 OK 333 OK 55555
> diff --git a/test/unittest/actions/trace/tst.alloca.r.p b/test/unittest/actions/trace/tst.alloca.r.p
> new file mode 100755
> index 00000000..8515861a
> --- /dev/null
> +++ b/test/unittest/actions/trace/tst.alloca.r.p
> @@ -0,0 +1,11 @@
> +#!/usr/bin/gawk -f
> +
> +{
> +	$1 = $1 > 0x7fffffff ? "OK" : "BAD";
> +	$3 = $3 > 0x7fffffff ? "OK" : "BAD";
> +	$5 = $5 > 0x7fffffff ? "OK" : "BAD";
> +}
> +
> +{
> +	print;
> +}



More information about the DTrace-devel mailing list