[DTrace-devel] [PATCH 15/15] Implement the proc provider

Kris Van Hees kris.van.hees at oracle.com
Thu Feb 23 07:24:22 UTC 2023


The following probes (and their arguments) are currently supported:

proc:::exec
proc:::exec-failure
proc:::exec-success
proc:::exit
proc:::lwp-exit
proc:::create
proc:::lwp-create
proc:::start
proc:::lwp-start
proc:::signal-discard
proc:::signal-handle
proc:::signal-send

Various tests now pass and therefore no longer need @@xfail.

Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 libdtrace/Build                             |   2 +
 libdtrace/dt_open.c                         |   1 +
 libdtrace/dt_prov_proc.c                    | 435 ++++++++++++++++++++
 libdtrace/dt_provider.h                     |   9 +-
 test/demo/proc/lwptime.d                    |   1 -
 test/demo/proc/progtime.d                   |   1 -
 test/demo/proc/sig.d                        |   1 -
 test/demo/proc/whoexec.d                    |   1 -
 test/unittest/builtinvar/tst.errno2.d       |   1 -
 test/unittest/dtrace-util/tst.ProcInvoke.sh |   2 -
 test/unittest/pid/tst.fork.d                |   1 -
 test/unittest/pid/tst.vfork.d               |   2 +-
 test/unittest/proc/tst.create.sh            |   2 -
 test/unittest/proc/tst.discard.sh           |  12 +-
 test/unittest/proc/tst.exec.sh              |   2 -
 test/unittest/proc/tst.execfail.ENOENT.sh   |   2 -
 test/unittest/proc/tst.execfail.sh          |   2 -
 test/unittest/proc/tst.exitcore.sh          |  31 +-
 test/unittest/proc/tst.exitexit.sh          |   2 -
 test/unittest/proc/tst.startexit.sh         |   2 -
 test/unittest/regression/exit_panic.d       |   1 -
 21 files changed, 469 insertions(+), 44 deletions(-)
 create mode 100644 libdtrace/dt_prov_proc.c

diff --git a/libdtrace/Build b/libdtrace/Build
index e674e22e..c73aa881 100644
--- a/libdtrace/Build
+++ b/libdtrace/Build
@@ -48,6 +48,7 @@ libdtrace-build_SOURCES = dt_aggregate.c \
 			  dt_program.c \
 			  dt_prov_dtrace.c \
 			  dt_prov_fbt.c \
+			  dt_prov_proc.c \
 			  dt_prov_profile.c \
 			  dt_prov_rawtp.c \
 			  dt_prov_sdt.c \
@@ -89,6 +90,7 @@ dt_pid.c_CFLAGS := -Wno-pedantic
 dt_proc.c_CFLAGS := -Wno-pedantic
 dt_prov_dtrace.c_CFLAGS := -Wno-pedantic
 dt_prov_fbt.c_CFLAGS := -Wno-pedantic
+dt_prov_proc.c_CFLAGS := -Wno-pedantic
 dt_prov_profile.c_CFLAGS := -Wno-pedantic
 dt_prov_rawtp.c_CFLAGS := -Wno-pedantic
 dt_prov_sdt.c_CFLAGS := -Wno-pedantic
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index aa739d95..cb2b287c 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -66,6 +66,7 @@ const dt_version_t _dtrace_versions[] = {
 static const dt_provimpl_t *dt_providers[] = {
 	&dt_dtrace,
 	&dt_fbt,
+	&dt_proc,
 	&dt_profile,
 	&dt_rawtp,
 	&dt_sdt,
diff --git a/libdtrace/dt_prov_proc.c b/libdtrace/dt_prov_proc.c
new file mode 100644
index 00000000..edf1fdae
--- /dev/null
+++ b/libdtrace/dt_prov_proc.c
@@ -0,0 +1,435 @@
+/*
+ * 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.
+ *
+ * The 'proc' SDT provider for DTrace specific probes.
+ */
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/bpf.h>
+#include <linux/perf_event.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <bpf_asm.h>
+
+#include "dt_dctx.h"
+#include "dt_cg.h"
+#include "dt_bpf.h"
+#include "dt_provider.h"
+#include "dt_probe.h"
+#include "dt_pt_regs.h"
+
+static const char		prvname[] = "proc";
+static const char		modname[] = "vmlinux";
+
+#define PROBE_LIST		TRACEFS "available_events"
+
+#define KPROBES			"kprobes"
+#define SYSCALLS		"syscalls"
+#define UPROBES			"uprobes"
+#define PID			"dt_pid"
+
+/*
+ * Implement proc probes as dependent probes on other probes.  E.g. for the
+ * exec* case, call (to be written) dt_probe_add_dependent(probe).  When the
+ * program for the main probe (e.g. syscall::execve:entry) is generated, it
+ * should loop through any dependent probes, and for each call a (new) hook
+ * function that generates a pseudo-trampoline that converts the main probe
+ * into the dependent probe.  Then it should add calls to all the clauses of
+ * the dependent probe.
+ *
+ * The process of converting the main probe to the dependent probe needs to be
+ * done in a way that preserves the original probe data so that multiple
+ * dependent probes are possible (and each needs to be able to convert the
+ * main probe data into the proper dependent data using a pseudo-trampoline).
+ *
+ * The conversion needs to be able to implement predicate-style conditions that
+ * determine whether the dependent probe is to fire when the main probe does.
+ * The proc:::exec-failure and proc:::exec-success probes are an example of
+ * dependent probes that need a conditional.  If the condition fails, the main
+ * probe processing should move on to the next dependent probe (if any).  If
+ * there are no more dependent probes, it will end up skipping to the exit
+ * label.
+ *
+ * Dependent probes need priorities for cases where two probes are dependent on
+ * the same underlying probe, but one needs to 'fire' before the other.  One
+ * such example is proc:::start and proc:::lwp-start.
+ *
+ * proc:::exec
+ *	- Use syscall::exec*:entry
+ *	- Clear arg1 and beyond (arg0 is already the filename)
+ * proc:::exec-success
+ *	- Use syscall::exec*:return
+ *	- Only when arg0 == 0
+ *	- Clear all args
+ * proc:::exec-failure
+ *	- Use syscall::exec*:return
+ *	- Only when arg0 != 0
+ *	- Argument arg0 is already correct
+ */
+
+typedef struct probe_arg {
+	const char	*name;			/* name of probe */
+	int		argno;			/* argument number */
+	dt_argdesc_t	argdesc;		/* argument description */
+} probe_arg_t;
+
+static probe_arg_t probe_args[] = {
+	{ "create", 0, { 0, "struct task_struct *", "psinfo_t *" } },
+	{ "exec", 0, { 0, "string", } },
+	{ "exec-failure", 0, { 0, "int", } },
+	{ "exec-success", },
+	{ "exit", 0, { 0, "int", } },
+#if 0
+	{ "fault", 0, { 0, "int", } },
+	{ "fault", 1, { 1, "siginfo_t *", } },
+#endif
+	{ "lwp-create", 0, { 0, "struct task_struct *", "lwpsinfo_t *" } },
+	{ "lwp-create", 1, { 0, "struct task_struct *", "psinfo_t *" } },
+	{ "lwp-exit", },
+	{ "lwp-start", },
+#if 0
+	{ "signal-clear", 0, { 0, "int", } },
+	{ "signal-clear", 1, { 1, "siginfo_t *", } },
+#endif
+	{ "signal-discard", 0, { 0, "struct task_struct *", "lwpsinfo_t *" } },
+	{ "signal-discard", 1, { 0, "struct task_struct *", "psinfo_t *" } },
+	{ "signal-discard", 2, { 1, "int", } },
+	{ "signal-handle", 0, { 0, "int", } },
+	{ "signal-handle", 1, { 1, "siginfo_t *", } },
+	{ "signal-handle", 2, { 2, "void (*)(void)", } },
+	{ "signal-send", 0, { 0, "struct task_struct *", "lwpsinfo_t *" } },
+	{ "signal-send", 1, { 0, "struct task_struct *", "psinfo_t *" } },
+	{ "signal-send", 2, { 1, "int", } },
+	{ "start", },
+};
+
+static const dtrace_pattr_t	pattr = {
+{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
+{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
+{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
+{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
+{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
+};
+
+/*
+ * Provide all the "proc" SDT probes.
+ */
+static int populate(dtrace_hdl_t *dtp)
+{
+	dt_provider_t	*prv;
+	int		i;
+	int		n = 0;
+
+	prv = dt_provider_create(dtp, prvname, &dt_proc, &pattr);
+	if (prv == NULL)
+		return 0;
+
+	/*
+	 * Create "proc" probes based on the probe_args list.  Since each probe
+	 * will have at least one entry (with argno == 0), we can use those
+	 * entries to identify the probe names.
+	 */
+	for (i = 0; i < ARRAY_SIZE(probe_args); i++) {
+		probe_arg_t	*arg = &probe_args[i];
+
+		if (arg->argno == 0 &&
+		    dt_probe_insert(dtp, prv, prvname, modname, "", arg->name,
+				    NULL))
+			n++;
+	}
+
+	return n;
+}
+
+static void enable(dtrace_hdl_t *dtp, dt_probe_t *prp)
+{
+	dt_probe_t		*uprp = NULL;
+	dtrace_probedesc_t	pd;
+
+	if (strcmp(prp->desc->prb, "create") == 0 ||
+	    strcmp(prp->desc->prb, "lwp-create") == 0) {
+		pd.id = DTRACE_IDNONE;
+		pd.prv = "rawtp";
+		pd.mod = "sched";
+		pd.fun = "";
+		pd.prb = "sched_process_fork";
+
+		uprp = dt_probe_lookup(dtp, &pd);
+		assert(uprp != NULL);
+
+		dt_probe_add_dependent(dtp, uprp, prp);
+		dt_probe_enable(dtp, uprp);
+	} else if (strcmp(prp->desc->prb, "exec") == 0) {
+		pd.id = DTRACE_IDNONE;
+		pd.prv = "syscall";
+		pd.mod = "";
+		pd.fun = "execve";
+		pd.prb = "entry";
+
+		uprp = dt_probe_lookup(dtp, &pd);
+		assert(uprp != NULL);
+
+		dt_probe_add_dependent(dtp, uprp, prp);
+		dt_probe_enable(dtp, uprp);
+
+		pd.fun = "execveat";
+
+		uprp = dt_probe_lookup(dtp, &pd);
+		assert(uprp != NULL);
+
+		dt_probe_add_dependent(dtp, uprp, prp);
+		dt_probe_enable(dtp, uprp);
+	} else if (strcmp(prp->desc->prb, "exec-failure") == 0 ||
+		   strcmp(prp->desc->prb, "exec-success") == 0) {
+		pd.id = DTRACE_IDNONE;
+		pd.prv = "syscall";
+		pd.mod = "";
+		pd.fun = "execve";
+		pd.prb = "return";
+
+		uprp = dt_probe_lookup(dtp, &pd);
+		assert(uprp != NULL);
+
+		dt_probe_add_dependent(dtp, uprp, prp);
+		dt_probe_enable(dtp, uprp);
+
+		pd.fun = "execveat";
+
+		uprp = dt_probe_lookup(dtp, &pd);
+		assert(uprp != NULL);
+
+		dt_probe_add_dependent(dtp, uprp, prp);
+		dt_probe_enable(dtp, uprp);
+	} else if (strcmp(prp->desc->prb, "exit") == 0 ||
+		   strcmp(prp->desc->prb, "lwp-exit") == 0) {
+		pd.id = DTRACE_IDNONE;
+		pd.prv = "fbt";
+		pd.mod = "";
+		pd.fun = "taskstats_exit";
+		pd.prb = "entry";
+
+		uprp = dt_probe_lookup(dtp, &pd);
+		assert(uprp != NULL);
+
+		dt_probe_add_dependent(dtp, uprp, prp);
+		dt_probe_enable(dtp, uprp);
+	} else if (strcmp(prp->desc->prb, "signal-discard") == 0) {
+		pd.id = DTRACE_IDNONE;
+		pd.prv = "rawtp";
+		pd.mod = "signal";
+		pd.fun = "";
+		pd.prb = "signal_generate";
+
+		uprp = dt_probe_lookup(dtp, &pd);
+		assert(uprp != NULL);
+
+		dt_probe_add_dependent(dtp, uprp, prp);
+		dt_probe_enable(dtp, uprp);
+	} else if (strcmp(prp->desc->prb, "signal-handle") == 0) {
+		pd.id = DTRACE_IDNONE;
+		pd.prv = "rawtp";
+		pd.mod = "signal";
+		pd.fun = "";
+		pd.prb = "signal_deliver";
+
+		uprp = dt_probe_lookup(dtp, &pd);
+		assert(uprp != NULL);
+
+		dt_probe_add_dependent(dtp, uprp, prp);
+		dt_probe_enable(dtp, uprp);
+	} else if (strcmp(prp->desc->prb, "signal-send") == 0) {
+		pd.id = DTRACE_IDNONE;
+		pd.prv = "fbt";
+		pd.mod = "";
+		pd.fun = "complete_signal";
+		pd.prb = "entry";
+
+		uprp = dt_probe_lookup(dtp, &pd);
+		assert(uprp != NULL);
+
+		dt_probe_add_dependent(dtp, uprp, prp);
+		dt_probe_enable(dtp, uprp);
+	} else if (strcmp(prp->desc->prb, "start") == 0 ||
+		   strcmp(prp->desc->prb, "lwp-start") == 0) {
+		pd.id = DTRACE_IDNONE;
+		pd.prv = "fbt";
+		pd.mod = "";
+		pd.fun = "schedule_tail";
+		pd.prb = "return";
+
+		uprp = dt_probe_lookup(dtp, &pd);
+		assert(uprp != NULL);
+
+		dt_probe_add_dependent(dtp, uprp, prp);
+		dt_probe_enable(dtp, uprp);
+	}
+
+	/*
+	 * Finally, ensure we're in the list of enablings as well.
+	 * (This ensures that, among other things, the probes map
+	 * gains entries for us.)
+	 */
+	if (!dt_in_list(&dtp->dt_enablings, prp))
+		dt_list_append(&dtp->dt_enablings, prp);
+}
+
+/*
+ * Generate a BPF trampoline for a SDT probe.
+ *
+ * The trampoline function is called when a SDT probe triggers, and it must
+ * satisfy the following prototype:
+ *
+ *	int dt_proc(void *data)
+ *
+ * The trampoline will populate a dt_dctx_t struct and then call the function
+ * that implements the compiled D clause.  It returns the value that it gets
+ * back from that function.
+ */
+static void trampoline(dt_pcb_t *pcb, uint_t exitlbl)
+{
+	dtrace_hdl_t	*dtp = pcb->pcb_hdl;
+	dt_irlist_t	*dlp = &pcb->pcb_ir;
+	dt_probe_t	*prp = pcb->pcb_probe;
+
+	if (strcmp(prp->desc->prb, "create") == 0) {
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_7, DMST_ARG(1)));
+		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
+	} else if (strcmp(prp->desc->prb, "exec-success") == 0) {
+		/* Pre-condition: exec syscall returns 0 */
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_7, DMST_ARG(1)));
+		emit(dlp, BPF_BRANCH_IMM(BPF_JNE, BPF_REG_0, 0, exitlbl));
+	} else if (strcmp(prp->desc->prb, "exec-failure") == 0) {
+		/* Pre-condition: exec syscall returns non-0 */
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_7, DMST_ARG(1)));
+		emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, exitlbl));
+		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
+	} else if (strcmp(prp->desc->prb, "exit") == 0) {
+		ctf_file_t	*cfp = dtp->dt_shared_ctf;
+		ctf_id_t	type;
+		ctf_membinfo_t	ctm;
+		int		rc = 0;
+		uint_t		lbl_out = dt_irlist_label(dlp);
+
+		emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_7, DMST_ARG(1)));
+		emit(dlp,  BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, exitlbl));
+
+		if (!cfp)
+			longjmp(yypcb->pcb_jmpbuf, EDT_NOCTF);
+		type = ctf_lookup_by_name(cfp, "struct task_struct");
+		if (type == CTF_ERR) {
+			dtp->dt_ctferr = ctf_errno(cfp);
+			longjmp(yypcb->pcb_jmpbuf, EDT_CTF);
+		}
+		rc = ctf_member_info(cfp, type, "exit_code", &ctm);
+		if (rc == CTF_ERR) {
+			dtp->dt_ctferr = ctf_errno(cfp);
+			longjmp(yypcb->pcb_jmpbuf, EDT_CTF);
+		}
+
+		/*
+		 * This implements:
+		 *	%r1 = tsk->exit_code
+		 *	if ((%r1 & 0x7f) == 0) args[0] = 1;
+		 *	else if (%r1 & 0x80) args[0] = 3;
+		 *	else args[0] = 2;
+		 */
+		emit(dlp,  BPF_MOV_REG(BPF_REG_1, BPF_REG_FP));
+		emit(dlp,  BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, DT_STK_SPILL(0)));
+		emit(dlp,  BPF_MOV_IMM(BPF_REG_2, sizeof(int)));
+		emit(dlp,  BPF_LOAD(BPF_DW, BPF_REG_3, BPF_REG_7, DMST_ARG(0)));
+		emit(dlp,  BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, ctm.ctm_offset / NBBY));
+		emit(dlp,  BPF_CALL_HELPER(BPF_FUNC_probe_read));
+		emit(dlp,  BPF_LOAD(BPF_W, BPF_REG_1, BPF_REG_FP, DT_STK_SPILL(0)));
+		emit(dlp,  BPF_MOV_IMM(BPF_REG_0, 1));
+		emit(dlp,  BPF_MOV_REG(BPF_REG_2, BPF_REG_1));
+		emit(dlp,  BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 0x7f));
+		emit(dlp,  BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_2, 0, lbl_out));
+
+		emit(dlp,  BPF_MOV_IMM(BPF_REG_0, 3));
+		emit(dlp,  BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x80));
+		emit(dlp,  BPF_BRANCH_IMM(BPF_JNE, BPF_REG_1, 0, lbl_out));
+
+		emit(dlp,  BPF_MOV_IMM(BPF_REG_0, 2));
+		emitl(dlp, lbl_out,
+			   BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
+	} else if (strcmp(prp->desc->prb, "lwp-create") == 0) {
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_7, DMST_ARG(1)));
+		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
+	} else if (strcmp(prp->desc->prb, "signal-discard") == 0) {
+		/* Pre-condition: arg4 == 1 */
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_7, DMST_ARG(4)));
+		emit(dlp, BPF_BRANCH_IMM(BPF_JNE, BPF_REG_0, 1, exitlbl));
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_7, DMST_ARG(0)));
+		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_0));
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_7, DMST_ARG(2)));
+		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
+	} else if (strcmp(prp->desc->prb, "signal-handle") == 0) {
+		/* All three arguments are already in their proper place. */
+	} else if (strcmp(prp->desc->prb, "signal-send") == 0) {
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_7, DMST_ARG(1)));
+		emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_7, DMST_ARG(0)));
+		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
+		emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_1));
+	}
+}
+
+static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
+		      int *argcp, dt_argdesc_t **argvp)
+{
+	int		i;
+	int		pidx = -1;
+	int		argc = 0;
+	dt_argdesc_t	*argv = NULL;
+
+	for (i = 0; i < ARRAY_SIZE(probe_args); i++) {
+		probe_arg_t	*arg = &probe_args[i];
+
+		if (strcmp(arg->name, prp->desc->prb) == 0) {
+			if (pidx == -1) {
+				pidx = i;
+
+				if (arg->argdesc.native == NULL)
+					break;
+			}
+
+			argc++;
+		}
+	}
+
+	if (argc == 0)
+		goto done;
+
+	argv = dt_zalloc(dtp, argc * sizeof(dt_argdesc_t));
+	if (!argv)
+		return -ENOMEM;
+
+	for (i = pidx; i < pidx + argc; i++) {
+		probe_arg_t	*arg = &probe_args[i];
+
+		argv[arg->argno] = arg->argdesc;
+	}
+
+done:
+	*argcp = argc;
+	*argvp = argv;
+
+	return 0;
+}
+
+dt_provimpl_t	dt_proc = {
+	.name		= prvname,
+	.prog_type	= BPF_PROG_TYPE_UNSPEC,
+	.populate	= &populate,
+	.enable		= &enable,
+	.trampoline	= &trampoline,
+	.probe_info	= &probe_info,
+};
diff --git a/libdtrace/dt_provider.h b/libdtrace/dt_provider.h
index 92fa7d55..5015a275 100644
--- a/libdtrace/dt_provider.h
+++ b/libdtrace/dt_provider.h
@@ -47,13 +47,9 @@ struct dt_probe;
  * to multiple args[X] variables.
  */
 typedef struct dt_argdesc {
-#ifdef FIXME
-	dtrace_id_t id;
-	int ndx;
-#endif
 	int mapping;
-	char *native;
-	char *xlate;
+	const char *native;
+	const char *xlate;
 } dt_argdesc_t;
 
 typedef struct dt_provimpl {
@@ -81,6 +77,7 @@ typedef struct dt_provimpl {
 
 extern dt_provimpl_t dt_dtrace;
 extern dt_provimpl_t dt_fbt;
+extern dt_provimpl_t dt_proc;
 extern dt_provimpl_t dt_profile;
 extern dt_provimpl_t dt_rawtp;
 extern dt_provimpl_t dt_sdt;
diff --git a/test/demo/proc/lwptime.d b/test/demo/proc/lwptime.d
index 65ede271..14f1620e 100644
--- a/test/demo/proc/lwptime.d
+++ b/test/demo/proc/lwptime.d
@@ -4,7 +4,6 @@
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
-/* @@xfail: dtv2 */
 
 proc:::lwp-start
 /tid != 1/
diff --git a/test/demo/proc/progtime.d b/test/demo/proc/progtime.d
index 6ee4d2a6..a7d9b730 100644
--- a/test/demo/proc/progtime.d
+++ b/test/demo/proc/progtime.d
@@ -4,7 +4,6 @@
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
-/* @@xfail: dtv2 */
 
 proc:::create
 {
diff --git a/test/demo/proc/sig.d b/test/demo/proc/sig.d
index 70a03b32..283de42b 100644
--- a/test/demo/proc/sig.d
+++ b/test/demo/proc/sig.d
@@ -4,7 +4,6 @@
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
-/* @@xfail: dtv2 */
 
 #pragma D option quiet
 
diff --git a/test/demo/proc/whoexec.d b/test/demo/proc/whoexec.d
index 3411e42f..4d1627c9 100644
--- a/test/demo/proc/whoexec.d
+++ b/test/demo/proc/whoexec.d
@@ -4,7 +4,6 @@
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
-/* @@xfail: dtv2 */
 
 #pragma D option quiet
 
diff --git a/test/unittest/builtinvar/tst.errno2.d b/test/unittest/builtinvar/tst.errno2.d
index 44a8c785..22fe8b4a 100644
--- a/test/unittest/builtinvar/tst.errno2.d
+++ b/test/unittest/builtinvar/tst.errno2.d
@@ -4,7 +4,6 @@
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
-/* @@xfail: dtv2 */
 
 /*
  * ASSERTION:
diff --git a/test/unittest/dtrace-util/tst.ProcInvoke.sh b/test/unittest/dtrace-util/tst.ProcInvoke.sh
index fed174f5..6def6d23 100755
--- a/test/unittest/dtrace-util/tst.ProcInvoke.sh
+++ b/test/unittest/dtrace-util/tst.ProcInvoke.sh
@@ -4,8 +4,6 @@
 # Copyright (c) 2012, 2020, 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.
-#
-# @@xfail: dtv2
 
 ##
 #
diff --git a/test/unittest/pid/tst.fork.d b/test/unittest/pid/tst.fork.d
index 0e3ecbd3..a569ddc3 100644
--- a/test/unittest/pid/tst.fork.d
+++ b/test/unittest/pid/tst.fork.d
@@ -5,7 +5,6 @@
  * http://oss.oracle.com/licenses/upl.
  */
 
-/* @@xfail: dtv2 */
 /* @@runtest-opts: $_pid */
 /* @@trigger: pid-tst-fork */
 /* @@trigger-timing: before */
diff --git a/test/unittest/pid/tst.vfork.d b/test/unittest/pid/tst.vfork.d
index 016b83b1..977a2774 100644
--- a/test/unittest/pid/tst.vfork.d
+++ b/test/unittest/pid/tst.vfork.d
@@ -4,7 +4,7 @@
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  */
-/* @@xfail: dtv2 */
+
 /* @@runtest-opts: $_pid */
 /* @@trigger: pid-tst-vfork */
 /* @@trigger-timing: before */
diff --git a/test/unittest/proc/tst.create.sh b/test/unittest/proc/tst.create.sh
index 82f0453a..9b0c2cf8 100755
--- a/test/unittest/proc/tst.create.sh
+++ b/test/unittest/proc/tst.create.sh
@@ -10,8 +10,6 @@
 #
 # If this fails, the script will run indefinitely; it relies on the harness
 # to time it out.
-#
-# @@xfail: dtv2
 
 script()
 {
diff --git a/test/unittest/proc/tst.discard.sh b/test/unittest/proc/tst.discard.sh
index 8ac82c2e..b157cf66 100755
--- a/test/unittest/proc/tst.discard.sh
+++ b/test/unittest/proc/tst.discard.sh
@@ -8,20 +8,22 @@
 # This script tests that the proc:::signal-discard probe fires correctly
 # and with the correct arguments.
 #
-# If this fails, the script will run indefinitely; it relies on the harness
-# to time it out.
-#
 # @@xfail: dtv2
 
 script()
 {
 	$dtrace $dt_flags -s /dev/stdin <<EOF
 	proc:::signal-discard
-	/args[1]->pr_pid == $child &&
-	    args[1]->pr_psargs == "$longsleep" && args[2] == SIGHUP/
+	/args[1]->pr_pid == $child && args[1]->pr_fname == "sleep" &&
+	 args[2] == SIGHUP/
 	{
 		exit(0);
 	}
+
+	tick-5s
+	{
+		exit(124);
+	}
 EOF
 }
 
diff --git a/test/unittest/proc/tst.exec.sh b/test/unittest/proc/tst.exec.sh
index 25d67c17..b9757912 100755
--- a/test/unittest/proc/tst.exec.sh
+++ b/test/unittest/proc/tst.exec.sh
@@ -10,8 +10,6 @@
 #
 # If this fails, the script will run indefinitely; it relies on the harness
 # to time it out.
-#
-# @@xfail: dtv2
 
 script()
 {
diff --git a/test/unittest/proc/tst.execfail.ENOENT.sh b/test/unittest/proc/tst.execfail.ENOENT.sh
index 4ace949e..2dcf867a 100755
--- a/test/unittest/proc/tst.execfail.ENOENT.sh
+++ b/test/unittest/proc/tst.execfail.ENOENT.sh
@@ -11,8 +11,6 @@
 #
 # If this fails, the script will run indefinitely; it relies on the harness
 # to time it out.
-#
-# @@xfail: dtv2
 
 script()
 {
diff --git a/test/unittest/proc/tst.execfail.sh b/test/unittest/proc/tst.execfail.sh
index d8b96158..8b76b51a 100755
--- a/test/unittest/proc/tst.execfail.sh
+++ b/test/unittest/proc/tst.execfail.sh
@@ -14,8 +14,6 @@
 #
 # If this fails, the script will run indefinitely; it relies on the harness
 # to time it out.
-#
-# @@xfail: dtv2
 
 script()
 {
diff --git a/test/unittest/proc/tst.exitcore.sh b/test/unittest/proc/tst.exitcore.sh
index d7ed4872..dff3fbe1 100755
--- a/test/unittest/proc/tst.exitcore.sh
+++ b/test/unittest/proc/tst.exitcore.sh
@@ -1,17 +1,12 @@
 #!/bin/bash
 #
 # Oracle Linux DTrace.
-# Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 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.
 #
 # This script tests that the proc:::exit probe fires with the correct argument
 # when the process core dumps.
-#
-# If this fails, the script will run indefinitely; it relies on the harness
-# to time it out.
-#
-# @@xfail: dtv2
 
 # Coredump to names that we can distinguish from each other: don't
 # suppress coredumps.
@@ -25,20 +20,32 @@ ulimit -c unlimited
 script()
 {
 	$dtrace $dt_flags -s /dev/stdin <<EOF
+	syscall::execve:entry
+	/copyinstr((uintptr_t)args[1][0]) == "sleep" && args[1][1] &&
+	 copyinstr((uintptr_t)args[1][1]) == "10000"/
+	{
+		core_pid = pid;
+	}
+
 	proc:::exit
-	/curpsinfo->pr_ppid == $child &&
-	    curpsinfo->pr_psargs == "$longsleep" && args[0] == CLD_DUMPED/
+	/curpsinfo->pr_ppid == $child && core_pid == pid &&
+	 args[0] == CLD_DUMPED/
 	{
 		exit(0);
 	}
 
 	proc:::exit
-	/curpsinfo->pr_ppid == $child &&
-	    curpsinfo->pr_psargs == "$longsleep" && args[0] != CLD_DUMPED/
+	/curpsinfo->pr_ppid == $child && core_pid == pid &&
+	 args[0] != CLD_DUMPED/
 	{
 		printf("Child process could not dump core.");
 		exit(1);
 	}
+
+	tick-5s
+	{
+		exit(124);
+	}
 EOF
 }
 
@@ -48,9 +55,11 @@ sleeper()
 	ulimit -c 4096
 	while true; do
 		$longsleep &
+		target=$!
 		disown %+
 		sleep 1
-		kill -SEGV $!
+		kill -SEGV $target
+		sleep 1
 	done
 }
 
diff --git a/test/unittest/proc/tst.exitexit.sh b/test/unittest/proc/tst.exitexit.sh
index 090176af..5da0a9b5 100755
--- a/test/unittest/proc/tst.exitexit.sh
+++ b/test/unittest/proc/tst.exitexit.sh
@@ -10,8 +10,6 @@
 #
 # If this fails, the script will run indefinitely; it relies on the harness
 # to time it out.
-#
-# @@xfail: dtv2
 
 script()
 {
diff --git a/test/unittest/proc/tst.startexit.sh b/test/unittest/proc/tst.startexit.sh
index cf94f52b..21510f33 100755
--- a/test/unittest/proc/tst.startexit.sh
+++ b/test/unittest/proc/tst.startexit.sh
@@ -14,8 +14,6 @@
 #
 # If this fails, the script will run indefinitely; it relies on the harness
 # to time it out.
-#
-# @@xfail: dtv2
 
 script()
 {
diff --git a/test/unittest/regression/exit_panic.d b/test/unittest/regression/exit_panic.d
index 51730482..9fc08f84 100644
--- a/test/unittest/regression/exit_panic.d
+++ b/test/unittest/regression/exit_panic.d
@@ -5,7 +5,6 @@
  * http://oss.oracle.com/licenses/upl.
  */
 
-/* @@xfail: dtv2 */
 /* @@trigger: none */
 
 #pragma D option destructive
-- 
2.39.1




More information about the DTrace-devel mailing list