diff mbox series

[1/3] libtracefs: New APIs for ftrace uprobes

Message ID 20220328090347.107849-2-tz.stoyanov@gmail.com (mailing list archive)
State Accepted
Commit ca469d1be3bf231d5042924e5e63c8c3f729a854
Headers show
Series libtracefs: Uprobe APIs | expand

Commit Message

Tzvetomir Stoyanov (VMware) March 28, 2022, 9:03 a.m. UTC
The tracefs library has APIs for allocating almost all types of ftrace
dynamic events. Uprobe is the only dynamic event that has no
corresponding tracefs API. These two APIs are proposed:
 tracefs_uprobe_alloc()
 tracefs_uretprobe_alloc()
They allocate context for new uprobe/uretprobe, without creating events
in the system. The regular dynamic events APIs can be used to work with
newly created uprobes.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 include/tracefs.h     |  6 +++
 src/Makefile          |  1 +
 src/tracefs-uprobes.c | 90 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 97 insertions(+)
 create mode 100644 src/tracefs-uprobes.c
diff mbox series

Patch

diff --git a/include/tracefs.h b/include/tracefs.h
index 05f3352..27954a4 100644
--- a/include/tracefs.h
+++ b/include/tracefs.h
@@ -280,6 +280,12 @@  tracefs_dynevent_get_event(struct tep_handle *tep, struct tracefs_dynevent *dyne
 struct tracefs_dynevent *
 tracefs_eprobe_alloc(const char *system, const char *event,
 		     const char *target_system, const char *target_event, const char *fetchargs);
+struct tracefs_dynevent *
+tracefs_uprobe_alloc(const char *system, const char *event,
+		     const char *file, unsigned long long offset, const char *fetchargs);
+struct tracefs_dynevent *
+tracefs_uretprobe_alloc(const char *system, const char *event,
+			const char *file, unsigned long long offset, const char *fetchargs);
 
 struct tracefs_dynevent *
 tracefs_kprobe_alloc(const char *system, const char *event, const char *addr, const char *format);
diff --git a/src/Makefile b/src/Makefile
index e8afab5..645d518 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -13,6 +13,7 @@  OBJS += tracefs-hist.o
 OBJS += tracefs-filter.o
 OBJS += tracefs-dynevents.o
 OBJS += tracefs-eprobes.o
+OBJS += tracefs-uprobes.o
 
 # Order matters for the the three below
 OBJS += sqlhist-lex.o
diff --git a/src/tracefs-uprobes.c b/src/tracefs-uprobes.c
new file mode 100644
index 0000000..aa39b75
--- /dev/null
+++ b/src/tracefs-uprobes.c
@@ -0,0 +1,90 @@ 
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * Copyright (C) 2022, VMware, Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
+ *
+ */
+#include <stdlib.h>
+#include <errno.h>
+
+#include "tracefs.h"
+#include "tracefs-local.h"
+
+#define UPROBE_DEFAULT_GROUP "uprobes"
+
+static struct tracefs_dynevent *
+uprobe_alloc(enum tracefs_dynevent_type type, const char *system, const char *event,
+	     const char *file, unsigned long long offset, const char *fetchargs)
+{
+	struct tracefs_dynevent *kp;
+	char *target;
+
+	if (!event || !file) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	if (!system)
+		system = UPROBE_DEFAULT_GROUP;
+
+	if (asprintf(&target, "%s:0x%0*llx", file, (int)(sizeof(void *) * 2), offset) < 0)
+		return NULL;
+
+	kp = dynevent_alloc(type, system, event, target, fetchargs);
+	free(target);
+
+	return kp;
+}
+
+/**
+ * tracefs_uprobe_alloc - Allocate new user probe (uprobe)
+ * @system: The system name (NULL for the default uprobes)
+ * @event: The name of the event to create
+ * @file: The full path to the binary file, where the uprobe will be set
+ * @offset: Offset within the @file
+ * @fetchargs: String with arguments, that will be fetched with the uprobe
+ *
+ * Allocate new uprobe context that will be in the @system group
+ * (or uprobes if @system is NULL) and with @event name. The new uprobe will be
+ * attached to @offset within the @file. The arguments described in @fetchargs
+ * will fetched with the uprobe. See linux/Documentation/trace/uprobetracer.rst
+ * for more details.
+ *
+ * The uprobe is not created in the system.
+ *
+ * Return a pointer to a uprobe context on success, or NULL on error.
+ * The returned pointer must be freed with tracefs_dynevent_free()
+ *
+ */
+struct tracefs_dynevent *
+tracefs_uprobe_alloc(const char *system, const char *event,
+		     const char *file, unsigned long long offset, const char *fetchargs)
+{
+	return uprobe_alloc(TRACEFS_DYNEVENT_UPROBE, system, event, file, offset, fetchargs);
+}
+
+/**
+ * tracefs_uretprobe_alloc - Allocate new user return probe (uretprobe)
+ * @system: The system name (NULL for the default uprobes)
+ * @event: The name of the event to create
+ * @file: The full path to the binary file, where the uretprobe will be set
+ * @offset: Offset within the @file
+ * @fetchargs: String with arguments, that will be fetched with the uretprobe
+ *
+ * Allocate mew uretprobe context that will be in the @system group
+ * (or uprobes if @system is NULL) and with @event name. The new uretprobe will
+ * be attached to @offset within the @file. The arguments described in @fetchargs
+ * will fetched with the uprobe. See linux/Documentation/trace/uprobetracer.rst
+ * for more details.
+ *
+ * The uretprobe is not created in the system.
+ *
+ * Return a pointer to a uretprobe context on success, or NULL on error.
+ * The returned pointer must be freed with tracefs_dynevent_free()
+ *
+ */
+struct tracefs_dynevent *
+tracefs_uretprobe_alloc(const char *system, const char *event,
+			const char *file, unsigned long long offset, const char *fetchargs)
+{
+	return uprobe_alloc(TRACEFS_DYNEVENT_URETPROBE, system, event, file, offset, fetchargs);
+}