public inbox for dtrace@lists.linux.dev
 help / color / mirror / Atom feed
From: Alan Maguire <alan.maguire@oracle.com>
To: dtrace@lists.linux.dev
Cc: dtrace-devel@oss.oracle.com, Alan Maguire <alan.maguire@oracle.com>
Subject: [PATCH v3 dtrace 2/4] fbt: support "."-suffixed functions for kprobes
Date: Wed, 16 Oct 2024 16:54:07 +0100	[thread overview]
Message-ID: <20241016155409.4038017-3-alan.maguire@oracle.com> (raw)
In-Reply-To: <20241016155409.4038017-1-alan.maguire@oracle.com>

gcc adds suffixes when it carries out optimizations, but often
these leave parameters to functions intact.  Many of these functions
(like finish_task_switch()) are important for tracing (and they
are present in available_filter_functions so are traceable) so it is
valuable to support probing them.  For kprobes, the probe name removes
the "." suffix, so store it as additional tp event data for kprobe
attach (attach time is the only time we need the full function name).

fprobe does not support such functions, so the kprobe impl is always
used in such cases.

Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
---
 libdtrace/dt_prov_fbt.c | 76 ++++++++++++++++++++++++++++++++---------
 1 file changed, 59 insertions(+), 17 deletions(-)

diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
index 21f63ddf..06ea78ca 100644
--- a/libdtrace/dt_prov_fbt.c
+++ b/libdtrace/dt_prov_fbt.c
@@ -21,6 +21,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <port.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -63,8 +64,8 @@ static const dtrace_pattr_t	pattr = {
  */
 static int populate(dtrace_hdl_t *dtp)
 {
-	dt_provider_t		*prv;
-	dt_provimpl_t		*impl;
+	dt_provider_t		*default_prv, *kprobe_prv = NULL;
+	dt_provimpl_t		*default_impl;
 	FILE			*f;
 	char			*buf = NULL;
 	char			*p;
@@ -73,17 +74,25 @@ static int populate(dtrace_hdl_t *dtp)
 	dtrace_syminfo_t	sip;
 	dtrace_probedesc_t	pd;
 
-	impl = BPF_HAS(dtp, BPF_FEAT_FENTRY) ? &dt_fbt_fprobe : &dt_fbt_kprobe;
+	default_impl = BPF_HAS(dtp, BPF_FEAT_FENTRY) ? &dt_fbt_fprobe : &dt_fbt_kprobe;
 
-	prv = dt_provider_create(dtp, prvname, impl, &pattr, NULL);
-	if (prv == NULL)
+	default_prv = dt_provider_create(dtp, prvname, default_impl, &pattr, NULL);
+	if (default_prv == NULL)
 		return -1;			/* errno already set */
+	if (default_impl == &dt_fbt_kprobe)
+		kprobe_prv = default_prv;
 
 	f = fopen(PROBE_LIST, "r");
 	if (f == NULL)
 		return 0;
 
 	while (getline(&buf, &n, f) >= 0) {
+		dt_provimpl_t	*impl = default_impl;
+		dt_provider_t	*prv = default_prv;
+		char		fun[DTRACE_FUNCNAMELEN] = {};
+		void		*entry_data = NULL;
+		void		*return_data = NULL;
+
 		/*
 		 * Here buf is either "funcname\n" or "funcname [modname]\n".
 		 * The last line may not have a linefeed.
@@ -106,10 +115,6 @@ static int populate(dtrace_hdl_t *dtp)
 				p++;
 		}
 
-		/* Weed out synthetic symbol names (that are invalid). */
-		if (strchr(buf, '.') != NULL)
-			continue;
-
 #define strstarts(var, x) (strncmp(var, x, strlen (x)) == 0)
 		/* Weed out __ftrace_invalid_address___* entries. */
 		if (strstarts(buf, "__ftrace_invalid_address__") ||
@@ -129,6 +134,31 @@ static int populate(dtrace_hdl_t *dtp)
 		} else
 			mod = p;
 
+		/* '.'-suffixed functions (e.g. foo.isra.0) must always be
+		 * kprobe-backed as fprobe does not support them.  They
+		 * are represented with their unsuffixed names however, so
+		 * the full name including suffix is stored as data associated
+		 * with the tp event.
+		 */
+		strlcpy(fun, buf, sizeof(fun));
+		if (strchr(buf, '.') != NULL) {
+			char *suffix;
+
+			impl = &dt_fbt_kprobe;
+			if (!kprobe_prv) {
+				kprobe_prv = dt_provider_create(dtp, prvname,
+								impl, &pattr,
+								NULL);
+				if (kprobe_prv == NULL)
+					return -1;
+			}
+			prv = kprobe_prv;
+			suffix = strchr(fun, '.');
+			*suffix = '\0';
+			entry_data = strdup(buf);
+			return_data = strdup(buf);
+		}
+
 		/*
 		 * Due to the lack of module names in
 		 * TRACEFS/available_filter_functions, there are some duplicate
@@ -138,14 +168,16 @@ static int populate(dtrace_hdl_t *dtp)
 		pd.id = DTRACE_IDNONE;
 		pd.prv = prvname;
 		pd.mod = mod;
-		pd.fun = buf;
+		pd.fun = fun;
 		pd.prb = "entry";
 		if (dt_probe_lookup(dtp, &pd) != NULL)
 			continue;
 
-		if (dt_tp_probe_insert(dtp, prv, prvname, mod, buf, "entry"))
+		if (dt_tp_probe_insert_data(dtp, prv, prvname, mod, fun,
+					    "entry", entry_data))
 			n++;
-		if (dt_tp_probe_insert(dtp, prv, prvname, mod, buf, "return"))
+		if (dt_tp_probe_insert_data(dtp, prv, prvname, mod, fun,
+					    "return", return_data))
 			n++;
 	}
 
@@ -363,10 +395,11 @@ static int kprobe_trampoline(dt_pcb_t *pcb, uint_t exitlbl)
 static int kprobe_attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
 {
 	if (!dt_tp_probe_has_info(prp)) {
-		char	*fn;
-		FILE	*f;
-		size_t	len;
-		int	fd, rc = -1;
+		char		*fn;
+		const char	*fun;
+		FILE		*f;
+		size_t		len;
+		int		fd, rc = -1;
 
 		/*
 		 * Register the kprobe with the tracing subsystem.  This will
@@ -376,9 +409,18 @@ static int kprobe_attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
 		if (fd == -1)
 			return -ENOENT;
 
+		/* If actual function name contained a '.', it is stored in
+		 * tp data; use non-suffix name for event as event names
+		 * cannot contain a '.'.  User-visible probe name does
+		 * not contain a '.'.
+		 */
+		fun = dt_tp_get_event_data(prp);
+		if (!fun)
+			fun = prp->desc->fun;
+
 		rc = dprintf(fd, "%c:" FBT_GROUP_FMT "/%s %s\n",
 			     prp->desc->prb[0] == 'e' ? 'p' : 'r',
-			     FBT_GROUP_DATA, prp->desc->fun, prp->desc->fun);
+			     FBT_GROUP_DATA, prp->desc->fun, fun);
 		close(fd);
 		if (rc == -1)
 			return -ENOENT;
-- 
2.43.5


  parent reply	other threads:[~2024-10-16 15:54 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-16 15:54 [PATCH v3 dtrace 0/4] kprobe support for .isra.0, sched fix Alan Maguire
2024-10-16 15:54 ` [PATCH v3 dtrace 1/4] dt_provider_tp: add optional event data, freed on tp free Alan Maguire
2024-11-14  5:26   ` [DTrace-devel] " Kris Van Hees
2024-11-14 16:45     ` Alan Maguire
2024-10-16 15:54 ` Alan Maguire [this message]
2024-11-28  2:22   ` [PATCH v3 dtrace 2/4] fbt: support "."-suffixed functions for kprobes Kris Van Hees
2024-11-28  9:58     ` Alan Maguire
2024-10-16 15:54 ` [PATCH v3 dtrace 3/4] fbt: avoid mix of kprobe, fprobe implementations for used probes Alan Maguire
2024-10-16 15:54 ` [PATCH v3 dtrace 4/4] sched: fix on-cpu firing for kernels < 5.16 Alan Maguire
2024-10-18 15:41 ` [PATCH v3 dtrace 0/4] kprobe support for .isra.0, sched fix Kris Van Hees
2024-10-18 16:15   ` Alan Maguire
2024-10-18 18:38     ` Kris Van Hees

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241016155409.4038017-3-alan.maguire@oracle.com \
    --to=alan.maguire@oracle.com \
    --cc=dtrace-devel@oss.oracle.com \
    --cc=dtrace@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox