aboutsummaryrefslogtreecommitdiffstats
path: root/trace-cmd.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-02-17 21:26:26 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-02-17 21:26:26 -0500
commitea645651cdc0ab38fddeb9f81b13eccc9a22d98d (patch)
tree3e5684793fd898451179738fdbddec0b4b3994a0 /trace-cmd.c
parent3095089b3c0e95adda29ddcde8840e784d2f8ea5 (diff)
trace-cmd: Implement trace-cmd record function filtering
Now with "trace-cmd record -l func -g func -n func" you can add function filtering to the trace. Since -F and -f are taken, -l is used as "limit functions". -l func ; writes func into set_ftrace_filter -n func ; writes func into set_ftrace_notrace -g func ; writes func into set_graph_function You can specify more than one function on the command line. trace-cmd record -p function -l sys_write -l sys_read The above will set set_ftrace_filter to both sys_write and sys_read. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'trace-cmd.c')
-rw-r--r--trace-cmd.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/trace-cmd.c b/trace-cmd.c
index d91e212..2b246df 100644
--- a/trace-cmd.c
+++ b/trace-cmd.c
@@ -59,6 +59,15 @@ static int *pids;
59 59
60static int filter_task; 60static int filter_task;
61 61
62struct func_list {
63 struct func_list *next;
64 const char *func;
65};
66
67static struct func_list *filter_funcs;
68static struct func_list *notrace_funcs;
69static struct func_list *graph_funcs;
70
62struct event_list { 71struct event_list {
63 struct event_list *next; 72 struct event_list *next;
64 const char *event; 73 const char *event;
@@ -997,6 +1006,48 @@ static int trace_empty(void)
997 return ret; 1006 return ret;
998} 1007}
999 1008
1009static void write_func_file(const char *file, struct func_list **list)
1010{
1011 struct func_list *item;
1012 char *path;
1013 int fd;
1014
1015 path = get_tracing_file(file);
1016
1017 fd = open(path, O_WRONLY | O_TRUNC);
1018 if (fd < 0)
1019 goto free;
1020
1021 while (*list) {
1022 item = *list;
1023 *list = item->next;
1024 write(fd, item->func, strlen(item->func));
1025 write(fd, " ", 1);
1026 free(item);
1027 }
1028 close(fd);
1029
1030 free:
1031 put_tracing_file(path);
1032}
1033
1034static void set_funcs(void)
1035{
1036 write_func_file("set_ftrace_filter", &filter_funcs);
1037 write_func_file("set_ftrace_notrace", &notrace_funcs);
1038 write_func_file("set_graph_function", &graph_funcs);
1039}
1040
1041static void add_func(struct func_list **list, const char *func)
1042{
1043 struct func_list *item;
1044
1045 item = malloc_or_die(sizeof(*item));
1046 item->func = func;
1047 item->next = *list;
1048 *list = item;
1049}
1050
1000void usage(char **argv) 1051void usage(char **argv)
1001{ 1052{
1002 char *arg = argv[0]; 1053 char *arg = argv[0];
@@ -1009,11 +1060,15 @@ void usage(char **argv)
1009 printf("\n" 1060 printf("\n"
1010 "%s version %s\n\n" 1061 "%s version %s\n\n"
1011 "usage:\n" 1062 "usage:\n"
1012 " %s record [-v][-e event [-f filter]][-p plugin][-F][-d][-o file][-s usecs][-O option ] [command ...]\n" 1063 " %s record [-v][-e event [-f filter]][-p plugin][-F][-d][-o file] \\\n"
1064 " [-s usecs][-O option ][-l func][-g func][-n func][command ...]\n"
1013 " -e run command with event enabled\n" 1065 " -e run command with event enabled\n"
1014 " -f filter for previous -e event\n" 1066 " -f filter for previous -e event\n"
1015 " -p run command with plugin enabled\n" 1067 " -p run command with plugin enabled\n"
1016 " -F filter only on the given process\n" 1068 " -F filter only on the given process\n"
1069 " -l filter function name\n"
1070 " -g set graph function\n"
1071 " -n do not trace function\n"
1017 " -v will negate all -e after it (disable those events)\n" 1072 " -v will negate all -e after it (disable those events)\n"
1018 " -d disable function tracer when running\n" 1073 " -d disable function tracer when running\n"
1019 " -o data output file [default trace.dat]\n" 1074 " -o data output file [default trace.dat]\n"
@@ -1105,7 +1160,7 @@ int main (int argc, char **argv)
1105 (strcmp(argv[1], "start") == 0) || 1160 (strcmp(argv[1], "start") == 0) ||
1106 ((extract = strcmp(argv[1], "extract") == 0))) { 1161 ((extract = strcmp(argv[1], "extract") == 0))) {
1107 1162
1108 while ((c = getopt(argc-1, argv+1, "+he:f:Fp:do:O:s:v")) >= 0) { 1163 while ((c = getopt(argc-1, argv+1, "+he:f:Fp:do:O:s:vg:l:n:")) >= 0) {
1109 switch (c) { 1164 switch (c) {
1110 case 'h': 1165 case 'h':
1111 usage(argv); 1166 usage(argv);
@@ -1150,6 +1205,15 @@ int main (int argc, char **argv)
1150 usage(argv); 1205 usage(argv);
1151 neg_event = 1; 1206 neg_event = 1;
1152 break; 1207 break;
1208 case 'l':
1209 add_func(&filter_funcs, optarg);
1210 break;
1211 case 'n':
1212 add_func(&notrace_funcs, optarg);
1213 break;
1214 case 'g':
1215 add_func(&graph_funcs, optarg);
1216 break;
1153 case 'p': 1217 case 'p':
1154 if (plugin) 1218 if (plugin)
1155 die("only one plugin allowed"); 1219 die("only one plugin allowed");
@@ -1254,6 +1318,7 @@ int main (int argc, char **argv)
1254 if (!extract) { 1318 if (!extract) {
1255 fset = set_ftrace(!disable); 1319 fset = set_ftrace(!disable);
1256 disable_all(); 1320 disable_all();
1321 set_funcs();
1257 1322
1258 if (events) 1323 if (events)
1259 enable_events(); 1324 enable_events();