[DTrace-devel] [PATCH v3 38/38] Systemwide USDT WIP
eugene.loh at oracle.com
eugene.loh at oracle.com
Wed Jul 3 20:33:40 UTC 2024
From: Eugene Loh <eugene.loh at oracle.com>
need to:
- handle globs in dt_pid_create_probes_module()
- add process monitoring / inotify
- deal with FIXMEs
Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
libdtrace/dt_cc.c | 5 +-
libdtrace/dt_pid.c | 65 ++++++++++++++-----
.../dtrace-util/tst.ListProbesFuncUSDT.sh | 1 -
.../dtrace-util/tst.ListProbesModuleUSDT.sh | 1 -
.../dtrace-util/tst.ListProbesNameUSDT.sh | 1 -
.../dtrace-util/tst.ListProbesProviderUSDT.sh | 1 -
test/unittest/usdt/tst.forker.sh | 1 -
7 files changed, 52 insertions(+), 23 deletions(-)
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index d09a9775..cc8f7c1c 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -277,8 +277,9 @@ dt_setcontext(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp)
* On an error, dt_pid_create_probes() will set the error message
* and tag -- we just have to longjmp() out of here.
*/
- if (pdp->prv && pdp->prv[0] &&
- isdigit(pdp->prv[strlen(pdp->prv) - 1]) &&
+ if (pdp->prv &&
+ (pdp->prv[0] == '\0' || isdigit(pdp->prv[strlen(pdp->prv) - 1]) ||
+ pdp->prv[strlen(pdp->prv) - 1] == '*') &&
((pvp = dt_provider_lookup(dtp, pdp->prv)) == NULL ||
pvp->pv_flags & DT_PROVIDER_PID) &&
dt_pid_create_probes((dtrace_probedesc_t *)pdp, dtp, yypcb) != 0) {
diff --git a/libdtrace/dt_pid.c b/libdtrace/dt_pid.c
index 996543b1..484156b2 100644
--- a/libdtrace/dt_pid.c
+++ b/libdtrace/dt_pid.c
@@ -605,6 +605,9 @@ dt_pid_fix_mod(dt_pid_probe_t *pp, dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
return pmp;
}
+/*
+ * Create pid probes for the specified process.
+ */
static int
dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
dt_pcb_t *pcb, dt_proc_t *dpr)
@@ -702,6 +705,7 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp,
return ret;
}
+
/*
* Read a file into a buffer and return it.
*/
@@ -780,8 +784,8 @@ validate_dof_record(const char *path, const dof_parsed_t *parsed,
/*
* Create underlying probes relating to the probespec passed on input.
*
- * If dpr is set, just set up probes relating to mappings found in that one
- * process. (dpr must in this case be locked.)
+ * dpr must be set and locked. Just set up probes relating to mappings found
+ * in this one process.
*
* Return 0 on success or -1 on error. (Failure to create specific underlying
* probes is not an error.)
@@ -795,9 +799,6 @@ dt_pid_create_usdt_probes(dtrace_hdl_t *dtp, dt_proc_t *dpr, dtrace_probedesc_t
char *probepath = NULL;
glob_t probeglob = {0};
- /*
- * Systemwide probing: not yet implemented.
- */
assert(dpr != NULL && dpr->dpr_proc);
assert(MUTEX_HELD(&dpr->dpr_lock));
@@ -1100,16 +1101,25 @@ dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb)
char provname[DTRACE_PROVNAMELEN];
dt_proc_t *dpr;
pid_t pid;
- int err = 0;
+ int err = 0, i, nmatches = 0;
+ glob_t globbuf;
+ char *globpat = NULL;
assert(pcb != NULL);
- if ((pid = dt_pid_get_pid(pdp, dtp, pcb, NULL)) == -1)
+ /* Exclude pid0 from being specifically requested. */
+ if (strcmp(pdp->prv, "pid0") == 0) {
+ dt_pid_error(dtp, pcb, NULL, D_PROC_BADPID,
+ "pid0 does not contain a valid pid");
return -1;
+ }
- snprintf(provname, sizeof(provname), "pid%d", (int)pid);
-
- if (gmatch(provname, pdp->prv) != 0) {
+ /*
+ * Is this a pid$pid probe?
+ */
+ if ((pid = dt_pid_get_pid(pdp, dtp, pcb, NULL)) > 0 &&
+ snprintf(provname, sizeof(provname), "pid%d", (int)pid) > 0 &&
+ gmatch(provname, pdp->prv) != 0) {
if (dt_proc_grab_lock(dtp, pid, DTRACE_PROC_WAITING) < 0) {
dt_pid_error(dtp, pcb, NULL, D_PROC_GRAB,
"failed to grab process %d", (int)pid);
@@ -1119,14 +1129,36 @@ dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb)
dpr = dt_proc_lookup(dtp, pid);
assert(dpr != NULL);
+ // FIXME How should err be handled?
err = dt_pid_create_pid_probes(pdp, dtp, pcb, dpr);
dt_proc_release_unlock(dtp, pid);
}
/*
- * If it's not strictly a pid provider, we might match a USDT provider.
+ * If it's strictly a pid provider, we're done.
*/
- if (strcmp(provname, pdp->prv) != 0) {
+ if (strcmp(provname, pdp->prv) == 0)
+ return err ? -1 : 0;
+
+ asprintf(&globpat, "%s/probes/*/%s", dtp->dt_dofstash_path, pdp->prv[0] ? pdp->prv : "*");
+ nmatches = glob(globpat, 0, NULL, &globbuf) ? 0 : globbuf.gl_pathc;
+ for (i = 0; i < nmatches; i++) {
+ char *s = globbuf.gl_pathv[i]
+ + strlen(dtp->dt_dofstash_path)
+ + strlen("/probes/");
+ dtrace_probedesc_t pdptmp;
+
+ pdptmp.prv = strchr(s, '/') + 1;
+ pdptmp.mod = pdp->mod[0] == '\0' ? "*" : pdp->mod;
+ pdptmp.fun = pdp->fun[0] == '\0' ? "*" : pdp->fun;
+ pdptmp.prb = pdp->prb[0] == '\0' ? "*" : pdp->prb;
+
+ pid = atoll(s);
+
+ // Check, since dtprobed takes a while to clean up dead processes.
+ if (!Pexists(pid))
+ continue;
+
if (dt_proc_grab_lock(dtp, pid, DTRACE_PROC_WAITING |
DTRACE_PROC_SHORTLIVED) < 0) {
dt_pid_error(dtp, pcb, NULL, D_PROC_GRAB,
@@ -1137,17 +1169,18 @@ dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb)
dpr = dt_proc_lookup(dtp, pid);
assert(dpr != NULL);
- err = dt_pid_create_usdt_probes(dtp, dpr, pdp, pcb);
+ // FIXME: How should err be handled?
+ err = dt_pid_create_usdt_probes(dtp, dpr, &pdptmp, pcb);
/*
* Put the module name in its canonical form.
*/
- dt_pid_fix_mod(NULL, pdp, dtp, dpr->dpr_pid);
+ dt_pid_fix_mod(NULL, &pdptmp, dtp, dpr->dpr_pid);
dt_proc_release_unlock(dtp, pid);
}
-
- /* (USDT systemwide probing goes here.) */
+ free(globpat);
+ globfree(&globbuf);
return err ? -1 : 0;
}
diff --git a/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh
index bd0552dc..99ae995e 100755
--- a/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh
+++ b/test/unittest/dtrace-util/tst.ListProbesFuncUSDT.sh
@@ -5,7 +5,6 @@
# 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/dtrace-util/tst.ListProbesModuleUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh
index 7b9c6a5f..5ae087fb 100755
--- a/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh
+++ b/test/unittest/dtrace-util/tst.ListProbesModuleUSDT.sh
@@ -5,7 +5,6 @@
# 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/dtrace-util/tst.ListProbesNameUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh
index c5dfc72b..9d8f06e9 100755
--- a/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh
+++ b/test/unittest/dtrace-util/tst.ListProbesNameUSDT.sh
@@ -5,7 +5,6 @@
# 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/dtrace-util/tst.ListProbesProviderUSDT.sh b/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh
index 644da2ac..6eae82ed 100755
--- a/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh
+++ b/test/unittest/dtrace-util/tst.ListProbesProviderUSDT.sh
@@ -5,7 +5,6 @@
# 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/usdt/tst.forker.sh b/test/unittest/usdt/tst.forker.sh
index 7cfa9eb5..92513eb5 100755
--- a/test/unittest/usdt/tst.forker.sh
+++ b/test/unittest/usdt/tst.forker.sh
@@ -7,7 +7,6 @@
#
#
# @@timeout: 120
-# @@xfail: dtv2 USDT wildcard
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
--
2.43.5
More information about the DTrace-devel
mailing list