aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-12-10 00:34:23 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-12-10 00:34:54 -0500
commit82bf45c96fcf9cfe6fd2d99d39119475c8d3b590 (patch)
treeb1e79ec092f801bc2eaecbecca33a22504998a05
parent2d802a522d04d89fc9277cd5c79dafb7af62fae4 (diff)
Add override handler to handle kernel stack trace entry
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-ftrace.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/trace-ftrace.c b/trace-ftrace.c
index 68ac7a8..b1d420d 100644
--- a/trace-ftrace.c
+++ b/trace-ftrace.c
@@ -6,6 +6,7 @@
6 6
7static struct event *fgraph_ret_event; 7static struct event *fgraph_ret_event;
8static int fgraph_ret_id; 8static int fgraph_ret_id;
9static int long_size;
9 10
10static int get_field_val(struct trace_seq *s, void *data, 11static int get_field_val(struct trace_seq *s, void *data,
11 struct event *event, const char *name, 12 struct event *event, const char *name,
@@ -289,6 +290,43 @@ fgraph_ret_handler(struct trace_seq *s, void *data, int size,
289 return trace_seq_putc(s, '}'); 290 return trace_seq_putc(s, '}');
290} 291}
291 292
293static int
294trace_stack_handler(struct trace_seq *s, void *data, int size,
295 struct event *event, int cpu,
296 unsigned long long nsecs)
297{
298 struct format_field *field;
299 unsigned long long addr;
300 const char *func;
301 int ret;
302 int i;
303
304 field = pevent_find_any_field(event, "caller");
305 if (!field) {
306 trace_seq_printf(s, "<CANT FIND FIELD %s>", "caller");
307 return -1;
308 }
309
310 ret = trace_seq_puts(s, "<stack trace>\n");
311
312 for (i = 0; i < field->size; i += long_size) {
313 addr = pevent_read_number(event->pevent,
314 data + field->offset + i, long_size);
315
316 if ((long_size == 8 && addr == (unsigned long long)-1) ||
317 ((int)addr == -1))
318 break;
319
320 func = pevent_find_function(event->pevent, addr);
321 if (func)
322 ret = trace_seq_printf(s, "=> %s (%llx)\n", func, addr);
323 else
324 ret = trace_seq_printf(s, "=> %llx\n", addr);
325 }
326
327 return ret;
328}
329
292int tracecmd_ftrace_overrides(struct tracecmd_input *handle) 330int tracecmd_ftrace_overrides(struct tracecmd_input *handle)
293{ 331{
294 struct pevent *pevent; 332 struct pevent *pevent;
@@ -305,11 +343,16 @@ int tracecmd_ftrace_overrides(struct tracecmd_input *handle)
305 pevent_register_event_handler(pevent, -1, "ftrace", "funcgraph_exit", 343 pevent_register_event_handler(pevent, -1, "ftrace", "funcgraph_exit",
306 fgraph_ret_handler); 344 fgraph_ret_handler);
307 345
346 pevent_register_event_handler(pevent, -1, "ftrace", "kernel_stack",
347 trace_stack_handler);
348
308 /* Store the func ret id and event for later use */ 349 /* Store the func ret id and event for later use */
309 event = pevent_find_event_by_name(pevent, "ftrace", "funcgraph_exit"); 350 event = pevent_find_event_by_name(pevent, "ftrace", "funcgraph_exit");
310 if (!event) 351 if (!event)
311 return 0; 352 return 0;
312 353
354 long_size = tracecmd_long_size(handle);
355
313 fgraph_ret_id = event->id; 356 fgraph_ret_id = event->id;
314 fgraph_ret_event = event; 357 fgraph_ret_event = event;
315 358