diff options
author | Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com> | 2019-09-19 17:23:41 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-09-25 08:51:43 -0400 |
commit | 077faf3dc7cc13c3bd784613304bf38696b591da (patch) | |
tree | 89ad2a3e12bb8b225a9317c76b10d1f708b89254 /tools/lib/traceevent/plugins/plugin_function.c | |
parent | d69094f364d012f6d0be712969e6a6a355b69e84 (diff) |
libtraceevent: Move traceevent plugins in its own subdirectory
All traceevent plugins code is moved to tools/lib/traceevent/plugins
subdirectory. It makes traceevent implementation in trace-cmd and in
kernel tree consistent. There is no changes in the way libtraceevent and
plugins are compiled and installed.
Committer notes:
Applied fixup provided by Steven, fixing the tools/perf/Makefile.perf
target for the plugin dynamic list file. Problem noticed when cross
building to aarch64 from a Ubuntu 19.04 container.
Suggested-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
Cc: linux-trace-devel@vger.kernel.org
Link: http://lore.kernel.org/lkml/20190923115929.453b68f1@oasis.local.home
Link: http://lore.kernel.org/lkml/20190919212542.377333393@goodmis.org
Link: http://lore.kernel.org/linux-trace-devel/20190917105055.18983-1-tz.stoyanov@gmail.com
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/lib/traceevent/plugins/plugin_function.c')
-rw-r--r-- | tools/lib/traceevent/plugins/plugin_function.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/tools/lib/traceevent/plugins/plugin_function.c b/tools/lib/traceevent/plugins/plugin_function.c new file mode 100644 index 000000000000..7770fcb78e0f --- /dev/null +++ b/tools/lib/traceevent/plugins/plugin_function.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> | ||
3 | * | ||
4 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Lesser General Public | ||
7 | * License as published by the Free Software Foundation; | ||
8 | * version 2.1 of the License (not later!) | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Lesser General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public | ||
16 | * License along with this program; if not, see <http://www.gnu.org/licenses> | ||
17 | * | ||
18 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
19 | */ | ||
20 | #include <stdio.h> | ||
21 | #include <stdlib.h> | ||
22 | #include <string.h> | ||
23 | |||
24 | #include "event-parse.h" | ||
25 | #include "event-utils.h" | ||
26 | #include "trace-seq.h" | ||
27 | |||
28 | static struct func_stack { | ||
29 | int size; | ||
30 | char **stack; | ||
31 | } *fstack; | ||
32 | |||
33 | static int cpus = -1; | ||
34 | |||
35 | #define STK_BLK 10 | ||
36 | |||
37 | struct tep_plugin_option plugin_options[] = | ||
38 | { | ||
39 | { | ||
40 | .name = "parent", | ||
41 | .plugin_alias = "ftrace", | ||
42 | .description = | ||
43 | "Print parent of functions for function events", | ||
44 | }, | ||
45 | { | ||
46 | .name = "indent", | ||
47 | .plugin_alias = "ftrace", | ||
48 | .description = | ||
49 | "Try to show function call indents, based on parents", | ||
50 | .set = 1, | ||
51 | }, | ||
52 | { | ||
53 | .name = NULL, | ||
54 | } | ||
55 | }; | ||
56 | |||
57 | static struct tep_plugin_option *ftrace_parent = &plugin_options[0]; | ||
58 | static struct tep_plugin_option *ftrace_indent = &plugin_options[1]; | ||
59 | |||
60 | static void add_child(struct func_stack *stack, const char *child, int pos) | ||
61 | { | ||
62 | int i; | ||
63 | |||
64 | if (!child) | ||
65 | return; | ||
66 | |||
67 | if (pos < stack->size) | ||
68 | free(stack->stack[pos]); | ||
69 | else { | ||
70 | char **ptr; | ||
71 | |||
72 | ptr = realloc(stack->stack, sizeof(char *) * | ||
73 | (stack->size + STK_BLK)); | ||
74 | if (!ptr) { | ||
75 | warning("could not allocate plugin memory\n"); | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | stack->stack = ptr; | ||
80 | |||
81 | for (i = stack->size; i < stack->size + STK_BLK; i++) | ||
82 | stack->stack[i] = NULL; | ||
83 | stack->size += STK_BLK; | ||
84 | } | ||
85 | |||
86 | stack->stack[pos] = strdup(child); | ||
87 | } | ||
88 | |||
89 | static int add_and_get_index(const char *parent, const char *child, int cpu) | ||
90 | { | ||
91 | int i; | ||
92 | |||
93 | if (cpu < 0) | ||
94 | return 0; | ||
95 | |||
96 | if (cpu > cpus) { | ||
97 | struct func_stack *ptr; | ||
98 | |||
99 | ptr = realloc(fstack, sizeof(*fstack) * (cpu + 1)); | ||
100 | if (!ptr) { | ||
101 | warning("could not allocate plugin memory\n"); | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | fstack = ptr; | ||
106 | |||
107 | /* Account for holes in the cpu count */ | ||
108 | for (i = cpus + 1; i <= cpu; i++) | ||
109 | memset(&fstack[i], 0, sizeof(fstack[i])); | ||
110 | cpus = cpu; | ||
111 | } | ||
112 | |||
113 | for (i = 0; i < fstack[cpu].size && fstack[cpu].stack[i]; i++) { | ||
114 | if (strcmp(parent, fstack[cpu].stack[i]) == 0) { | ||
115 | add_child(&fstack[cpu], child, i+1); | ||
116 | return i; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | /* Not found */ | ||
121 | add_child(&fstack[cpu], parent, 0); | ||
122 | add_child(&fstack[cpu], child, 1); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int function_handler(struct trace_seq *s, struct tep_record *record, | ||
127 | struct tep_event *event, void *context) | ||
128 | { | ||
129 | struct tep_handle *tep = event->tep; | ||
130 | unsigned long long function; | ||
131 | unsigned long long pfunction; | ||
132 | const char *func; | ||
133 | const char *parent; | ||
134 | int index = 0; | ||
135 | |||
136 | if (tep_get_field_val(s, event, "ip", record, &function, 1)) | ||
137 | return trace_seq_putc(s, '!'); | ||
138 | |||
139 | func = tep_find_function(tep, function); | ||
140 | |||
141 | if (tep_get_field_val(s, event, "parent_ip", record, &pfunction, 1)) | ||
142 | return trace_seq_putc(s, '!'); | ||
143 | |||
144 | parent = tep_find_function(tep, pfunction); | ||
145 | |||
146 | if (parent && ftrace_indent->set) | ||
147 | index = add_and_get_index(parent, func, record->cpu); | ||
148 | |||
149 | trace_seq_printf(s, "%*s", index*3, ""); | ||
150 | |||
151 | if (func) | ||
152 | trace_seq_printf(s, "%s", func); | ||
153 | else | ||
154 | trace_seq_printf(s, "0x%llx", function); | ||
155 | |||
156 | if (ftrace_parent->set) { | ||
157 | trace_seq_printf(s, " <-- "); | ||
158 | if (parent) | ||
159 | trace_seq_printf(s, "%s", parent); | ||
160 | else | ||
161 | trace_seq_printf(s, "0x%llx", pfunction); | ||
162 | } | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | int TEP_PLUGIN_LOADER(struct tep_handle *tep) | ||
168 | { | ||
169 | tep_register_event_handler(tep, -1, "ftrace", "function", | ||
170 | function_handler, NULL); | ||
171 | |||
172 | tep_plugin_add_options("ftrace", plugin_options); | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | void TEP_PLUGIN_UNLOADER(struct tep_handle *tep) | ||
178 | { | ||
179 | int i, x; | ||
180 | |||
181 | tep_unregister_event_handler(tep, -1, "ftrace", "function", | ||
182 | function_handler, NULL); | ||
183 | |||
184 | for (i = 0; i <= cpus; i++) { | ||
185 | for (x = 0; x < fstack[i].size && fstack[i].stack[x]; x++) | ||
186 | free(fstack[i].stack[x]); | ||
187 | free(fstack[i].stack); | ||
188 | } | ||
189 | |||
190 | tep_plugin_remove_options(plugin_options); | ||
191 | |||
192 | free(fstack); | ||
193 | fstack = NULL; | ||
194 | cpus = -1; | ||
195 | } | ||