[DTrace-devel] [PATCH v3] Implement the ppid builtin D variable
eugene.loh at oracle.com
eugene.loh at oracle.com
Thu Sep 17 13:14:34 PDT 2020
From: Eugene Loh <eugene.loh at oracle.com>
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
bpf/get_bvar.c | 36 ++++++++++++++++++++++++
libdtrace/dt_bpf.c | 26 +++++++++++++++++
libdtrace/dt_state.h | 5 ++++
test/unittest/variables/bvar/tst.ppid.d | 1 -
test/unittest/variables/bvar/tst.ppid2.d | 20 +++++++++++++
5 files changed, 87 insertions(+), 1 deletion(-)
create mode 100644 test/unittest/variables/bvar/tst.ppid2.d
diff --git a/bpf/get_bvar.c b/bpf/get_bvar.c
index 0cac46d5..8d595efb 100644
--- a/bpf/get_bvar.c
+++ b/bpf/get_bvar.c
@@ -9,12 +9,14 @@
#include <dtrace/conf.h>
#include <dtrace/dif_defines.h>
#include <dt_dctx.h>
+#include <dt_state.h>
#ifndef noinline
# define noinline __attribute__((noinline))
#endif
extern struct bpf_map_def cpuinfo;
+extern struct bpf_map_def state;
noinline uint64_t dt_get_bvar(dt_mstate_t *mst, uint32_t id)
{
@@ -47,6 +49,40 @@ noinline uint64_t dt_get_bvar(dt_mstate_t *mst, uint32_t id)
return val & 0x00000000ffffffffUL;
}
+ case DIF_VAR_PPID: {
+ uint64_t ptr;
+ int32_t val = -1;
+ uint32_t key;
+ uint32_t *parent_off;
+ uint32_t *tgid_off;
+
+ /*
+ * In the "state" map, look up the "struct task_struct" offsets
+ * of real_parent and tgid.
+ */
+ key = DT_STATE_TASK_PARENT_OFF;
+ parent_off = bpf_map_lookup_elem(&state, &key);
+ if (parent_off == NULL)
+ return -1;
+
+ key = DT_STATE_TASK_TGID_OFF;
+ tgid_off = bpf_map_lookup_elem(&state, &key);
+ if (tgid_off == NULL)
+ return -1;
+
+ /* Chase pointers val = current->real_parent->tgid. */
+ ptr = bpf_get_current_task();
+ if (ptr == 0)
+ return -1;
+ if (bpf_probe_read((void *) &ptr, 8,
+ (const void *) (ptr + *parent_off)))
+ return -1;
+ if (bpf_probe_read((void *) &val, 4,
+ (const void *) (ptr + *tgid_off)))
+ return -1;
+
+ return (uint64_t) val;
+ }
case DIF_VAR_UID: {
uint64_t val = bpf_get_current_uid_gid();
diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
index 4e0cdc91..736b3318 100644
--- a/libdtrace/dt_bpf.c
+++ b/libdtrace/dt_bpf.c
@@ -115,6 +115,28 @@ create_gmap(dtrace_hdl_t *dtp, const char *name, enum bpf_map_type type,
return fd;
}
+static int
+set_task_offsets(dtrace_hdl_t *dtp)
+{
+ ctf_id_t type;
+ ctf_membinfo_t ctm;
+ ctf_file_t *cfp = dtp->dt_shared_ctf;
+
+ type = ctf_lookup_by_name(cfp, "struct task_struct");
+ if (type == CTF_ERR)
+ return -1;
+
+ if (ctf_member_info(cfp, type, "real_parent", &ctm) == CTF_ERR)
+ return -1;
+ dt_state_set_offparent(dtp, ctm.ctm_offset / NBBY);
+
+ if (ctf_member_info(cfp, type, "tgid", &ctm) == CTF_ERR)
+ return -1;
+ dt_state_set_offtgid(dtp, ctm.ctm_offset / NBBY);
+
+ return 0;
+}
+
/*
* Create the global BPF maps that are shared between all BPF programs in a
* single tracing session:
@@ -225,6 +247,10 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)
/* Populate the 'cpuinfo' map. */
dt_bpf_map_update(ci_mapfd, &key, dtp->dt_conf.cpus);
+ /* Set some task_struct offsets in state. */
+ if (set_task_offsets(dtp))
+ return dt_set_errno(dtp, EDT_CTF);
+
return 0;
}
diff --git a/libdtrace/dt_state.h b/libdtrace/dt_state.h
index c6500dca..ed6f2030 100644
--- a/libdtrace/dt_state.h
+++ b/libdtrace/dt_state.h
@@ -21,6 +21,8 @@ typedef enum dt_state_elem {
DT_STATE_ACTIVITY = 0, /* activity state of the session */
DT_STATE_BEGANON, /* cpu BEGIN probe executed on */
DT_STATE_ENDEDON, /* cpu END probe executed on */
+ DT_STATE_TASK_PARENT_OFF, /* offsetof(struct task_struct, real_parent) */
+ DT_STATE_TASK_TGID_OFF, /* offsetof(struct task_struct, tgid) */
DT_STATE_NUM_ELEMS
} dt_state_elem_t;
@@ -61,6 +63,9 @@ dt_state_set(dtrace_hdl_t *dtp, uint32_t key, uint32_t val)
# define dt_state_get_beganon(dtp) dt_state_get(dtp, DT_STATE_BEGANON)
# define dt_state_get_endedon(dtp) dt_state_get(dtp, DT_STATE_ENDEDON)
+
+# define dt_state_set_offparent(dtp, x) dt_state_set(dtp, DT_STATE_TASK_PARENT_OFF, (x))
+# define dt_state_set_offtgid(dtp, x) dt_state_set(dtp, DT_STATE_TASK_TGID_OFF, (x))
#endif
#endif /* _DT_STATE_H */
diff --git a/test/unittest/variables/bvar/tst.ppid.d b/test/unittest/variables/bvar/tst.ppid.d
index e406b36f..87bc52da 100644
--- a/test/unittest/variables/bvar/tst.ppid.d
+++ b/test/unittest/variables/bvar/tst.ppid.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: The 'ppid' variable can be accessed and is not -1.
diff --git a/test/unittest/variables/bvar/tst.ppid2.d b/test/unittest/variables/bvar/tst.ppid2.d
new file mode 100644
index 00000000..7a50ac89
--- /dev/null
+++ b/test/unittest/variables/bvar/tst.ppid2.d
@@ -0,0 +1,20 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 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.
+ */
+
+/*
+ * ASSERTION: The 'ppid' variable matches the scripting variable for BEGIN.
+ *
+ * SECTION: Variables/Built-in Variables/ppid
+ */
+
+#pragma D option quiet
+
+BEGIN {
+ trace(ppid);
+ trace($ppid);
+ exit(ppid == $ppid ? 0 : 1);
+}
--
2.18.4
More information about the DTrace-devel
mailing list