[DTrace-devel] [PATCH v2 4/4] probe: make it possible to destroy probes in more cases
Nick Alcock
nick.alcock at oracle.com
Thu Nov 14 22:01:08 UTC 2024
In particular, when the parser has failed (so we have no yypcb)
but we have successfully defined some interface-only probes but
not yet cooked them (so we have no provimpl), we can find that
*both* our sources for a dtp in dt_probe_destroy are unavailable.
Make one available in the dt_probe_t as well.
The test in this commit provides a .d like this:
provider prova { probe entrya(); };
provider provb { probe entryb(); probe entryc(int, char *) : (char *, int); };
prova is defined but not cooked because parsing failed in provb, so we get
this crash when trying to do final cleanup of prova, long after the parser is
gone:
1 0x00007ffff7cf408a in dt_iddtor_probe (idp=0x3cee000) at libdtrace/dt_ident.c:542
2 0x00007ffff7cf4d5a in dt_ident_destroy (idp=0x3cee000) at libdtrace/dt_ident.c:964
3 0x00007ffff7d0c226 in dt_node_free (dnp=0x21e05b0) at libdtrace/dt_parser.c:571
4 0x00007ffff7d17748 in dt_node_list_free (pnp=0x3cee1b8) at libdtrace/dt_parser.c:4851
5 0x00007ffff7d0c460 in dt_node_free (dnp=0x3cee180) at libdtrace/dt_parser.c:643
6 0x00007ffff7d177ab in dt_node_link_free (pnp=0x3cee278) at libdtrace/dt_parser.c:4865
7 0x00007ffff7d3df8b in dt_provider_del_prov (head=0x0, pvp=0x3cee1f0) at libdtrace/dt_provider.c:74
8 0x00007ffff7cf1d32 in dt_htab_destroy (dtp=0x53eb20, htab=0x187a8a0) at libdtrace/dt_htab.c:108
9 0x00007ffff7d0842e in dtrace_close (dtp=0x53eb20) at libdtrace/dt_open.c:1306
10 0x0000000000403f8e in dfatal (fmt=0x4d6a45 "failed to compile script %s") at cmd/dtrace.c:194
11 0x0000000000404b9b in compile_file (dcp=0x536990) at cmd/dtrace.c:480
12 0x00000000004073c9 in main (argc=8, argv=0x7fffffffe788) at cmd/dtrace.c:1351
Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
---
libdtrace/dt_probe.c | 14 +++-----
libdtrace/dt_probe.h | 1 +
.../unittest/usdt/err.argmap-name-required.sh | 34 +++++++++++++++++++
3 files changed, 40 insertions(+), 9 deletions(-)
create mode 100755 test/unittest/usdt/err.argmap-name-required.sh
diff --git a/libdtrace/dt_probe.c b/libdtrace/dt_probe.c
index ccaa3081c5b23..31c78d6d987e1 100644
--- a/libdtrace/dt_probe.c
+++ b/libdtrace/dt_probe.c
@@ -140,8 +140,7 @@ alloc_arg_nodes(dtrace_hdl_t *dtp, dt_provider_t *pvp, int argc)
static void
dt_probe_alloc_args(dt_probe_t *prp, int nargc, int xargc)
{
- dt_provider_t *pvp = prp->prov;
- dtrace_hdl_t *dtp = pvp->pv_hdl;
+ dtrace_hdl_t *dtp = prp->dtp;
dt_node_t *nargs = NULL, *xargs = NULL;
int i;
@@ -252,6 +251,7 @@ dt_probe_create(dtrace_hdl_t *dtp, dt_ident_t *idp, int protoc,
prp->pr_inst = NULL;
prp->argv = dt_calloc(dtp, xargc, sizeof(dtrace_typeinfo_t));
prp->argc = xargc;
+ prp->dtp = dtp;
if ((prp->nargc != 0 && prp->nargv == NULL) ||
(prp->xargc != 0 && prp->xargv == NULL) ||
@@ -323,12 +323,7 @@ dt_probe_destroy(dt_probe_t *prp)
dt_probe_stmt_t *psp, *psp_next;
dt_probe_instance_t *pip, *pip_next;
dt_probe_dependent_t *dep, *dep_next;
- dtrace_hdl_t *dtp;
-
- if (prp->prov != NULL)
- dtp = prp->prov->pv_hdl;
- else
- dtp = yypcb->pcb_hdl;
+ dtrace_hdl_t *dtp = prp->dtp;
if (prp->difo)
dt_difo_free(dtp, prp->difo);
@@ -473,7 +468,7 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp, const char *fname,
dt_node_t *
dt_probe_tag(dt_probe_t *prp, uint_t argn, dt_node_t *dnp)
{
- dtrace_hdl_t *dtp = prp->prov->pv_hdl;
+ dtrace_hdl_t *dtp = prp->dtp;
dtrace_typeinfo_t dtt;
size_t len;
char *tag;
@@ -557,6 +552,7 @@ dt_probe_insert(dtrace_hdl_t *dtp, dt_provider_t *prov, const char *prv,
prp->prov = prov;
prp->prv_data = datap;
prp->argc = -1;
+ prp->dtp = dtp;
dt_htab_insert(dtp->dt_byprv, prp);
dt_htab_insert(dtp->dt_bymod, prp);
diff --git a/libdtrace/dt_probe.h b/libdtrace/dt_probe.h
index 2a78cb9ca4dae..da7a341354225 100644
--- a/libdtrace/dt_probe.h
+++ b/libdtrace/dt_probe.h
@@ -55,6 +55,7 @@ typedef struct dt_probe {
int argc; /* output argument count */
dt_probe_instance_t *pr_inst; /* list of functions and offsets */
dtrace_difo_t *difo; /* BPF probe program */
+ dtrace_hdl_t *dtp; /* pointer to containing dtrace_hdl */
} dt_probe_t;
extern dt_probe_t *dt_probe_lookup2(dt_provider_t *, const char *);
diff --git a/test/unittest/usdt/err.argmap-name-required.sh b/test/unittest/usdt/err.argmap-name-required.sh
new file mode 100755
index 0000000000000..3fdefb8130ac7
--- /dev/null
+++ b/test/unittest/usdt/err.argmap-name-required.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2024, 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.
+#
+# Make sure we get the right error when mappings are defined with no
+# argument.
+
+if [ $# != 1 ]; then
+ echo expected one argument: '<'dtrace-path'>'
+ exit 2
+fi
+
+dtrace=$1
+CC=/usr/bin/gcc
+CFLAGS="$test_cppflags"
+LDFLAGS="$test_ldflags"
+
+DIRNAME="$tmpdir/argmap-name-required.$$.$RANDOM"
+mkdir -p $DIRNAME
+cd $DIRNAME
+
+# We define multiple probes here to verify the absence of a potential error
+# where parser failures when previous probes have been successfully defined
+# causes crashes due to problems freeing still-uncooked probes.
+
+cat > prov.d <<EOF
+provider prova { probe entrya(); };
+provider provb { probe entryb(); probe entryc(int, char *) : (char *, int); };
+EOF
+
+exec $dtrace $dt_flags -h -s prov.d
--
2.46.0.278.g36e3a12567
More information about the DTrace-devel
mailing list