public inbox for dtrace@lists.linux.dev
 help / color / mirror / Atom feed
From: Nick Alcock <nick.alcock@oracle.com>
To: eugene.loh@oracle.com
Cc: dtrace@lists.linux.dev, dtrace-devel@oss.oracle.com
Subject: Re: [PATCH 4/4] Pad strings in the output buffer with NUL bytes after terminating byte
Date: Tue, 22 Jul 2025 15:05:06 +0100	[thread overview]
Message-ID: <87seio723x.fsf@esperi.org.uk> (raw)
In-Reply-To: <20250325222521.15224-4-eugene.loh@oracle.com> (eugene loh's message of "Tue, 25 Mar 2025 18:25:21 -0400")

On 25 Mar 2025, eugene loh uttered the following:

> From: Eugene Loh <eugene.loh@oracle.com>
>
> The consumer checks if there are non-NUL bytes after the terminating
> NUL byte to decide whether to print the contents of the output buffer
> as a string or as raw bytes.  So, for strings, make sure that the
> string is padded with NUL bytes.

Ugh. I guess there's no choice if we want trace() to work properly.

A use for strncpy()! except that this is BPF :)

> Signed-off-by: Eugene Loh <eugene.loh@oracle.com>

Reviewed-by: Nick Alcock <nick.alcock@oracle.com>

because basing decisions on uninitialized data is bad.

(Modulo nit below.)

> ---
>  libdtrace/dt_cg.c                      | 46 ++++++++++++++++++--------
>  test/unittest/error/tst.trace_string.d | 26 +++++++++++++++
>  2 files changed, 59 insertions(+), 13 deletions(-)
>  create mode 100644 test/unittest/error/tst.trace_string.d
>
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 9b3592b9c..6dcf4cd3d 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -1596,6 +1596,22 @@ dt_cg_check_ptr_arg(dt_irlist_t *dlp, dt_regset_t *drp, dt_node_t *dnp,
>  
>  static void dt_cg_setx(dt_irlist_t *dlp, int reg, uint64_t x);
>  
> +/*
> + * Store a pointer to the 'memory block of zeros' in reg.
> + */
> +static void
> +dt_cg_zerosptr(int reg, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> +	dtrace_hdl_t	*dtp = yypcb->pcb_hdl;
> +	dt_ident_t	*zero_off = dt_dlib_get_var(dtp, "ZERO_OFF");
> +
> +	dt_cg_access_dctx(reg, dlp, drp, DCTX_STRTAB);
> +	emite(dlp, BPF_ALU64_IMM(BPF_ADD, reg, -1), zero_off);
> +}
> +
> +/*
> + * Store a value to the output buffer.
> + */
>  static int
>  dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
>  		dt_pfargv_t *pfp, int arg)
> @@ -1676,6 +1692,7 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
>  
>  		goto ok;
>  	} else if (dt_node_is_string(dnp)) {
> +		uint_t	lbl_ok = dt_irlist_label(dlp);
>  		size_t	strsize = dtp->dt_options[DTRACEOPT_STRSIZE];
>  
>  		if (!not_null)
> @@ -1702,6 +1719,22 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
>  		dt_regset_xalloc(drp, BPF_REG_0);
>  		emit(dlp, BPF_CALL_HELPER(BPF_FUNC_probe_read_str));
>  		dt_regset_free_args(drp);
> +
> +		/*
> +		 * Pad the rest with zeroes, if necessary.
> +		 */
> +		emit(dlp,  BPF_BRANCH_IMM(BPF_JGE, BPF_REG_0, strsize + 1, lbl_ok));
> +		if (dt_regset_xalloc_args(drp) == -1)
> +			longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> +		emit(dlp,  BPF_MOV_REG(BPF_REG_1, BPF_REG_9));
> +		emit(dlp,  BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, off));
> +		emit(dlp,  BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0));
> +		emit(dlp,  BPF_MOV_IMM(BPF_REG_2, strsize + 1));
> +		emit(dlp,  BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_0));
> +		dt_cg_zerosptr(BPF_REG_3, dlp, drp);
> +		emit(dlp,  BPF_CALL_HELPER(dtp->dt_bpfhelper[BPF_FUNC_probe_read_kernel]));

Much faster than using a loop in all but the smallest cases, I suppose.
(And the zero block is presumably always big enough... yes, it is.)

> diff --git a/test/unittest/error/tst.trace_string.d b/test/unittest/error/tst.trace_string.d
> new file mode 100644
> index 000000000..4b06aef88
> --- /dev/null
> +++ b/test/unittest/error/tst.trace_string.d
> @@ -0,0 +1,26 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2025, 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: Test ERROR probe firing.

... is that really what you want to describe this test as?

> + * SECTION: dtrace Provider
> + */
> +
> +#pragma D option quiet
> +
> +ERROR
> +{
> +	trace("Error fired");

.... given that its stated purpose is quite different, why not describe
that purpose?

  reply	other threads:[~2025-07-22 14:05 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-25 22:25 [PATCH 1/4] Remove orphaned dtrace_recdesc_t component dtrd_uarg eugene.loh
2025-03-25 22:25 ` [PATCH 2/4] test: Skip trace() of a 1-byte struct eugene.loh
2025-07-22 13:46   ` Nick Alcock
2025-08-13 20:20     ` Eugene Loh
2025-03-25 22:25 ` [PATCH 3/4] test: Update some char-array results files eugene.loh
2025-07-22 13:51   ` Nick Alcock
2025-07-22 21:53     ` Eugene Loh
2025-03-25 22:25 ` [PATCH 4/4] Pad strings in the output buffer with NUL bytes after terminating byte eugene.loh
2025-07-22 14:05   ` Nick Alcock [this message]
2025-04-11 20:38 ` [PATCH 1/4] Remove orphaned dtrace_recdesc_t component dtrd_uarg Kris Van Hees

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87seio723x.fsf@esperi.org.uk \
    --to=nick.alcock@oracle.com \
    --cc=dtrace-devel@oss.oracle.com \
    --cc=dtrace@lists.linux.dev \
    --cc=eugene.loh@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox