diff options
| author | Steven Rostedt <srostedt@redhat.com> | 2009-12-10 00:34:23 -0500 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2009-12-10 00:34:54 -0500 |
| commit | 82bf45c96fcf9cfe6fd2d99d39119475c8d3b590 (patch) | |
| tree | b1e79ec092f801bc2eaecbecca33a22504998a05 | |
| parent | 2d802a522d04d89fc9277cd5c79dafb7af62fae4 (diff) | |
Add override handler to handle kernel stack trace entry
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
| -rw-r--r-- | trace-ftrace.c | 43 |
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 | ||
| 7 | static struct event *fgraph_ret_event; | 7 | static struct event *fgraph_ret_event; |
| 8 | static int fgraph_ret_id; | 8 | static int fgraph_ret_id; |
| 9 | static int long_size; | ||
| 9 | 10 | ||
| 10 | static int get_field_val(struct trace_seq *s, void *data, | 11 | static 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 | ||
| 293 | static int | ||
| 294 | trace_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 | |||
| 292 | int tracecmd_ftrace_overrides(struct tracecmd_input *handle) | 330 | int 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 | ||
