diff options
-rw-r--r-- | Documentation/trace-cmd-record.1.txt | 7 | ||||
-rw-r--r-- | trace-record.c | 59 | ||||
-rw-r--r-- | trace-usage.c | 2 |
3 files changed, 67 insertions, 1 deletions
diff --git a/Documentation/trace-cmd-record.1.txt b/Documentation/trace-cmd-record.1.txt index 87e4f97..b78182a 100644 --- a/Documentation/trace-cmd-record.1.txt +++ b/Documentation/trace-cmd-record.1.txt | |||
@@ -64,6 +64,13 @@ OPTIONS | |||
64 | => cpu_idle (ffffffff8100a38c) | 64 | => cpu_idle (ffffffff8100a38c) |
65 | => start_secondary (ffffffff814ab828) | 65 | => start_secondary (ffffffff814ab828) |
66 | 66 | ||
67 | *--func-stack*:: | ||
68 | Enable a stack trace on all functions. Note this is only applicable | ||
69 | for the "function" plugin tracer, and will only take effect if the | ||
70 | -l option is used and succeeds in limiting functions. If the function | ||
71 | tracer is not filtered, and the stack trace is enabled, you can live | ||
72 | lock the machine. | ||
73 | |||
67 | *-f* 'filter':: | 74 | *-f* 'filter':: |
68 | Specify a filter for the previous event. This must come after a *-e*. This | 75 | Specify a filter for the previous event. This must come after a *-e*. This |
69 | will filter what events get recorded based on the content of the event. | 76 | will filter what events get recorded based on the content of the event. |
diff --git a/trace-record.c b/trace-record.c index 2a6872c..031e084 100644 --- a/trace-record.c +++ b/trace-record.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #define ITER_CTRL "trace_options" | 54 | #define ITER_CTRL "trace_options" |
55 | #define MAX_LATENCY "tracing_max_latency" | 55 | #define MAX_LATENCY "tracing_max_latency" |
56 | #define STAMP "stamp" | 56 | #define STAMP "stamp" |
57 | #define FUNC_STACK_TRACE "func_stack_trace" | ||
57 | 58 | ||
58 | #define UDP_MAX_PACKET (65536 - 20) | 59 | #define UDP_MAX_PACKET (65536 - 20) |
59 | 60 | ||
@@ -97,6 +98,8 @@ static struct func_list *filter_funcs; | |||
97 | static struct func_list *notrace_funcs; | 98 | static struct func_list *notrace_funcs; |
98 | static struct func_list *graph_funcs; | 99 | static struct func_list *graph_funcs; |
99 | 100 | ||
101 | static int func_stack; | ||
102 | |||
100 | struct filter_pids { | 103 | struct filter_pids { |
101 | struct filter_pids *next; | 104 | struct filter_pids *next; |
102 | int pid; | 105 | int pid; |
@@ -560,6 +563,7 @@ static void set_plugin(const char *name) | |||
560 | { | 563 | { |
561 | FILE *fp; | 564 | FILE *fp; |
562 | char *path; | 565 | char *path; |
566 | char zero = '0'; | ||
563 | 567 | ||
564 | path = tracecmd_get_tracing_file("current_tracer"); | 568 | path = tracecmd_get_tracing_file("current_tracer"); |
565 | fp = fopen(path, "w"); | 569 | fp = fopen(path, "w"); |
@@ -569,6 +573,16 @@ static void set_plugin(const char *name) | |||
569 | 573 | ||
570 | fwrite(name, 1, strlen(name), fp); | 574 | fwrite(name, 1, strlen(name), fp); |
571 | fclose(fp); | 575 | fclose(fp); |
576 | |||
577 | if (strncmp(name, "function", 8) != 0) | ||
578 | return; | ||
579 | |||
580 | /* Make sure func_stack_trace option is disabled */ | ||
581 | path = tracecmd_get_tracing_file("options/func_stack_trace"); | ||
582 | fp = fopen(path, "w"); | ||
583 | tracecmd_put_tracing_file(path); | ||
584 | fwrite(&zero, 1, 1, fp); | ||
585 | fclose(fp); | ||
572 | } | 586 | } |
573 | 587 | ||
574 | static void save_option(const char *option) | 588 | static void save_option(const char *option) |
@@ -1525,11 +1539,44 @@ static void write_func_file(const char *file, struct func_list **list) | |||
1525 | tracecmd_put_tracing_file(path); | 1539 | tracecmd_put_tracing_file(path); |
1526 | } | 1540 | } |
1527 | 1541 | ||
1542 | static int functions_filtered(void) | ||
1543 | { | ||
1544 | char buf[1] = { '#' }; | ||
1545 | char *path; | ||
1546 | int fd; | ||
1547 | |||
1548 | path = tracecmd_get_tracing_file("set_ftrace_filter"); | ||
1549 | fd = open(path, O_RDONLY); | ||
1550 | tracecmd_put_tracing_file(path); | ||
1551 | if (fd < 0) | ||
1552 | return 0; | ||
1553 | |||
1554 | /* | ||
1555 | * If functions are not filtered, than the first character | ||
1556 | * will be '#'. Make sure it is not an '#' and also not space. | ||
1557 | */ | ||
1558 | read(fd, buf, 1); | ||
1559 | close(fd); | ||
1560 | |||
1561 | if (buf[0] == '#' || isspace(buf[0])) | ||
1562 | return 0; | ||
1563 | return 1; | ||
1564 | } | ||
1565 | |||
1528 | static void set_funcs(void) | 1566 | static void set_funcs(void) |
1529 | { | 1567 | { |
1530 | write_func_file("set_ftrace_filter", &filter_funcs); | 1568 | write_func_file("set_ftrace_filter", &filter_funcs); |
1531 | write_func_file("set_ftrace_notrace", ¬race_funcs); | 1569 | write_func_file("set_ftrace_notrace", ¬race_funcs); |
1532 | write_func_file("set_graph_function", &graph_funcs); | 1570 | write_func_file("set_graph_function", &graph_funcs); |
1571 | |||
1572 | /* make sure we are filtering functions */ | ||
1573 | if (func_stack) { | ||
1574 | if (!functions_filtered()) { | ||
1575 | disable_all(); | ||
1576 | die("Function stack trace set, but functions not filtered"); | ||
1577 | } | ||
1578 | save_option(FUNC_STACK_TRACE); | ||
1579 | } | ||
1533 | } | 1580 | } |
1534 | 1581 | ||
1535 | static void add_func(struct func_list **list, const char *func) | 1582 | static void add_func(struct func_list **list, const char *func) |
@@ -1810,6 +1857,7 @@ static void record_all_events(void) | |||
1810 | } | 1857 | } |
1811 | 1858 | ||
1812 | enum { | 1859 | enum { |
1860 | OPT_funcstack = 254, | ||
1813 | OPT_date = 255, | 1861 | OPT_date = 255, |
1814 | }; | 1862 | }; |
1815 | 1863 | ||
@@ -1867,6 +1915,7 @@ void trace_record (int argc, char **argv) | |||
1867 | int option_index = 0; | 1915 | int option_index = 0; |
1868 | static struct option long_options[] = { | 1916 | static struct option long_options[] = { |
1869 | {"date", no_argument, NULL, OPT_date}, | 1917 | {"date", no_argument, NULL, OPT_date}, |
1918 | {"func-stack", no_argument, NULL, OPT_funcstack}, | ||
1870 | {"help", no_argument, NULL, '?'}, | 1919 | {"help", no_argument, NULL, '?'}, |
1871 | {NULL, 0, NULL, 0} | 1920 | {NULL, 0, NULL, 0} |
1872 | }; | 1921 | }; |
@@ -1957,7 +2006,8 @@ void trace_record (int argc, char **argv) | |||
1957 | case 'p': | 2006 | case 'p': |
1958 | if (plugin) | 2007 | if (plugin) |
1959 | die("only one plugin allowed"); | 2008 | die("only one plugin allowed"); |
1960 | plugin = optarg; | 2009 | for (plugin = optarg; isspace(*plugin); plugin++) |
2010 | ; | ||
1961 | fprintf(stderr, " plugin %s\n", plugin); | 2011 | fprintf(stderr, " plugin %s\n", plugin); |
1962 | break; | 2012 | break; |
1963 | case 'd': | 2013 | case 'd': |
@@ -2012,11 +2062,18 @@ void trace_record (int argc, char **argv) | |||
2012 | case OPT_date: | 2062 | case OPT_date: |
2013 | date = 1; | 2063 | date = 1; |
2014 | break; | 2064 | break; |
2065 | case OPT_funcstack: | ||
2066 | func_stack = 1; | ||
2067 | break; | ||
2015 | default: | 2068 | default: |
2016 | usage(argv); | 2069 | usage(argv); |
2017 | } | 2070 | } |
2018 | } | 2071 | } |
2019 | 2072 | ||
2073 | if (strncmp(plugin, "function", 8) == 0 && | ||
2074 | func_stack && !filter_funcs) | ||
2075 | die("Must supply function filtering with --func-stack\n"); | ||
2076 | |||
2020 | if (do_ptrace && !filter_task && (filter_pid < 0)) | 2077 | if (do_ptrace && !filter_task && (filter_pid < 0)) |
2021 | die(" -c can only be used with -F or -P"); | 2078 | die(" -c can only be used with -F or -P"); |
2022 | 2079 | ||
diff --git a/trace-usage.c b/trace-usage.c index 1ecc8fa..4b171fe 100644 --- a/trace-usage.c +++ b/trace-usage.c | |||
@@ -40,6 +40,8 @@ static struct usage_help usage_help[] = { | |||
40 | " -b change kernel buffersize (in kilobytes per CPU)\n" | 40 | " -b change kernel buffersize (in kilobytes per CPU)\n" |
41 | " -k do not reset the buffers after tracing.\n" | 41 | " -k do not reset the buffers after tracing.\n" |
42 | " -i do not fail if an event is not found\n" | 42 | " -i do not fail if an event is not found\n" |
43 | " --func-stack perform a stack trace for function tracer\n" | ||
44 | " (use with caution)\n" | ||
43 | }, | 45 | }, |
44 | { | 46 | { |
45 | "start", | 47 | "start", |