All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: Linux Trace Devel <linux-trace-devel@vger.kernel.org>
Subject: [PATCH] libtracefs: Add tracefs_kprobe_destory() API
Date: Mon, 5 Jun 2023 21:42:14 -0400	[thread overview]
Message-ID: <20230605214214.2289969d@gandalf.local.home> (raw)

From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

Currently the only way to remove kprobes from the system via tracefs that
was created by tracefs_kprobe_raw() or tracefs_ketprobe_all is with the
big hammer of tracefs_dynevent_destroy_all(), as removing a single kprobe
requires having the tracefs_dynevent descriptor for it (which the raw
functions do not return).

Add tracefs_kprobe_destroy() that will remove an individual kprobe or
kretprobe that was created by one of the raw functions.

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 Documentation/libtracefs-kprobes.txt | 14 +++++++++++--
 include/tracefs.h                    |  2 ++
 samples/Makefile                     |  2 ++
 src/tracefs-kprobes.c                | 30 ++++++++++++++++++++++++++++
 utest/tracefs-utest.c                | 18 ++++++++++++++++-
 5 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/Documentation/libtracefs-kprobes.txt b/Documentation/libtracefs-kprobes.txt
index 593ef9ee11fb..f03b096778a5 100644
--- a/Documentation/libtracefs-kprobes.txt
+++ b/Documentation/libtracefs-kprobes.txt
@@ -3,8 +3,9 @@ libtracefs(3)
 
 NAME
 ----
-tracefs_kprobe_alloc, tracefs_kretprobe_alloc, tracefs_kprobe_raw, tracefs_kretprobe_raw -
-Allocate, get, and create kprobes
+tracefs_kprobe_alloc, tracefs_kretprobe_alloc, tracefs_kprobe_raw, tracefs_kretprobe_raw,
+tracefs_kprobe_destroy -
+Allocate, get, create, and remove kprobes
 
 SYNOPSIS
 --------
@@ -22,6 +23,8 @@ int *tracefs_kprobe_raw*(const char pass:[*]_system_, const char pass:[*]_event_
 			 const char pass:[*]_addr_, const char pass:[*]_format_);
 int *tracefs_kretprobe_raw*(const char pass:[*]_system_, const char pass:[*]_event_,
 			    const char pass:[*]_addr_, const char pass:[*]_format_);
+int *tracefs_kprobe_destroy*(const char pass:[*]_system_, const char pass:[*]_event_,
+			   const char pass:[*]_addr_, const char pass:[*]_format_, bool _force_);
 --
 
 DESCRIPTION
@@ -49,6 +52,9 @@ document.
 creates a kretprobe instead of a kprobe. The difference is also described
 in the Linux kernel source in the Documentation/trace/kprobetrace.rst file.
 
+*tracefs_kprobe_destroy*() will destroy a specific kprobe or kretprobe created by
+*tracefs_kprobe_raw*() or *tracefs_kretprobe_raw*() with the same parameters.
+
 RETURN VALUE
 ------------
 
@@ -61,6 +67,10 @@ tracefs_dynevent structure, describing the probe. This pointer must be freed by
 *tracefs_dynevent_free*(3). Note, this only allocates a descriptor representing the kprobe. It does
 not modify the running system.
 
+The *tracefs_kprobe_destroy*() returns 0 on success or -1 on error if it was not able to
+successful destory (or find) the kprobe or kretprobe.
+
+
 ERRORS
 ------
 The following errors are for all the above calls:
diff --git a/include/tracefs.h b/include/tracefs.h
index 7c442e47204d..269b119ffc2a 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -325,6 +325,8 @@ int tracefs_kprobe_raw(const char *system, const char *event,
 		       const char *addr, const char *format);
 int tracefs_kretprobe_raw(const char *system, const char *event,
 			  const char *addr, const char *format);
+int tracefs_kprobe_destroy(const char *system, const char *event,
+			   const char *addr, const char *format, bool force);
 
 enum tracefs_hist_key_type {
 	TRACEFS_HIST_KEY_NORMAL = 0,
diff --git a/samples/Makefile b/samples/Makefile
index fa88ffc75b1d..d782e8f79424 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -63,6 +63,8 @@ $(EXAMPLES): $(patsubst %,$(sdir)/%,$(TARGETS))
 #
 # $(bdir)/XX.o: $(bdir)/XX.c
 #	$(CC) -g -Wall $(CFLAGS) -c -o $@ $^ -I../include/ $(LIBTRACEEVENT_INCLUDES)
+$(bdir)/kprobes.o: $(bdir)/kprobes.c
+	$(CC) -g -Wall $(CFLAGS) -c -o $@ $^ -I../include/ $(LIBTRACEEVENT_INCLUDES)
 
 $(bdir)/%.o: $(bdir)/%.c
 	$(call do_sample_obj,$@,$^)
diff --git a/src/tracefs-kprobes.c b/src/tracefs-kprobes.c
index a8c016376118..5c50b21753e6 100644
--- a/src/tracefs-kprobes.c
+++ b/src/tracefs-kprobes.c
@@ -196,3 +196,33 @@ int tracefs_kretprobe_raw(const char *system, const char *event,
 {
 	return kprobe_raw(TRACEFS_DYNEVENT_KRETPROBE, system, event, addr, format);
 }
+
+/**
+ * tracefs_kprobe_destroy - Remove an individual kprobe or kretprobe
+ * @system: The system of the kprobe to remove (could be NULL)
+ * @event: The event of the kprobe or kretprobe to remove
+ * @addr: The address used to create the kprobe
+ * @format: The format used to create the kprobe
+ * @force: If true, try to disable the kprobe/kretprobe first
+ *
+ * This removes the kprobe or kretprobe that was created by
+ * tracefs_kprobe_raw() or tracefs_kretprobe_raw().
+ *
+ * Returns 0 on success and -1 otherwise.
+ */
+int tracefs_kprobe_destroy(const char *system, const char *event,
+			   const char *addr, const char *format, bool force)
+{
+	struct tracefs_dynevent *kp;
+	int ret;
+
+	kp = tracefs_kprobe_alloc(system, event, addr, format);
+	if (!kp)
+		return -1;
+
+	ret = tracefs_dynevent_destroy(kp, force);
+
+	tracefs_dynevent_free(kp);
+
+	return ret;
+}
diff --git a/utest/tracefs-utest.c b/utest/tracefs-utest.c
index cd2304474089..398c94368e66 100644
--- a/utest/tracefs-utest.c
+++ b/utest/tracefs-utest.c
@@ -1368,7 +1368,23 @@ static void test_kprobes_instance(struct tracefs_instance *instance)
 	tracefs_dynevent_list_free(devents);
 	devents = NULL;
 
-	destroy_dynevents(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE);
+	/* Try destroying all the events using tracefs_kprobe_destroy */
+	for (i = 0; i < kprobe_count; i++) {
+		ret = tracefs_kprobe_destroy(ktests[i].system, ktests[i].event,
+					     ktests[i].address, ktests[i].format, true);
+		CU_TEST(ret == 0);
+		get_dynevents_check(TRACEFS_DYNEVENT_KPROBE, kprobe_count - (i + 1));
+	}
+	get_dynevents_check(TRACEFS_DYNEVENT_KPROBE, 0);
+
+	for (i = 0; i < kretprobe_count; i++) {
+		ret = tracefs_kprobe_destroy(kretests[i].system, kretests[i].event,
+					     kretests[i].address, kretests[i].format, true);
+		CU_TEST(ret == 0);
+		get_dynevents_check(TRACEFS_DYNEVENT_KRETPROBE, kretprobe_count - (i + 1));
+	}
+	get_dynevents_check(TRACEFS_DYNEVENT_KRETPROBE, 0);
+
 	free(dkretprobe);
 	free(dkprobe);
 	tep_free(tep);
-- 
2.39.2


                 reply	other threads:[~2023-06-06  1:42 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20230605214214.2289969d@gandalf.local.home \
    --to=rostedt@goodmis.org \
    --cc=linux-trace-devel@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.