[DTrace-devel] [PATCH] print: Fix truncation
Kris Van Hees
kvanhees at kvh-deb-bpf.us.oracle.com
Tue Jan 30 16:06:47 UTC 2024
On Fri, Dec 22, 2023 at 07:51:15PM -0500, eugene.loh at oracle.com wrote:
>
> The printsize option can be used to limit how much data is reported
> by print(). A few corrections are needed.
>
> 1) In dt_print_visit(), we check if offset/NBBY > dv_size. E.g.,
> if a 40-byte limit is set, then an 8-byte record at offset 40 will
> be reported. Change to offset/NBBY >= dv_size. We do not worry
> about the case where the print size ends in the middle of a record.
>
> 2) dt_print_type() sets the size and then calls dt_print_visit().
> But dt_print_visit() can also call itself recursively, and in this
> case dv_size is not set. The dv_size values at deeper depths are
> garbage. Have dt_print_visit() set dva2.dt_size.
>
> The existing test for -xprintsize is corrected and a new test,
> focused on truncation at deeper depths, is added.
>
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
> libdtrace/dt_printf.c | 3 +-
> test/unittest/print/tst.print.local.trunc.d | 9 +-
> test/unittest/print/tst.print.local.trunc.r | 1 +
> test/unittest/print/tst.print.local.trunc2.d | 55 ++++++++
> test/unittest/print/tst.print.local.trunc2.r | 125 +++++++++++++++++++
> 5 files changed, 191 insertions(+), 2 deletions(-)
> create mode 100644 test/unittest/print/tst.print.local.trunc2.d
> create mode 100644 test/unittest/print/tst.print.local.trunc2.r
>
> diff --git a/libdtrace/dt_printf.c b/libdtrace/dt_printf.c
> index 2658c6a8..e844dc1b 100644
> --- a/libdtrace/dt_printf.c
> +++ b/libdtrace/dt_printf.c
> @@ -1993,7 +1993,7 @@ dt_print_visit(const char *name, ctf_id_t type, unsigned long offset,
> int i;
>
> /* run out of data to display, or hit depth limit? */
> - if ((offset/NBBY) > dva->dv_size || depth >= DT_PRINT_DEPTH) {
> + if ((offset/NBBY) >= dva->dv_size || depth >= DT_PRINT_DEPTH) {
> dt_printf(dva->dv_dtp, dva->dv_fp, "%*s...\n",
> dva->dv_startindent + depth, "");
> return -1;
> @@ -2197,6 +2197,7 @@ doprint:
> dva2.dv_fp = dva->dv_fp;
> dva2.dv_data = dva->dv_data;
> dva2.dv_startindent = dva->dv_startindent;
> + dva2.dv_size = dva->dv_size;
> if (ctf_type_encoding(dva->dv_ctfp, a.ctr_contents, &e) < 0) {
> dt_dprintf("error retrieving type encoding for array contents in [%ld]: %s\n",
> a.ctr_contents,
> diff --git a/test/unittest/print/tst.print.local.trunc.d b/test/unittest/print/tst.print.local.trunc.d
> index 25ad54b0..2e40dd84 100644
> --- a/test/unittest/print/tst.print.local.trunc.d
> +++ b/test/unittest/print/tst.print.local.trunc.d
> @@ -41,9 +41,16 @@ BEGIN
> t->s.f = 100,
> t->g = 1;
> t->h = FIRSTVAL;
> + printf("a %d; b %d; u %d; s %d; g %d; h %d\n",
> + offsetof(struct test_struct, a),
> + offsetof(struct test_struct, b),
> + offsetof(struct test_struct, u),
> + offsetof(struct test_struct, s),
> + offsetof(struct test_struct, g),
> + offsetof(struct test_struct, h));
> print(t);
> /* ensure printsize can be dynamically changed */
> - setopt("printsize", "16");
> + setopt("printsize", "24");
> print(t);
> exit(0);
> }
> diff --git a/test/unittest/print/tst.print.local.trunc.r b/test/unittest/print/tst.print.local.trunc.r
> index df5708d9..8cefaa17 100644
> --- a/test/unittest/print/tst.print.local.trunc.r
> +++ b/test/unittest/print/tst.print.local.trunc.r
> @@ -1,3 +1,4 @@
> +a 0; b 4; u 16; s 24; g 40; h 44
> {ptr} = *
> (struct test_struct) {
> .a = (int)1,
> diff --git a/test/unittest/print/tst.print.local.trunc2.d b/test/unittest/print/tst.print.local.trunc2.d
> new file mode 100644
> index 00000000..5f500fc8
> --- /dev/null
> +++ b/test/unittest/print/tst.print.local.trunc2.d
> @@ -0,0 +1,55 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2023, 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.
> + */
> +/* @@nosort */
> +
> +#pragma D option quiet
> +
> +struct test_struct {
> + long long x;
> + struct {
> + long long x;
> + struct {
> + long long x;
> + struct {
> + long long x;
> + struct {
> + long long x;
> + struct {
> + long long x;
> + struct {
> + long long x;
> + struct {
> + long long x;
> + } g;
> + } f;
> + } e;
> + } d;
> + } c;
> + } b;
> + } a;
> +};
> +
> +BEGIN
> +{
> + t = (struct test_struct *)alloca(sizeof (struct test_struct));
> + t->x = 1111111111111111ll;
> + t->a.x = 2222222222222222ll;
> + t->a.b.x = 3333333333333333ll;
> + t->a.b.c.x = 4444444444444444ll;
> + t->a.b.c.d.x = 5555555555555555ll;
> + t->a.b.c.d.e.x = 6666666666666666ll;
> + t->a.b.c.d.e.f.x = 7777777777777777ll;
> + t->a.b.c.d.e.f.g.x = 8888888888888888ll;
> +
> + setopt("printsize", "90"); print(t);
> + setopt("printsize", "64"); print(t);
> + setopt("printsize", "56"); print(t);
> + setopt("printsize", "48"); print(t);
> + setopt("printsize", "40"); print(t);
> + setopt("printsize", "32"); print(t);
> + exit(0);
> +}
> diff --git a/test/unittest/print/tst.print.local.trunc2.r b/test/unittest/print/tst.print.local.trunc2.r
> new file mode 100644
> index 00000000..7de3136c
> --- /dev/null
> +++ b/test/unittest/print/tst.print.local.trunc2.r
> @@ -0,0 +1,125 @@
> +{ptr} = *
> + (struct test_struct) {
> + .x = (long long)1111111111111111,
> + .a = (struct) {
> + .x = (long long)2222222222222222,
> + .b = (struct) {
> + .x = (long long)3333333333333333,
> + .c = (struct) {
> + .x = (long long)4444444444444444,
> + .d = (struct) {
> + .x = (long long)5555555555555555,
> + .e = (struct) {
> + .x = (long long)6666666666666666,
> + .f = (struct) {
> + .x = (long long)7777777777777777,
> + .g = (struct) {
> + .x = (long long)8888888888888888,
> + },
> + },
> + },
> + },
> + },
> + },
> + },
> + }
> +{ptr} = *
> + (struct test_struct) {
> + .x = (long long)1111111111111111,
> + .a = (struct) {
> + .x = (long long)2222222222222222,
> + .b = (struct) {
> + .x = (long long)3333333333333333,
> + .c = (struct) {
> + .x = (long long)4444444444444444,
> + .d = (struct) {
> + .x = (long long)5555555555555555,
> + .e = (struct) {
> + .x = (long long)6666666666666666,
> + .f = (struct) {
> + .x = (long long)7777777777777777,
> + .g = (struct) {
> + .x = (long long)8888888888888888,
> + },
> + },
> + },
> + },
> + },
> + },
> + },
> + }
> +{ptr} = *
> + (struct test_struct) {
> + .x = (long long)1111111111111111,
> + .a = (struct) {
> + .x = (long long)2222222222222222,
> + .b = (struct) {
> + .x = (long long)3333333333333333,
> + .c = (struct) {
> + .x = (long long)4444444444444444,
> + .d = (struct) {
> + .x = (long long)5555555555555555,
> + .e = (struct) {
> + .x = (long long)6666666666666666,
> + .f = (struct) {
> + .x = (long long)7777777777777777,
> + ...
> + },
> + },
> + },
> + },
> + },
> + },
> + }
> +{ptr} = *
> + (struct test_struct) {
> + .x = (long long)1111111111111111,
> + .a = (struct) {
> + .x = (long long)2222222222222222,
> + .b = (struct) {
> + .x = (long long)3333333333333333,
> + .c = (struct) {
> + .x = (long long)4444444444444444,
> + .d = (struct) {
> + .x = (long long)5555555555555555,
> + .e = (struct) {
> + .x = (long long)6666666666666666,
> + ...
> + },
> + },
> + },
> + },
> + },
> + }
> +{ptr} = *
> + (struct test_struct) {
> + .x = (long long)1111111111111111,
> + .a = (struct) {
> + .x = (long long)2222222222222222,
> + .b = (struct) {
> + .x = (long long)3333333333333333,
> + .c = (struct) {
> + .x = (long long)4444444444444444,
> + .d = (struct) {
> + .x = (long long)5555555555555555,
> + ...
> + },
> + },
> + },
> + },
> + }
> +{ptr} = *
> + (struct test_struct) {
> + .x = (long long)1111111111111111,
> + .a = (struct) {
> + .x = (long long)2222222222222222,
> + .b = (struct) {
> + .x = (long long)3333333333333333,
> + .c = (struct) {
> + .x = (long long)4444444444444444,
> + ...
> + },
> + },
> + },
> + }
> +
> --
> 2.18.4
>
>
More information about the DTrace-devel
mailing list