[DTrace-devel] [PATCH 1/2] Add support for progenyof() subroutine
eugene.loh at oracle.com
eugene.loh at oracle.com
Thu Feb 17 20:45:30 UTC 2022
From: Eugene Loh <eugene.loh at oracle.com>
Also, clean up err*progeny*.d tests. In particular,
*) err.D_FUNC_UNDEF.progenyofbad1.d was failing because it had always
been wrong: the test was mislabeled. The test was introduced in patch
c17a42e11dba "Add the OpenSolaris dtrace testsuite."
with a .r results file that explicitly indicates D_PROTO_LEN,
even though the test name expects D_FUNC_UNDEF. However, runtest.sh
did not check the error tag. Though runtest.sh was eventually fixed,
the test fail was simply dismissed XFAIL.
*) err.D_PROTO_LEN.progenyofbad2.d was passing, but for reasons unrelated
to progenyof() or its argument checks. The test used progenyof(trace())
and therefore did not test progenyof() at all; rather, it failed on
trace(), which is missing its argument.
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
bpf/Build | 1 +
bpf/progenyof.S | 88 +++++++++++++++++++
libdtrace/dt_bpf.h | 2 +
libdtrace/dt_cc.c | 26 ++++++
libdtrace/dt_cg.c | 30 ++++++-
libdtrace/dt_dlibs.c | 2 +
.../funcs/err.D_FUNC_UNDEF.progenyofbad1.r | 2 -
...bad2.d => err.D_PROTO_ARG.progenyofbad1.d} | 11 +--
.../funcs/err.D_PROTO_ARG.progenyofbad1.r | 4 +
.../funcs/err.D_PROTO_ARG.progenyofbad2.d | 18 ++++
.../funcs/err.D_PROTO_ARG.progenyofbad2.r | 4 +
.../funcs/err.D_PROTO_LEN.progenyofbad2.r | 2 -
.../funcs/err.D_PROTO_LEN.progenyoftoofew.d | 18 ++++
.../funcs/err.D_PROTO_LEN.progenyoftoofew.r | 2 +
...1.d => err.D_PROTO_LEN.progenyoftoomany.d} | 10 +--
.../funcs/err.D_PROTO_LEN.progenyoftoomany.r | 2 +
test/unittest/funcs/tst.progenyof.d | 3 +-
17 files changed, 203 insertions(+), 22 deletions(-)
create mode 100644 bpf/progenyof.S
delete mode 100644 test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.r
rename test/unittest/funcs/{err.D_PROTO_LEN.progenyofbad2.d => err.D_PROTO_ARG.progenyofbad1.d} (55%)
create mode 100644 test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.r
create mode 100644 test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d
create mode 100644 test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.r
delete mode 100644 test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.r
create mode 100644 test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d
create mode 100644 test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.r
rename test/unittest/funcs/{err.D_FUNC_UNDEF.progenyofbad1.d => err.D_PROTO_LEN.progenyoftoomany.d} (59%)
create mode 100644 test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.r
diff --git a/bpf/Build b/bpf/Build
index 69a2e4d4..5cf9c45f 100644
--- a/bpf/Build
+++ b/bpf/Build
@@ -30,6 +30,7 @@ bpf_dlib_SOURCES = \
index.S \
inet_ntoa.S \
lltostr.S \
+ progenyof.S \
probe_error.c \
rindex.S \
speculation.c \
diff --git a/bpf/progenyof.S b/bpf/progenyof.S
new file mode 100644
index 00000000..e17eaa98
--- /dev/null
+++ b/bpf/progenyof.S
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#define BPF_FUNC_probe_read 4
+#define BPF_FUNC_get_current_task 35
+
+ .text
+ .align 4
+ .global dt_progenyof
+ .type dt_progenyof, @function
+dt_progenyof:
+#define ARG %r6
+#define CNT %r7
+#define PTR %r8
+#define VAL %r9
+
+ /* uint64_t dt_progenyof(pid_t arg); */
+ mov ARG, %r1
+ lsh ARG, 32
+ rsh ARG, 32
+
+ /* assure the BPF verifier there is no infinite loop */
+ mov CNT, 256
+
+ /* ptr = bpf_get_current_task() */
+ call BPF_FUNC_get_current_task
+ mov PTR, %r0
+
+.Lloop:
+ /* if (ptr == 0) goto Lret0 */
+ jeq PTR, 0, .Lret0
+
+ /* if (count <= 0) goto Lret0 */
+ jsle CNT, 0, .Lret0
+
+ /* val = *((uint32_t *)(ptr + TASK_PID)), using [%fp+-8] as temp */
+ mov %r1, %fp
+ add %r1, -8
+ mov %r2, 4
+ lddw %r3, TASK_PID
+ add %r3, PTR
+ call BPF_FUNC_probe_read
+ jne %r0, 0, .Lret0
+ ldxw VAL, [%fp+-8]
+ lsh VAL, 32
+ rsh VAL, 32
+
+ /* if (val == arg) goto Lret1 */
+ jeq VAL, ARG, .Lret1
+
+ /* val = *((uint64_t *)(ptr + TASK_REAL_PARENT)), using [%fp+-8] as temp */
+ mov %r1, %fp
+ add %r1, -8
+ mov %r2, 8
+ lddw %r3, TASK_REAL_PARENT
+ add %r3, PTR
+ call BPF_FUNC_probe_read
+ jne %r0, 0, .Lret0
+ ldxdw VAL, [%fp+-8]
+
+ /* if (val == ptr) goto Lret0 */
+ jeq VAL, PTR, .Lret0
+
+ /* ptr = val */
+ mov PTR, VAL
+
+ /* count-- */
+ sub CNT, 1
+
+ /* goto Lloop */
+ ja .Lloop
+
+.Lret0:
+ /* return 0 */
+ mov %r0, 0
+ exit
+
+.Lret1:
+ /* return 1 */
+ mov %r0, 1
+ exit
+ .size dt_progenyof, .-dt_progenyof
+#undef ARG
+#undef CNT
+#undef PTR
+#undef VAL
diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
index 5b9bae80..e361d103 100644
--- a/libdtrace/dt_bpf.h
+++ b/libdtrace/dt_bpf.h
@@ -28,6 +28,8 @@ extern "C" {
#define DT_CONST_BOOTTM 8
#define DT_CONST_NSPEC 9
#define DT_CONST_NCPUS 10
+#define DT_CONST_TASK_REAL_PARENT 11
+#define DT_CONST_TASK_PID 12
extern int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
int group_fd, unsigned long flags);
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index ce824eb5..f5b59109 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -2367,6 +2367,32 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
return -1;
nrp->dofr_data = boottime;
continue;
+ case DT_CONST_TASK_REAL_PARENT: {
+ ctf_file_t *cfp = dtp->dt_shared_ctf;
+ ctf_id_t type = ctf_lookup_by_name(cfp, "struct task_struct");
+ ctf_membinfo_t ctm;
+
+ if (type == CTF_ERR)
+ return -1;
+
+ if (ctf_member_info(cfp, type, "real_parent", &ctm) == CTF_ERR)
+ return -1;
+ nrp->dofr_data = ctm.ctm_offset / NBBY;
+ continue;
+ }
+ case DT_CONST_TASK_PID: {
+ ctf_file_t *cfp = dtp->dt_shared_ctf;
+ ctf_id_t type = ctf_lookup_by_name(cfp, "struct task_struct");
+ ctf_membinfo_t ctm;
+
+ if (type == CTF_ERR)
+ return -1;
+
+ if (ctf_member_info(cfp, type, "pid", &ctm) == CTF_ERR)
+ return -1;
+ nrp->dofr_data = ctm.ctm_offset / NBBY;
+ continue;
+ }
default:
/* probe name -> value is probe id */
if (strchr(idp->di_name, ':') != NULL)
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index ef04fafd..30f9705f 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -3499,6 +3499,34 @@ dt_cg_subr_lltostr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
TRACE_REGSET(" subr-lltostr:End ");
}
+static void
+dt_cg_subr_progenyof(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
+{
+ dt_ident_t *idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_progenyof");
+ dt_node_t *arg = dnp->dn_args;
+
+ assert(idp != NULL);
+
+ TRACE_REGSET(" subr-progenyof:Begin");
+ dt_cg_node(arg, dlp, drp);
+
+ if (dt_regset_xalloc_args(drp) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ emit(dlp, BPF_MOV_REG(BPF_REG_1, arg->dn_reg));
+ dt_regset_free(drp, arg->dn_reg);
+ dt_regset_xalloc(drp, BPF_REG_0);
+ emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
+ dt_regset_free_args(drp);
+
+ dnp->dn_reg = dt_regset_alloc(drp);
+ if (dnp->dn_reg == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ emit(dlp, BPF_MOV_REG(dnp->dn_reg, BPF_REG_0));
+ dt_regset_free(drp, BPF_REG_0);
+
+ TRACE_REGSET(" subr-progenyof:End ");
+}
+
static void
dt_cg_subr_rand(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
{
@@ -4137,7 +4165,7 @@ static dt_cg_subr_f *_dt_cg_subr[DIF_SUBR_MAX + 1] = {
[DIF_SUBR_COPYIN] = NULL,
[DIF_SUBR_COPYINSTR] = NULL,
[DIF_SUBR_SPECULATION] = &dt_cg_subr_speculation,
- [DIF_SUBR_PROGENYOF] = NULL,
+ [DIF_SUBR_PROGENYOF] = &dt_cg_subr_progenyof,
[DIF_SUBR_STRLEN] = &dt_cg_subr_strlen,
[DIF_SUBR_COPYOUT] = NULL,
[DIF_SUBR_COPYOUTSTR] = NULL,
diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
index ebed0509..a8d112d4 100644
--- a/libdtrace/dt_dlibs.c
+++ b/libdtrace/dt_dlibs.c
@@ -79,6 +79,8 @@ static const dt_ident_t dt_bpf_symbols[] = {
DT_BPF_SYMBOL_ID(BOOTTM, DT_IDENT_SCALAR, DT_CONST_BOOTTM),
DT_BPF_SYMBOL_ID(NSPEC, DT_IDENT_SCALAR, DT_CONST_NSPEC),
DT_BPF_SYMBOL_ID(NCPUS, DT_IDENT_SCALAR, DT_CONST_NCPUS),
+ DT_BPF_SYMBOL_ID(TASK_REAL_PARENT, DT_IDENT_SCALAR, DT_CONST_TASK_REAL_PARENT),
+ DT_BPF_SYMBOL_ID(TASK_PID, DT_IDENT_SCALAR, DT_CONST_TASK_PID),
/* End-of-list marker */
{ NULL, }
diff --git a/test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.r b/test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.r
deleted file mode 100644
index e7a64031..00000000
--- a/test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.r
+++ /dev/null
@@ -1,2 +0,0 @@
--- @@stderr --
-dtrace: failed to compile script test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.d: [D_PROTO_LEN] line 19: progenyof( ) prototype mismatch: 2 args passed, 1 expected
diff --git a/test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.d b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.d
similarity index 55%
rename from test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.d
rename to test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.d
index 033b3d54..4a00d08f 100644
--- a/test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.d
+++ b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.d
@@ -1,23 +1,18 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 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:
- * progenyof() should return an error if the argument is an
- * incorrect type.
+ * ASSERTION: progenyof() should take a pid_t argument.
*
* SECTION: Actions and Subroutines/progenyof()
- *
*/
-
BEGIN
{
- progenyof(trace());
+ progenyof("some_string");
exit(0);
}
-
diff --git a/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.r b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.r
new file mode 100644
index 00000000..158eee85
--- /dev/null
+++ b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.r
@@ -0,0 +1,4 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.d: [D_PROTO_ARG] line 16: progenyof( ) argument #1 is incompatible with prototype:
+ prototype: pid_t
+ argument: string
diff --git a/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d
new file mode 100644
index 00000000..67735b79
--- /dev/null
+++ b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d
@@ -0,0 +1,18 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2007, 2022, 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: progenyof() should take a pid_t argument.
+ *
+ * SECTION: Actions and Subroutines/progenyof()
+ */
+
+BEGIN
+{
+ progenyof(trace(1));
+ exit(0);
+}
diff --git a/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.r b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.r
new file mode 100644
index 00000000..73dec003
--- /dev/null
+++ b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.r
@@ -0,0 +1,4 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d: [D_PROTO_ARG] line 16: progenyof( ) argument #1 is incompatible with prototype:
+ prototype: pid_t
+ argument: void
diff --git a/test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.r b/test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.r
deleted file mode 100644
index 35145323..00000000
--- a/test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.r
+++ /dev/null
@@ -1,2 +0,0 @@
--- @@stderr --
-dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.d: [D_PROTO_LEN] line 20: trace( ) prototype mismatch: 0 args passed, 1 expected
diff --git a/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d
new file mode 100644
index 00000000..96bf8b4d
--- /dev/null
+++ b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d
@@ -0,0 +1,18 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2022, 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: progenyof() should take one argument.
+ *
+ * SECTION: Actions and Subroutines/progenyof()
+ */
+
+BEGIN
+{
+ progenyof();
+ exit(0);
+}
diff --git a/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.r b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.r
new file mode 100644
index 00000000..e31d0be3
--- /dev/null
+++ b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.r
@@ -0,0 +1,2 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d: [D_PROTO_LEN] line 16: progenyof( ) prototype mismatch: 0 args passed, 1 expected
diff --git a/test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.d b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.d
similarity index 59%
rename from test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.d
rename to test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.d
index dca7f283..2d4d922a 100644
--- a/test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.d
+++ b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.d
@@ -1,22 +1,18 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2022, 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 */
+
/*
- * ASSERTION:
- * progenyof() should accept one argument - a pid
+ * ASSERTION: progenyof() should take one argument.
*
* SECTION: Actions and Subroutines/progenyof()
- *
*/
-
BEGIN
{
progenyof(1, 2);
exit(0);
}
-
diff --git a/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.r b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.r
new file mode 100644
index 00000000..46b4f985
--- /dev/null
+++ b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.r
@@ -0,0 +1,2 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.d: [D_PROTO_LEN] line 16: progenyof( ) prototype mismatch: 2 args passed, 1 expected
diff --git a/test/unittest/funcs/tst.progenyof.d b/test/unittest/funcs/tst.progenyof.d
index cadeb654..9d73420f 100644
--- a/test/unittest/funcs/tst.progenyof.d
+++ b/test/unittest/funcs/tst.progenyof.d
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2022, 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.
*/
@@ -14,7 +14,6 @@
*
*/
-/* @@xfail: dtv2 */
/* @@trigger: pid-tst-float */
#pragma D option quiet
--
2.18.4
More information about the DTrace-devel
mailing list