All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] trace-cmd record: Use tracefs_filter_function() for function filtering
@ 2021-04-08 16:38 Steven Rostedt
  0 siblings, 0 replies; only message in thread
From: Steven Rostedt @ 2021-04-08 16:38 UTC (permalink / raw)
  To: Linux Trace Devel

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

By having the implementation for -l and -n use tracefs_function_filter()
and tracefs_function_notrace() it extends the filtering capability to use
full regex expressions.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 .../trace-cmd/trace-cmd-record.1.txt          |  9 +--
 tracecmd/trace-record.c                       | 58 ++++++++++++++++++-
 2 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/Documentation/trace-cmd/trace-cmd-record.1.txt b/Documentation/trace-cmd/trace-cmd-record.1.txt
index d992002e..55a8891b 100644
--- a/Documentation/trace-cmd/trace-cmd-record.1.txt
+++ b/Documentation/trace-cmd/trace-cmd-record.1.txt
@@ -134,10 +134,11 @@ OPTIONS
 *-l* 'function-name'::
     This will limit the 'function' and 'function_graph' tracers to only trace
     the given function name. More than one *-l* may be specified on the
-    command line to trace more than one function. The limited use of glob
-    expressions are also allowed. These are 'match\*' to only filter functions
-    that start with 'match'. '\*match' to only filter functions that end with
-    'match'. '\*match\*' to only filter on functions that contain 'match'.
+    command line to trace more than one function. This supports both full
+    regex(3) parsing, or basic glob parsing. If the filter has only alphanumeric,
+    '_', '*', '?' and '.' characters, then it will be parsed as a basic glob.
+    to force it to be a regex, prefix the filter with '^' or append it with '$'
+    and it will then be parsed as a regex.
 
 *-g* 'function-name'::
     This option is for the function_graph plugin. It will graph the given
diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
index 6b608ad5..fd03a605 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -4351,6 +4351,58 @@ static void record_data(struct common_record_context *ctx)
 	tracecmd_output_close(handle);
 }
 
+enum filter_type {
+	FUNC_FILTER,
+	FUNC_NOTRACE,
+};
+
+static int write_func_filter(enum filter_type type, struct buffer_instance *instance,
+			     struct func_list **list)
+{
+	struct func_list *item;
+	const char *file;
+	int ret = -1;
+	int (*filter_function)(struct tracefs_instance *instance, const char *filter,
+			       const char *module, unsigned int flags);
+
+	if (!*list)
+		return 0;
+
+	switch (type) {
+	case FUNC_FILTER:
+		filter_function = tracefs_function_filter;
+		file = "set_ftrace_filter";
+		break;
+	case FUNC_NOTRACE:
+		filter_function = tracefs_function_notrace;
+		file = "set_ftrace_notrace";
+		break;
+	}
+
+	ret = filter_function(instance->tracefs, NULL, NULL,
+			      TRACEFS_FL_RESET | TRACEFS_FL_CONTINUE);
+	if (ret < 0)
+		return ret;
+
+	while (*list) {
+		item = *list;
+		*list = item->next;
+		ret = filter_function(instance->tracefs, item->func, item->mod,
+				      TRACEFS_FL_CONTINUE);
+		if (ret < 0)
+			goto failed;
+		free(item);
+	}
+	ret = filter_function(instance->tracefs, NULL, NULL, 0);
+	return ret;
+ failed:
+	die("Failed to write %s to %s.\n"
+	    "Perhaps this function is not available for tracing.\n"
+	    "run 'trace-cmd list -f %s' to see if it is.",
+	    item->func, file, item->func);
+	return ret;
+}
+
 static int write_func_file(struct buffer_instance *instance,
 			    const char *file, struct func_list **list)
 {
@@ -4439,7 +4491,7 @@ static void set_funcs(struct buffer_instance *instance)
 	if (is_guest(instance))
 		return;
 
-	ret = write_func_file(instance, "set_ftrace_filter", &instance->filter_funcs);
+	ret = write_func_filter(FUNC_FILTER, instance, &instance->filter_funcs);
 	if (ret < 0)
 		die("set_ftrace_filter does not exist. Can not filter functions");
 
@@ -4455,13 +4507,13 @@ static void set_funcs(struct buffer_instance *instance)
 				set_notrace = 1;
 		}
 		if (!set_notrace) {
-			ret = write_func_file(instance, "set_ftrace_notrace",
+			ret = write_func_filter(FUNC_NOTRACE, instance,
 					      &instance->notrace_funcs);
 			if (ret < 0)
 				die("set_ftrace_notrace does not exist. Can not filter functions");
 		}
 	} else
-		write_func_file(instance, "set_ftrace_notrace", &instance->notrace_funcs);
+		write_func_filter(FUNC_NOTRACE, instance, &instance->notrace_funcs);
 
 	/* make sure we are filtering functions */
 	if (func_stack && is_top_instance(instance)) {
-- 
2.29.2


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-04-08 16:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-08 16:38 [PATCH] trace-cmd record: Use tracefs_filter_function() for function filtering Steven Rostedt

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.