From: "Steven Rostedt (VMware)" <rostedt@xxxxxxxxxxx> 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@xxxxxxxxxxx> --- .../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