[DTrace-devel] [PATCH v3] procfs: implement execargs for pr_psargs translator support
Kris Van Hees
kris.van.hees at oracle.com
Fri Jan 24 07:17:54 UTC 2025
Implement a new execargs built-in variable to provide the ps-style
argument string for the current task. It is used in the psinfo
translator for the pr_psargs member.
Due to BPF limitations, it is only possible to retrieve this information
for the current task. The data is stored in the task's address space,
and the only BPF helper that can access data in another task's address
space is not allowed to be used in non-sleepable programs (such as
tracing programs).
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
---
bpf/Build | 1 +
bpf/bvar_execargs.S | 97 +++++++++++++++++++
dlibs/aarch64/5.11/procfs.d | 4 +-
dlibs/aarch64/5.12/procfs.d | 4 +-
dlibs/aarch64/5.14/procfs.d | 4 +-
dlibs/aarch64/5.16/procfs.d | 4 +-
dlibs/aarch64/5.2/procfs.d | 4 +-
dlibs/aarch64/5.6/procfs.d | 4 +-
dlibs/aarch64/6.1/procfs.d | 4 +-
dlibs/aarch64/6.10/procfs.d | 4 +-
dlibs/x86_64/5.11/procfs.d | 5 +-
dlibs/x86_64/5.12/procfs.d | 5 +-
dlibs/x86_64/5.14/procfs.d | 5 +-
dlibs/x86_64/5.16/procfs.d | 5 +-
dlibs/x86_64/5.2/procfs.d | 5 +-
dlibs/x86_64/5.6/procfs.d | 5 +-
dlibs/x86_64/6.1/procfs.d | 5 +-
dlibs/x86_64/6.10/procfs.d | 5 +-
include/dtrace/dif_defines.h | 1 +
libdtrace/dt_bpf.h | 21 ++--
libdtrace/dt_cc.c | 33 ++++++-
libdtrace/dt_cg.c | 26 ++++-
libdtrace/dt_dlibs.c | 3 +
libdtrace/dt_open.c | 2 +
libdtrace/procfs.d.in | 5 +-
.../builtinvar/tst.psinfo-bug21974606.d | 4 +-
.../builtinvar/tst.psinfo-bug22561297.d | 8 +-
test/unittest/builtinvar/tst.psinfo.d | 8 +-
test/unittest/builtinvar/tst.psinfo1.d | 8 +-
test/unittest/proc/tst.pr_psargs.d | 36 +++++++
test/unittest/proc/tst.pr_psargs.r | 2 +
test/unittest/proc/tst.pr_psargs_other_task.d | 37 +++++++
test/unittest/proc/tst.pr_psargs_other_task.r | 9 ++
test/unittest/variables/bvar/tst.execargs.d | 23 +++++
34 files changed, 319 insertions(+), 77 deletions(-)
create mode 100644 bpf/bvar_execargs.S
create mode 100644 test/unittest/proc/tst.pr_psargs.d
create mode 100644 test/unittest/proc/tst.pr_psargs.r
create mode 100644 test/unittest/proc/tst.pr_psargs_other_task.d
create mode 100644 test/unittest/proc/tst.pr_psargs_other_task.r
create mode 100644 test/unittest/variables/bvar/tst.execargs.d
diff --git a/bpf/Build b/bpf/Build
index 3e43f4b6..a9fb100a 100644
--- a/bpf/Build
+++ b/bpf/Build
@@ -23,6 +23,7 @@ bpf_dlib_SRCDEPS = $(objdir)/include/.dir.stamp $(objdir)/include/bpf_asm_helper
bpf_dlib_SOURCES = \
agg_lqbin.c agg_qbin.c \
basename.S \
+ bvar_execargs.S \
cleanpath.S \
dirname.S \
get_agg.c \
diff --git a/bpf/bvar_execargs.S b/bpf/bvar_execargs.S
new file mode 100644
index 00000000..1c47cafb
--- /dev/null
+++ b/bpf/bvar_execargs.S
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025, Oracle and/or its affiliates.
+ */
+
+#include <bpf_asm_helpers.h>
+#include <dtrace/faults_defines.h>
+
+/*
+ * uint64_t dt_bvar_execargs(const dt_dctx_t *dctx, char *args)
+ */
+ .text
+ .align 4
+ .global dt_bvar_execargs
+ .type dt_bvar_execargs, @function
+dt_bvar_execargs:
+ stxdw [%fp+-8], %r1 /* save dctx to stack */
+ mov %r9, %r2 /* %r9 = args */
+
+ mov %r6, 0 /* set %r6 in case of error */
+ call BPF_FUNC_get_current_task /* get curthread (T) */
+ jeq %r0, 0, .Lerror
+
+ mov %r6, %r0
+ add %r6, TASK_MM /* %r6 = &(T->mm) */
+
+ mov %r1, %r9
+ mov %r2, 8
+ mov %r3, %r6
+ call BPF_FUNC_probe_read
+ jne %r0, 0, .Lerror
+
+ ldxdw %r8, [%r9+0] /* %r8 = T->mm */
+ jeq %r8, 0, .Lempty
+ mov %r6, %r8
+ add %r6, TASK_MM_ARG_START /* ptr = &(T->mm->arg_start) */
+
+ mov %r1, %r9
+ mov %r2, 8
+ mov %r3, %r6
+ call BPF_FUNC_probe_read
+ jne %r0, 0, .Lerror
+
+ ldxdw %r7, [%r9+0] /* %r7 = T->mm->arg_start */
+ mov %r6, %r8
+ add %r6, TASK_MM_ARG_END /* ptr = &(T->mm->arg_end) */
+
+ mov %r1, %r9
+ mov %r2, 8
+ mov %r3, %r6
+ call BPF_FUNC_probe_read
+ jne %r0, 0, .Lerror
+
+ ldxdw %r6, [%r9+0] /* %r6 = T->mm->arg_end */
+
+ mov %r8, %r6
+ sub %r8, %r7 /* %r8 = len = arg_end - arg_start */
+ jslt %r8, 2, .Lempty
+ mov %r0, STRSZ
+ jslt %r8, %r0, .Llen_ok
+ mov %r8, %r0
+.Llen_ok:
+
+ /* read data from arg_start to arg_end */
+ mov %r1, %r9
+ mov %r2, %r8
+ mov %r3, %r7
+ call BPF_FUNC_probe_read /* bpf_probe_read(&args, len + 1, arg_start) */
+ jne %r0, 0, .Lerror
+
+ /* loop over args and replace '\0' with ' ' */
+ mov %r1, %r8
+ sub %r1, 2
+.Lloop:
+ mov %r2, %r9
+ add %r2, %r1
+ ldxb %r0, [%r2+0]
+ jne %r0, 0, .Lnot_nil
+ stb [%r2+0], 32
+.Lnot_nil:
+ sub %r1, 1
+ jsge %r1, 0, .Lloop
+
+.Ldone:
+ mov %r0, %r9
+ exit /* return args */
+.Lerror:
+ ldxdw %r1, [%fp+-8]
+ mov %r2, PC
+ mov %r3, DTRACEFLT_BADADDR
+ mov %r4, %r6
+ call dt_probe_error
+.Lempty:
+ mov %r0, %r9
+ stb [%r9+0], 0 /* args[0] = 0 */
+ exit /* return args */
+ .size dt_bvar_execargs, .-dt_bvar_execargs
diff --git a/dlibs/aarch64/5.11/procfs.d b/dlibs/aarch64/5.11/procfs.d
index 44ec4280..70a43ddf 100644
--- a/dlibs/aarch64/5.11/procfs.d
+++ b/dlibs/aarch64/5.11/procfs.d
@@ -141,9 +141,7 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = d_execargs(T);
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/aarch64/5.12/procfs.d b/dlibs/aarch64/5.12/procfs.d
index 44ec4280..70a43ddf 100644
--- a/dlibs/aarch64/5.12/procfs.d
+++ b/dlibs/aarch64/5.12/procfs.d
@@ -141,9 +141,7 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = d_execargs(T);
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/aarch64/5.14/procfs.d b/dlibs/aarch64/5.14/procfs.d
index 584ac325..ef27bb70 100644
--- a/dlibs/aarch64/5.14/procfs.d
+++ b/dlibs/aarch64/5.14/procfs.d
@@ -141,9 +141,7 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = d_execargs(T);
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/aarch64/5.16/procfs.d b/dlibs/aarch64/5.16/procfs.d
index 5aabc6f1..cad2d2c5 100644
--- a/dlibs/aarch64/5.16/procfs.d
+++ b/dlibs/aarch64/5.16/procfs.d
@@ -141,9 +141,7 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = d_execargs(T);
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/aarch64/5.2/procfs.d b/dlibs/aarch64/5.2/procfs.d
index 683ff5a8..6b1b1b9c 100644
--- a/dlibs/aarch64/5.2/procfs.d
+++ b/dlibs/aarch64/5.2/procfs.d
@@ -141,9 +141,7 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = d_execargs(T);
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/aarch64/5.6/procfs.d b/dlibs/aarch64/5.6/procfs.d
index 44ec4280..70a43ddf 100644
--- a/dlibs/aarch64/5.6/procfs.d
+++ b/dlibs/aarch64/5.6/procfs.d
@@ -141,9 +141,7 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = d_execargs(T);
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/aarch64/6.1/procfs.d b/dlibs/aarch64/6.1/procfs.d
index 5d7873b5..4cb7b77c 100644
--- a/dlibs/aarch64/6.1/procfs.d
+++ b/dlibs/aarch64/6.1/procfs.d
@@ -141,9 +141,7 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = d_execargs(T);
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/aarch64/6.10/procfs.d b/dlibs/aarch64/6.10/procfs.d
index 5d7873b5..4cb7b77c 100644
--- a/dlibs/aarch64/6.10/procfs.d
+++ b/dlibs/aarch64/6.10/procfs.d
@@ -141,9 +141,7 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = d_execargs(T);
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/x86_64/5.11/procfs.d b/dlibs/x86_64/5.11/procfs.d
index 7274554e..f0071440 100644
--- a/dlibs/x86_64/5.11/procfs.d
+++ b/dlibs/x86_64/5.11/procfs.d
@@ -141,9 +141,8 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = T == curthread ? execargs
+ : "<unknown>";
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/x86_64/5.12/procfs.d b/dlibs/x86_64/5.12/procfs.d
index 7274554e..f0071440 100644
--- a/dlibs/x86_64/5.12/procfs.d
+++ b/dlibs/x86_64/5.12/procfs.d
@@ -141,9 +141,8 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = T == curthread ? execargs
+ : "<unknown>";
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/x86_64/5.14/procfs.d b/dlibs/x86_64/5.14/procfs.d
index d1cf90d3..17f95e5c 100644
--- a/dlibs/x86_64/5.14/procfs.d
+++ b/dlibs/x86_64/5.14/procfs.d
@@ -141,9 +141,8 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = T == curthread ? execargs
+ : "<unknown>";
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/x86_64/5.16/procfs.d b/dlibs/x86_64/5.16/procfs.d
index 5aabc6f1..f924c2a1 100644
--- a/dlibs/x86_64/5.16/procfs.d
+++ b/dlibs/x86_64/5.16/procfs.d
@@ -141,9 +141,8 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = T == curthread ? execargs
+ : "<unknown>";
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/x86_64/5.2/procfs.d b/dlibs/x86_64/5.2/procfs.d
index 35538862..36608ad0 100644
--- a/dlibs/x86_64/5.2/procfs.d
+++ b/dlibs/x86_64/5.2/procfs.d
@@ -141,9 +141,8 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = T == curthread ? execargs
+ : "<unknown>";
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/x86_64/5.6/procfs.d b/dlibs/x86_64/5.6/procfs.d
index 7274554e..f0071440 100644
--- a/dlibs/x86_64/5.6/procfs.d
+++ b/dlibs/x86_64/5.6/procfs.d
@@ -141,9 +141,8 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = T == curthread ? execargs
+ : "<unknown>";
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/x86_64/6.1/procfs.d b/dlibs/x86_64/6.1/procfs.d
index 5d7873b5..a3d7f949 100644
--- a/dlibs/x86_64/6.1/procfs.d
+++ b/dlibs/x86_64/6.1/procfs.d
@@ -141,9 +141,8 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = T == curthread ? execargs
+ : "<unknown>";
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/dlibs/x86_64/6.10/procfs.d b/dlibs/x86_64/6.10/procfs.d
index 5d7873b5..a3d7f949 100644
--- a/dlibs/x86_64/6.10/procfs.d
+++ b/dlibs/x86_64/6.10/procfs.d
@@ -141,9 +141,8 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = T == curthread ? execargs
+ : "<unknown>";
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/include/dtrace/dif_defines.h b/include/dtrace/dif_defines.h
index c8c1d961..9f6e3b55 100644
--- a/include/dtrace/dif_defines.h
+++ b/include/dtrace/dif_defines.h
@@ -162,6 +162,7 @@
#define DIF_VAR_GID 0x011f
#define DIF_VAR_ERRNO 0x0120
#define DIF_VAR_CURCPU 0x0121
+#define DIF_VAR_EXECARGS 0x0122
#define DIF_SUBR_RAND 0
#define DIF_SUBR_MUTEX_OWNED 1
diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
index 6518de66..85934d2d 100644
--- a/libdtrace/dt_bpf.h
+++ b/libdtrace/dt_bpf.h
@@ -47,15 +47,18 @@ extern "C" {
#define DT_CONST_TASK_TGID 12
#define DT_CONST_TASK_REAL_PARENT 13
#define DT_CONST_TASK_COMM 14
-#define DT_CONST_MUTEX_OWNER 15
-#define DT_CONST_RWLOCK_CNTS 16
-#define DT_CONST_DCTX_RODATA 17
-#define DT_CONST_RODATA_OFF 18
-#define DT_CONST_RODATA_SIZE 19
-#define DT_CONST_ZERO_OFF 20
-#define DT_CONST_STACK_OFF 21
-#define DT_CONST_STACK_SKIP 22
-#define DT_CONST_NPROBES 23
+#define DT_CONST_TASK_MM 15
+#define DT_CONST_TASK_MM_ARG_START 16
+#define DT_CONST_TASK_MM_ARG_END 17
+#define DT_CONST_MUTEX_OWNER 18
+#define DT_CONST_RWLOCK_CNTS 19
+#define DT_CONST_DCTX_RODATA 20
+#define DT_CONST_RODATA_OFF 21
+#define DT_CONST_RODATA_SIZE 22
+#define DT_CONST_ZERO_OFF 23
+#define DT_CONST_STACK_OFF 24
+#define DT_CONST_STACK_SKIP 25
+#define DT_CONST_NPROBES 26
#define DT_BPF_LOG_SIZE_DEFAULT (UINT32_MAX >> 8)
#define DT_BPF_LOG_SIZE_SMALL 4096
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index 29cfbd84..1dc119ea 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -1082,7 +1082,8 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
case DT_CONST_TASK_PID:
case DT_CONST_TASK_TGID:
case DT_CONST_TASK_REAL_PARENT:
- case DT_CONST_TASK_COMM: {
+ case DT_CONST_TASK_COMM:
+ case DT_CONST_TASK_MM: {
ctf_file_t *cfp = dtp->dt_shared_ctf;
ctf_id_t type;
ctf_membinfo_t ctm;
@@ -1108,6 +1109,36 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
case DT_CONST_TASK_COMM:
rc = ctf_member_info(cfp, type, "comm", &ctm);
break;
+ case DT_CONST_TASK_MM:
+ rc = ctf_member_info(cfp, type, "mm", &ctm);
+ break;
+ }
+ if (rc == CTF_ERR)
+ goto err_ctf;
+ nrp->dofr_data = ctm.ctm_offset / NBBY;
+ continue;
+ }
+ case DT_CONST_TASK_MM_ARG_START:
+ case DT_CONST_TASK_MM_ARG_END: {
+ ctf_file_t *cfp = dtp->dt_shared_ctf;
+ ctf_id_t type;
+ ctf_membinfo_t ctm;
+ int rc = 0;
+
+ if (!cfp)
+ return dt_set_errno(dtp, EDT_NOCTF);
+
+ type = ctf_lookup_by_name(cfp, "struct mm_struct");
+ if (type == CTF_ERR)
+ goto err_ctf;
+
+ switch (idp->di_id) {
+ case DT_CONST_TASK_MM_ARG_START:
+ rc = ctf_member_info(cfp, type, "arg_start", &ctm);
+ break;
+ case DT_CONST_TASK_MM_ARG_END:
+ rc = ctf_member_info(cfp, type, "arg_end", &ctm);
+ break;
}
if (rc == CTF_ERR)
goto err_ctf;
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index b48e27f0..5268e900 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -3341,7 +3341,6 @@ dt_cg_load_var(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
}
/* built-in variables (note: args[] is handled in dt_cg_array_op) */
- /* Special case for arg0 through arg9; encode as args[n] */
if (idp->di_id >= DIF_VAR_ARG0 && idp->di_id <= DIF_VAR_ARG9) {
fnp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_bvar_args");
idx = idp->di_id - DIF_VAR_ARG0;
@@ -3351,6 +3350,31 @@ dt_cg_load_var(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
idp->di_id == DIF_VAR_PROBENAME) {
fnp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_bvar_probedesc");
idx = idp->di_id;
+ } else if (idp->di_id == DIF_VAR_EXECARGS) {
+ fnp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_bvar_execargs");
+ assert(fnp != NULL);
+
+ if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ dt_cg_tstring_alloc(yypcb, dnp);
+
+ if (dt_regset_xalloc_args(drp) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+
+ dt_cg_access_dctx(BPF_REG_1, dlp, drp, -1);
+ emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_2, BPF_REG_1, DCTX_MEM));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, dnp->dn_tstring->dn_value));
+ dt_regset_xalloc(drp, BPF_REG_0);
+ emite(dlp, BPF_CALL_FUNC(fnp->di_id), fnp);
+ dt_regset_free_args(drp);
+
+ dt_cg_check_fault(yypcb);
+
+ emit(dlp, BPF_MOV_REG(dnp->dn_reg, BPF_REG_0));
+ dt_regset_free(drp, BPF_REG_0);
+
+ return;
} else {
char *fn;
diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
index 07d22afd..9ad4f5e7 100644
--- a/libdtrace/dt_dlibs.c
+++ b/libdtrace/dt_dlibs.c
@@ -89,6 +89,9 @@ static const dt_ident_t dt_bpf_symbols[] = {
DT_BPF_SYMBOL_ID(TASK_TGID, DT_IDENT_SCALAR, DT_CONST_TASK_TGID),
DT_BPF_SYMBOL_ID(TASK_REAL_PARENT, DT_IDENT_SCALAR, DT_CONST_TASK_REAL_PARENT),
DT_BPF_SYMBOL_ID(TASK_COMM, DT_IDENT_SCALAR, DT_CONST_TASK_COMM),
+ DT_BPF_SYMBOL_ID(TASK_MM, DT_IDENT_SCALAR, DT_CONST_TASK_MM),
+ DT_BPF_SYMBOL_ID(TASK_MM_ARG_START, DT_IDENT_SCALAR, DT_CONST_TASK_MM_ARG_START),
+ DT_BPF_SYMBOL_ID(TASK_MM_ARG_END, DT_IDENT_SCALAR, DT_CONST_TASK_MM_ARG_END),
DT_BPF_SYMBOL_ID(MUTEX_OWNER, DT_IDENT_SCALAR, DT_CONST_MUTEX_OWNER),
DT_BPF_SYMBOL_ID(RWLOCK_CNTS, DT_IDENT_SCALAR, DT_CONST_RWLOCK_CNTS),
DT_BPF_SYMBOL_ID(DCTX_RODATA, DT_IDENT_SCALAR, DT_CONST_DCTX_RODATA),
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index a0205887..51c056b2 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -153,6 +153,8 @@ static const dt_ident_t _dtrace_globals[] = {
&dt_idops_type, "uint64_t" },
{ "errno", DT_IDENT_SCALAR, 0, DIF_VAR_ERRNO, DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_type, "int" },
+{ "execargs", DT_IDENT_SCALAR, 0, DIF_VAR_EXECARGS,
+ DT_ATTR_STABCMN, DT_VERS_2_0, &dt_idops_type, "string" },
{ "execname", DT_IDENT_SCALAR, 0, DIF_VAR_EXECNAME,
DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
{ "exit", DT_IDENT_ACTFUNC, 0, DT_ACT_EXIT, DT_ATTR_STABCMN, DT_VERS_1_0,
diff --git a/libdtrace/procfs.d.in b/libdtrace/procfs.d.in
index 038cf69b..adcb1889 100644
--- a/libdtrace/procfs.d.in
+++ b/libdtrace/procfs.d.in
@@ -179,9 +179,8 @@ translator psinfo_t < struct task_struct *T > {
: (struct tty_struct *)-1;
pr_fname = T->comm;
-/*
- pr_psargs = stringof(get_psinfo(T)->__psinfo(psargs));
- */
+ pr_psargs = T == curthread ? execargs
+ : "<unknown>";
pr_wstat = 0;
/*
pr_argc = get_psinfo(T)->__psinfo(argc);
diff --git a/test/unittest/builtinvar/tst.psinfo-bug21974606.d b/test/unittest/builtinvar/tst.psinfo-bug21974606.d
index 68d9503d..67fea54e 100644
--- a/test/unittest/builtinvar/tst.psinfo-bug21974606.d
+++ b/test/unittest/builtinvar/tst.psinfo-bug21974606.d
@@ -4,11 +4,9 @@
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
-/* @@xfail: dtv2 */
/*
- * ASSERTION:
- * To ensure pr_psargs does not have an (extra) trailing space.
+ * ASSERTION: To ensure pr_psargs does not have an (extra) trailing space.
*
* SECTION: Variables/Built-in Variables
*/
diff --git a/test/unittest/builtinvar/tst.psinfo-bug22561297.d b/test/unittest/builtinvar/tst.psinfo-bug22561297.d
index b9efd0ec..5a9fe333 100644
--- a/test/unittest/builtinvar/tst.psinfo-bug22561297.d
+++ b/test/unittest/builtinvar/tst.psinfo-bug22561297.d
@@ -4,11 +4,9 @@
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
-/* @@xfail: dtv2 */
/*
- * ASSERTION:
- * To print psinfo structure values from profile.
+ * ASSERTION: To print psinfo structure values from profile.
*
* SECTION: Variables/Built-in Variables
*/
@@ -32,12 +30,14 @@ tick-10ms
printf("address of process = %p\n", curpsinfo->pr_addr);
printf("address of controlling tty = %p\n", curpsinfo->pr_ttydev);
printf("process name = %s\n", curpsinfo->pr_fname);
- /* These are still getting faked */
printf("initial chars of arg list = %s\n", curpsinfo->pr_psargs);
printf("wait status for zombie = %d\n", curpsinfo->pr_wstat);
+/*
+ * These are not implemented yet.
printf("initial argument count = %d\n", curpsinfo->pr_argc);
printf("initial argument vector = %p\n", curpsinfo->pr_argv);
printf("initial environment vector = %p\n", curpsinfo->pr_envp);
+ */
printf("process data model = %d\n", curpsinfo->pr_dmodel);
printf("task id = %d\n", curpsinfo->pr_taskid);
printf("project id = %d\n", curpsinfo->pr_projid);
diff --git a/test/unittest/builtinvar/tst.psinfo.d b/test/unittest/builtinvar/tst.psinfo.d
index 92f91de7..09bcce86 100644
--- a/test/unittest/builtinvar/tst.psinfo.d
+++ b/test/unittest/builtinvar/tst.psinfo.d
@@ -4,11 +4,9 @@
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
-/* @@xfail: dtv2 */
/*
- * ASSERTION:
- * To print psinfo structure values from profile.
+ * ASSERTION: To print psinfo structure values from profile.
*
* SECTION: Variables/Built-in Variables
*/
@@ -31,12 +29,14 @@ tick-10ms
printf("address of process = %p\n", curpsinfo->pr_addr);
printf("address of controlling tty = %p\n", curpsinfo->pr_ttydev);
printf("process name = %s\n", curpsinfo->pr_fname);
- /* These are still getting faked */
printf("initial chars of arg list = %s\n", curpsinfo->pr_psargs);
printf("wait status for zombie = %d\n", curpsinfo->pr_wstat);
+/*
+ * These are not implemented yet.
printf("initial argument count = %d\n", curpsinfo->pr_argc);
printf("initial argument vector = %p\n", curpsinfo->pr_argv);
printf("initial environment vector = %p\n", curpsinfo->pr_envp);
+ */
printf("process data model = %d\n", curpsinfo->pr_dmodel);
printf("task id = %d\n", curpsinfo->pr_taskid);
printf("project id = %d\n", curpsinfo->pr_projid);
diff --git a/test/unittest/builtinvar/tst.psinfo1.d b/test/unittest/builtinvar/tst.psinfo1.d
index 9e6d5053..be9e251c 100644
--- a/test/unittest/builtinvar/tst.psinfo1.d
+++ b/test/unittest/builtinvar/tst.psinfo1.d
@@ -4,11 +4,9 @@
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
-/* @@xfail: dtv2 */
/*
- * ASSERTION:
- * To print psinfo structure values.
+ * ASSERTION: To print psinfo structure values.
*
* SECTION: Variables/Built-in Variables
*/
@@ -29,12 +27,14 @@ BEGIN
printf("address of process = %p\n", curpsinfo->pr_addr);
printf("address of controlling tty = %p\n", curpsinfo->pr_ttydev);
printf("process name = %s\n", curpsinfo->pr_fname);
- /* These are still getting faked */
printf("initial chars of arg list = %s\n", curpsinfo->pr_psargs);
printf("wait status for zombie = %d\n", curpsinfo->pr_wstat);
+/*
+ * These are not implemented yet.
printf("initial argument count = %d\n", curpsinfo->pr_argc);
printf("initial argument vector = %p\n", curpsinfo->pr_argv);
printf("initial environment vector = %p\n", curpsinfo->pr_envp);
+ */
printf("process data model = %d\n", curpsinfo->pr_dmodel);
printf("task id = %d\n", curpsinfo->pr_taskid);
printf("project id = %d\n", curpsinfo->pr_projid);
diff --git a/test/unittest/proc/tst.pr_psargs.d b/test/unittest/proc/tst.pr_psargs.d
new file mode 100644
index 00000000..5c4995ad
--- /dev/null
+++ b/test/unittest/proc/tst.pr_psargs.d
@@ -0,0 +1,36 @@
+/*
+ * 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: psinfo->pr_psargs provides correct results.
+ */
+
+#pragma D option destructive
+#pragma D option quiet
+
+BEGIN
+{
+ mypid = pid;
+ system("/bin/echo TEST a b c ");
+}
+
+proc:::exec-success
+/progenyof(mypid) && curpsinfo->pr_psargs == "/bin/echo TEST a b c"/
+{
+ trace(curpsinfo->pr_psargs);
+ exit(0);
+}
+
+tick-1s
+{
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/test/unittest/proc/tst.pr_psargs.r b/test/unittest/proc/tst.pr_psargs.r
new file mode 100644
index 00000000..bbfe6074
--- /dev/null
+++ b/test/unittest/proc/tst.pr_psargs.r
@@ -0,0 +1,2 @@
+TEST a b c
+/bin/echo TEST a b c
diff --git a/test/unittest/proc/tst.pr_psargs_other_task.d b/test/unittest/proc/tst.pr_psargs_other_task.d
new file mode 100644
index 00000000..040a7864
--- /dev/null
+++ b/test/unittest/proc/tst.pr_psargs_other_task.d
@@ -0,0 +1,37 @@
+/*
+ * 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: psinfo->pr_psargs is only implemented for curthread
+ */
+
+#pragma D option destructive
+#pragma D option quiet
+
+BEGIN
+{
+ mypid = pid;
+ tsk = curthread;
+ system("/bin/echo TEST a b c ");
+}
+
+proc:::exec-success
+/progenyof(mypid) && curpsinfo->pr_psargs == "/bin/echo TEST a b c"/
+{
+ trace(xlate < psinfo_t > (tsk).pr_psargs);
+ exit(0);
+}
+
+tick-1s
+{
+ exit(1);
+}
+
+ERROR
+{
+ exit(1);
+}
diff --git a/test/unittest/proc/tst.pr_psargs_other_task.r b/test/unittest/proc/tst.pr_psargs_other_task.r
new file mode 100644
index 00000000..ed0aafb2
--- /dev/null
+++ b/test/unittest/proc/tst.pr_psargs_other_task.r
@@ -0,0 +1,9 @@
+TEST a b c
+
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
+ 0: 3c 75 6e 6b 6e 6f 77 6e 3e 00 00 00 00 00 00 00 <unknown>.......
+ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+
diff --git a/test/unittest/variables/bvar/tst.execargs.d b/test/unittest/variables/bvar/tst.execargs.d
new file mode 100644
index 00000000..d4eac223
--- /dev/null
+++ b/test/unittest/variables/bvar/tst.execargs.d
@@ -0,0 +1,23 @@
+/*
+ * 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: The 'execargs' variable value can be retrieved.
+ *
+ * SECTION: Variables/Built-in Variables/execargs
+ */
+
+#pragma D option quiet
+
+BEGIN {
+ trace(execargs);
+ exit(0);
+}
+
+ERROR {
+ exit(1);
+}
--
2.45.2
More information about the DTrace-devel
mailing list