Re: [PATCH v4] trace: print alloca pointers as actual pointer values

Eugene Loh <[email protected]>
Newsgroups dev.linux.lists.dtrace
Message-ID <[email protected]>
Reviewed-by: Eugene Loh <[email protected]>

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 <[email protected]>
> ---
>   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;
> +}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.