diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-12-31 17:16:18 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2009-12-31 17:20:52 -0500 |
commit | 05e0559ecaff29d65a478e85addef12cf9d1a81b (patch) | |
tree | 70a7d5751d197849a9c7a6fce15d7b8e09caa09d | |
parent | 4fe3fea9f09815461b40427c3c68f9cd62ef538c (diff) |
trace-cmd: Add plugin_kmem for showing function names of call sites
The kmem events only show a useless hex symbol for the call site name.
This adds a plugin to do a lookup of the function name and still
print the rest of the event format.
Also adds pevent_find_function_address() to let the plugin show the
offset into the function as well.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | Makefile | 18 | ||||
-rw-r--r-- | parse-events.c | 21 | ||||
-rw-r--r-- | parse-events.h | 2 | ||||
-rw-r--r-- | plugin_kmem.c | 56 |
4 files changed, 92 insertions, 5 deletions
@@ -9,8 +9,10 @@ LIBS = -L. -ltracecmd -ldl | |||
9 | %.o: %.c | 9 | %.o: %.c |
10 | $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@ | 10 | $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@ |
11 | 11 | ||
12 | TARGETS = libparsevent.a libtracecmd.a trace-cmd plugin_hrtimer.so plugin_mac80211.so \ | 12 | PLUGINS = plugin_hrtimer.so plugin_mac80211.so plugin_sched_switch.so \ |
13 | plugin_sched_switch.so | 13 | plugin_kmem.so |
14 | |||
15 | TARGETS = libparsevent.a libtracecmd.a trace-cmd $(PLUGINS) | ||
14 | 16 | ||
15 | all: $(TARGETS) | 17 | all: $(TARGETS) |
16 | 18 | ||
@@ -65,19 +67,25 @@ libtracecmd.so: $(TCMD_LIB_OBJS) | |||
65 | libtracecmd.a: $(TCMD_LIB_OBJS) | 67 | libtracecmd.a: $(TCMD_LIB_OBJS) |
66 | $(RM) $@; $(AR) rcs $@ $^ | 68 | $(RM) $@; $(AR) rcs $@ $^ |
67 | 69 | ||
68 | plugin_hrtimer.o: plugin_hrtimer.c parse-events.h | 70 | plugin_hrtimer.o: plugin_hrtimer.c parse-events.h trace-cmd.h |
69 | $(CC) -c $(CFLAGS) -fPIC -o $@ $< | 71 | $(CC) -c $(CFLAGS) -fPIC -o $@ $< |
70 | 72 | ||
71 | plugin_hrtimer.so: plugin_hrtimer.o | 73 | plugin_hrtimer.so: plugin_hrtimer.o |
72 | $(CC) -shared -nostartfiles -o $@ $< | 74 | $(CC) -shared -nostartfiles -o $@ $< |
73 | 75 | ||
74 | plugin_sched_switch.o: plugin_sched_switch.c parse-events.h | 76 | plugin_kmem.o: plugin_kmem.c parse-events.h trace-cmd.h |
77 | $(CC) -c $(CFLAGS) -fPIC -o $@ $< | ||
78 | |||
79 | plugin_kmem.so: plugin_kmem.o | ||
80 | $(CC) -shared -nostartfiles -o $@ $< | ||
81 | |||
82 | plugin_sched_switch.o: plugin_sched_switch.c parse-events.h trace-cmd.h | ||
75 | $(CC) -c $(CFLAGS) -fPIC -o $@ $< | 83 | $(CC) -c $(CFLAGS) -fPIC -o $@ $< |
76 | 84 | ||
77 | plugin_sched_switch.so: plugin_sched_switch.o | 85 | plugin_sched_switch.so: plugin_sched_switch.o |
78 | $(CC) -shared -nostartfiles -o $@ $< | 86 | $(CC) -shared -nostartfiles -o $@ $< |
79 | 87 | ||
80 | plugin_mac80211.o: plugin_mac80211.c parse-events.h | 88 | plugin_mac80211.o: plugin_mac80211.c parse-events.h trace-cmd.h |
81 | $(CC) -c $(CFLAGS) -fPIC -o $@ $< | 89 | $(CC) -c $(CFLAGS) -fPIC -o $@ $< |
82 | 90 | ||
83 | plugin_mac80211.so: plugin_mac80211.o | 91 | plugin_mac80211.so: plugin_mac80211.o |
diff --git a/parse-events.c b/parse-events.c index d2d7e0a..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 | */ | ||
359 | unsigned long long | ||
360 | pevent_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 |
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 | |||
366 | struct format_field *pevent_find_any_field(struct event_format *event, const char *name); | 366 | struct format_field *pevent_find_any_field(struct event_format *event, const char *name); |
367 | 367 | ||
368 | const char *pevent_find_function(struct pevent *pevent, unsigned long long addr); | 368 | const char *pevent_find_function(struct pevent *pevent, unsigned long long addr); |
369 | unsigned long long | ||
370 | pevent_find_function_address(struct pevent *pevent, unsigned long long addr); | ||
369 | unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size); | 371 | unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size); |
370 | int pevent_read_number_field(struct format_field *field, const void *data, | 372 | int 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 | |||
7 | static 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 | |||
32 | int 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 | } | ||