aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile19
-rw-r--r--parse-events.c34
-rw-r--r--parse-events.h2
-rw-r--r--plugin_kmem.c56
-rw-r--r--trace-ftrace.c22
5 files changed, 113 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index 6538c97..e879e90 100644
--- a/Makefile
+++ b/Makefile
@@ -18,8 +18,11 @@ CFLAGS = -g -Wall $(CONFIG_FLAGS)
18%.o: %.c 18%.o: %.c
19 $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@ 19 $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@
20 20
21TARGETS = libparsevent.a libtracecmd.a trace-cmd plugin_hrtimer.so plugin_mac80211.so \ 21PLUGINS = plugin_hrtimer.so plugin_mac80211.so plugin_sched_switch.so \
22 plugin_sched_switch.so trace-graph trace-view kernelshark 22 plugin_kmem.so
23
24TARGETS = libparsevent.a libtracecmd.a trace-cmd $(PLUGINS) \
25 trace-graph trace-view kernelshark
23 26
24all: $(TARGETS) 27all: $(TARGETS)
25 28
@@ -99,19 +102,25 @@ libtracecmd.so: $(TCMD_LIB_OBJS)
99libtracecmd.a: $(TCMD_LIB_OBJS) 102libtracecmd.a: $(TCMD_LIB_OBJS)
100 $(RM) $@; $(AR) rcs $@ $^ 103 $(RM) $@; $(AR) rcs $@ $^
101 104
102plugin_hrtimer.o: plugin_hrtimer.c parse-events.h 105plugin_hrtimer.o: plugin_hrtimer.c parse-events.h trace-cmd.h
103 $(CC) -c $(CFLAGS) -fPIC -o $@ $< 106 $(CC) -c $(CFLAGS) -fPIC -o $@ $<
104 107
105plugin_hrtimer.so: plugin_hrtimer.o 108plugin_hrtimer.so: plugin_hrtimer.o
106 $(CC) -shared -nostartfiles -o $@ $< 109 $(CC) -shared -nostartfiles -o $@ $<
107 110
108plugin_sched_switch.o: plugin_sched_switch.c parse-events.h 111plugin_kmem.o: plugin_kmem.c parse-events.h trace-cmd.h
112 $(CC) -c $(CFLAGS) -fPIC -o $@ $<
113
114plugin_kmem.so: plugin_kmem.o
115 $(CC) -shared -nostartfiles -o $@ $<
116
117plugin_sched_switch.o: plugin_sched_switch.c parse-events.h trace-cmd.h
109 $(CC) -c $(CFLAGS) -fPIC -o $@ $< 118 $(CC) -c $(CFLAGS) -fPIC -o $@ $<
110 119
111plugin_sched_switch.so: plugin_sched_switch.o 120plugin_sched_switch.so: plugin_sched_switch.o
112 $(CC) -shared -nostartfiles -o $@ $< 121 $(CC) -shared -nostartfiles -o $@ $<
113 122
114plugin_mac80211.o: plugin_mac80211.c parse-events.h 123plugin_mac80211.o: plugin_mac80211.c parse-events.h trace-cmd.h
115 $(CC) -c $(CFLAGS) -fPIC -o $@ $< 124 $(CC) -c $(CFLAGS) -fPIC -o $@ $<
116 125
117plugin_mac80211.so: plugin_mac80211.o 126plugin_mac80211.so: plugin_mac80211.o
diff --git a/parse-events.c b/parse-events.c
index 53aad3e..406b28f 100644
--- a/parse-events.c
+++ b/parse-events.c
@@ -348,6 +348,27 @@ const char *pevent_find_function(struct pevent *pevent, unsigned long long addr)
348} 348}
349 349
350/** 350/**
351 * pevent_find_function_address - find a function address by a given address
352 * @pevent: handle for the pevent
353 * @addr: the address to find the function with
354 *
355 * Returns the address the function starts at. This can be used in
356 * conjunction with pevent_find_function to print both the function
357 * name and the function offset.
358 */
359unsigned long long
360pevent_find_function_address(struct pevent *pevent, unsigned long long addr)
361{
362 struct func_map *map;
363
364 map = find_func(pevent, addr);
365 if (!map)
366 return 0;
367
368 return map->addr;
369}
370
371/**
351 * pevent_register_function - register a function with a given address 372 * pevent_register_function - register a function with a given address
352 * @pevent: handle for the pevent 373 * @pevent: handle for the pevent
353 * @function: the function name to register 374 * @function: the function name to register
@@ -3324,9 +3345,12 @@ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid)
3324void pevent_event_info(struct trace_seq *s, struct event_format *event, 3345void pevent_event_info(struct trace_seq *s, struct event_format *event,
3325 struct record *record) 3346 struct record *record)
3326{ 3347{
3348 int print_pretty = 1;
3349
3327 if (event->handler) 3350 if (event->handler)
3328 event->handler(s, record, event); 3351 print_pretty = event->handler(s, record, event);
3329 else 3352
3353 if (print_pretty)
3330 pretty_print(s, record->data, record->size, event); 3354 pretty_print(s, record->data, record->size, event);
3331 3355
3332 trace_seq_terminate(s); 3356 trace_seq_terminate(s);
@@ -3342,6 +3366,7 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
3342 const char *comm; 3366 const char *comm;
3343 void *data = record->data; 3367 void *data = record->data;
3344 int size = record->size; 3368 int size = record->size;
3369 int print_pretty = 1;
3345 int type; 3370 int type;
3346 int pid; 3371 int pid;
3347 int len; 3372 int len;
@@ -3376,8 +3401,9 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
3376 trace_seq_printf(s, "%.*s", 20 - len, spaces); 3401 trace_seq_printf(s, "%.*s", 20 - len, spaces);
3377 3402
3378 if (event->handler) 3403 if (event->handler)
3379 event->handler(s, record, event); 3404 print_pretty = event->handler(s, record, event);
3380 else 3405
3406 if (print_pretty)
3381 pretty_print(s, data, size, event); 3407 pretty_print(s, data, size, event);
3382 3408
3383 trace_seq_terminate(s); 3409 trace_seq_terminate(s);
diff --git a/parse-events.h b/parse-events.h
index bfbba5c..e148e7f 100644
--- a/parse-events.h
+++ b/parse-events.h
@@ -366,6 +366,8 @@ struct format_field *pevent_find_field(struct event_format *event, const char *n
366struct format_field *pevent_find_any_field(struct event_format *event, const char *name); 366struct format_field *pevent_find_any_field(struct event_format *event, const char *name);
367 367
368const char *pevent_find_function(struct pevent *pevent, unsigned long long addr); 368const char *pevent_find_function(struct pevent *pevent, unsigned long long addr);
369unsigned long long
370pevent_find_function_address(struct pevent *pevent, unsigned long long addr);
369unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size); 371unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size);
370int pevent_read_number_field(struct format_field *field, const void *data, 372int pevent_read_number_field(struct format_field *field, const void *data,
371 unsigned long long *value); 373 unsigned long long *value);
diff --git a/plugin_kmem.c b/plugin_kmem.c
new file mode 100644
index 0000000..d707bf2
--- /dev/null
+++ b/plugin_kmem.c
@@ -0,0 +1,56 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "trace-cmd.h"
6
7static int call_site_handler(struct trace_seq *s, struct record *record,
8 struct event_format *event)
9{
10 struct format_field *field;
11 unsigned long long val, addr;
12 void *data = record->data;
13 const char *func;
14
15 field = pevent_find_field(event, "call_site");
16 if (!field)
17 return 1;
18
19 if (pevent_read_number_field(field, data, &val))
20 return 1;
21
22 func = pevent_find_function(event->pevent, val);
23 if (!func)
24 return 1;
25 addr = pevent_find_function_address(event->pevent, val);
26
27 trace_seq_printf(s, "(%s+0x%x) ", func, (int)(val - addr));
28
29 return 1;
30}
31
32int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
33{
34 pevent_register_event_handler(pevent, -1, "kmem", "kfree",
35 call_site_handler);
36
37 pevent_register_event_handler(pevent, -1, "kmem", "kmalloc",
38 call_site_handler);
39
40 pevent_register_event_handler(pevent, -1, "kmem", "kmalloc_node",
41 call_site_handler);
42
43 pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_alloc",
44 call_site_handler);
45
46 pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_alloc_node",
47 call_site_handler);
48
49 pevent_register_event_handler(pevent, -1, "kmem", "kfree",
50 call_site_handler);
51
52 pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_free",
53 call_site_handler);
54
55 return 0;
56}
diff --git a/trace-ftrace.c b/trace-ftrace.c
index 1b79ec7..8b0646b 100644
--- a/trace-ftrace.c
+++ b/trace-ftrace.c
@@ -229,7 +229,6 @@ fgraph_ent_handler(struct trace_seq *s, struct record *record,
229 void *data = record->data; 229 void *data = record->data;
230 int size = record->size; 230 int size = record->size;
231 int cpu = record->cpu; 231 int cpu = record->cpu;
232 int ret;
233 232
234 if (get_field_val(s, data, event, "common_pid", &pid)) 233 if (get_field_val(s, data, event, "common_pid", &pid))
235 return trace_seq_putc(s, '!'); 234 return trace_seq_putc(s, '!');
@@ -257,15 +256,15 @@ fgraph_ent_handler(struct trace_seq *s, struct record *record,
257 * We also do a new peek on this CPU to update the 256 * We also do a new peek on this CPU to update the
258 * record cache. 257 * record cache.
259 */ 258 */
260 ret = print_graph_entry_leaf(s, event, data, rec); 259 print_graph_entry_leaf(s, event, data, rec);
261 free_record(rec); 260 free_record(rec);
262 tracecmd_peek_data(tracecmd_curr_thread_handle, cpu); 261 tracecmd_peek_data(tracecmd_curr_thread_handle, cpu);
263 } else 262 } else
264 ret = print_graph_nested(s, event, data); 263 print_graph_nested(s, event, data);
265 264
266 free(data); 265 free(data);
267 266
268 return ret; 267 return 0;
269} 268}
270 269
271static int 270static int
@@ -298,7 +297,9 @@ fgraph_ret_handler(struct trace_seq *s, struct record *record,
298 for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++) 297 for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++)
299 trace_seq_putc(s, ' '); 298 trace_seq_putc(s, ' ');
300 299
301 return trace_seq_putc(s, '}'); 300 trace_seq_putc(s, '}');
301
302 return 0;
302} 303}
303 304
304static int 305static int
@@ -309,16 +310,15 @@ trace_stack_handler(struct trace_seq *s, struct record *record,
309 unsigned long long addr; 310 unsigned long long addr;
310 const char *func; 311 const char *func;
311 void *data = record->data; 312 void *data = record->data;
312 int ret;
313 int i; 313 int i;
314 314
315 field = pevent_find_any_field(event, "caller"); 315 field = pevent_find_any_field(event, "caller");
316 if (!field) { 316 if (!field) {
317 trace_seq_printf(s, "<CANT FIND FIELD %s>", "caller"); 317 trace_seq_printf(s, "<CANT FIND FIELD %s>", "caller");
318 return -1; 318 return 0;
319 } 319 }
320 320
321 ret = trace_seq_puts(s, "<stack trace>\n"); 321 trace_seq_puts(s, "<stack trace>\n");
322 322
323 for (i = 0; i < field->size; i += long_size) { 323 for (i = 0; i < field->size; i += long_size) {
324 addr = pevent_read_number(event->pevent, 324 addr = pevent_read_number(event->pevent,
@@ -330,12 +330,12 @@ trace_stack_handler(struct trace_seq *s, struct record *record,
330 330
331 func = pevent_find_function(event->pevent, addr); 331 func = pevent_find_function(event->pevent, addr);
332 if (func) 332 if (func)
333 ret = trace_seq_printf(s, "=> %s (%llx)\n", func, addr); 333 trace_seq_printf(s, "=> %s (%llx)\n", func, addr);
334 else 334 else
335 ret = trace_seq_printf(s, "=> %llx\n", addr); 335 trace_seq_printf(s, "=> %llx\n", addr);
336 } 336 }
337 337
338 return ret; 338 return 0;
339} 339}
340 340
341int tracecmd_ftrace_overrides(struct tracecmd_input *handle) 341int tracecmd_ftrace_overrides(struct tracecmd_input *handle)