diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-11-24 22:10:30 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2009-11-24 22:10:30 -0500 |
commit | 3bb8ccb5259374234647376fbf776f973c39643f (patch) | |
tree | fee6a1e6c013f224d6574202efbdd4c24f3692ff | |
parent | c1f23506e61a6f1045a1a3fc3aac6fca39309047 (diff) |
Allow for reading of the format fields of an event by a plugin
Plugins need to find information about the format fields like the
offset and size of the field.
Added: pevent_find_field(event, name)
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | parse-events.c | 38 | ||||
-rw-r--r-- | parse-events.h | 3 | ||||
-rw-r--r-- | test_plugin.c | 56 |
3 files changed, 71 insertions, 26 deletions
diff --git a/parse-events.c b/parse-events.c index 1527c2b..f7b8bce 100644 --- a/parse-events.c +++ b/parse-events.c | |||
@@ -48,8 +48,6 @@ static unsigned long long input_buf_siz; | |||
48 | static int cpus; | 48 | static int cpus; |
49 | static int long_size; | 49 | static int long_size; |
50 | 50 | ||
51 | static struct format_field *find_field(struct event *event, const char *name); | ||
52 | |||
53 | static void init_input_buf(char *buf, unsigned long long size) | 51 | static void init_input_buf(char *buf, unsigned long long size) |
54 | { | 52 | { |
55 | input_buf = buf; | 53 | input_buf = buf; |
@@ -1728,7 +1726,7 @@ process_dynamic_array(struct event *event, struct print_arg *arg, char **tok) | |||
1728 | 1726 | ||
1729 | /* Find the field */ | 1727 | /* Find the field */ |
1730 | 1728 | ||
1731 | field = find_field(event, token); | 1729 | field = pevent_find_field(event, token); |
1732 | if (!field) | 1730 | if (!field) |
1733 | return EVENT_ERROR; | 1731 | return EVENT_ERROR; |
1734 | 1732 | ||
@@ -2041,8 +2039,8 @@ find_common_field(struct event *event, const char *name) | |||
2041 | return format; | 2039 | return format; |
2042 | } | 2040 | } |
2043 | 2041 | ||
2044 | static struct format_field * | 2042 | struct format_field * |
2045 | find_field(struct event *event, const char *name) | 2043 | pevent_find_field(struct event *event, const char *name) |
2046 | { | 2044 | { |
2047 | struct format_field *format; | 2045 | struct format_field *format; |
2048 | 2046 | ||
@@ -2063,7 +2061,7 @@ find_any_field(struct event *event, const char *name) | |||
2063 | format = find_common_field(event, name); | 2061 | format = find_common_field(event, name); |
2064 | if (format) | 2062 | if (format) |
2065 | return format; | 2063 | return format; |
2066 | return find_field(event, name); | 2064 | return pevent_find_field(event, name); |
2067 | } | 2065 | } |
2068 | 2066 | ||
2069 | static unsigned long long read_size(void *ptr, int size) | 2067 | static unsigned long long read_size(void *ptr, int size) |
@@ -2498,10 +2496,10 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
2498 | void *bptr; | 2496 | void *bptr; |
2499 | 2497 | ||
2500 | if (!field) { | 2498 | if (!field) { |
2501 | field = find_field(event, "buf"); | 2499 | field = pevent_find_field(event, "buf"); |
2502 | if (!field) | 2500 | if (!field) |
2503 | die("can't find buffer field for binary printk"); | 2501 | die("can't find buffer field for binary printk"); |
2504 | ip_field = find_field(event, "ip"); | 2502 | ip_field = pevent_find_field(event, "ip"); |
2505 | if (!ip_field) | 2503 | if (!ip_field) |
2506 | die("can't find ip field for binary printk"); | 2504 | die("can't find ip field for binary printk"); |
2507 | } | 2505 | } |
@@ -2612,7 +2610,7 @@ get_bprint_format(void *data, int size __unused, struct event *event) | |||
2612 | char *p; | 2610 | char *p; |
2613 | 2611 | ||
2614 | if (!field) { | 2612 | if (!field) { |
2615 | field = find_field(event, "fmt"); | 2613 | field = pevent_find_field(event, "fmt"); |
2616 | if (!field) | 2614 | if (!field) |
2617 | die("can't find format field for binary printk"); | 2615 | die("can't find format field for binary printk"); |
2618 | printf("field->offset = %d size=%d\n", field->offset, field->size); | 2616 | printf("field->offset = %d size=%d\n", field->offset, field->size); |
@@ -2941,7 +2939,7 @@ get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func, | |||
2941 | return NULL; | 2939 | return NULL; |
2942 | 2940 | ||
2943 | pid = parse_common_pid(next->data); | 2941 | pid = parse_common_pid(next->data); |
2944 | field = find_field(event, "func"); | 2942 | field = pevent_find_field(event, "func"); |
2945 | if (!field) | 2943 | if (!field) |
2946 | die("function return does not have field func"); | 2944 | die("function return does not have field func"); |
2947 | 2945 | ||
@@ -3022,12 +3020,12 @@ print_graph_entry_leaf(struct trace_seq *s, | |||
3022 | type = trace_parse_common_type(ret_rec->data); | 3020 | type = trace_parse_common_type(ret_rec->data); |
3023 | ret_event = trace_find_event(type); | 3021 | ret_event = trace_find_event(type); |
3024 | 3022 | ||
3025 | field = find_field(ret_event, "rettime"); | 3023 | field = pevent_find_field(ret_event, "rettime"); |
3026 | if (!field) | 3024 | if (!field) |
3027 | die("can't find rettime in return graph"); | 3025 | die("can't find rettime in return graph"); |
3028 | rettime = read_size(ret_rec->data + field->offset, field->size); | 3026 | rettime = read_size(ret_rec->data + field->offset, field->size); |
3029 | 3027 | ||
3030 | field = find_field(ret_event, "calltime"); | 3028 | field = pevent_find_field(ret_event, "calltime"); |
3031 | if (!field) | 3029 | if (!field) |
3032 | die("can't find rettime in return graph"); | 3030 | die("can't find rettime in return graph"); |
3033 | calltime = read_size(ret_rec->data + field->offset, field->size); | 3031 | calltime = read_size(ret_rec->data + field->offset, field->size); |
@@ -3040,7 +3038,7 @@ print_graph_entry_leaf(struct trace_seq *s, | |||
3040 | /* Duration */ | 3038 | /* Duration */ |
3041 | print_graph_duration(s, duration); | 3039 | print_graph_duration(s, duration); |
3042 | 3040 | ||
3043 | field = find_field(event, "depth"); | 3041 | field = pevent_find_field(event, "depth"); |
3044 | if (!field) | 3042 | if (!field) |
3045 | die("can't find depth in entry graph"); | 3043 | die("can't find depth in entry graph"); |
3046 | depth = read_size(data + field->offset, field->size); | 3044 | depth = read_size(data + field->offset, field->size); |
@@ -3049,7 +3047,7 @@ print_graph_entry_leaf(struct trace_seq *s, | |||
3049 | for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++) | 3047 | for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++) |
3050 | trace_seq_putc(s, ' '); | 3048 | trace_seq_putc(s, ' '); |
3051 | 3049 | ||
3052 | field = find_field(event, "func"); | 3050 | field = pevent_find_field(event, "func"); |
3053 | if (!field) | 3051 | if (!field) |
3054 | die("can't find func in entry graph"); | 3052 | die("can't find func in entry graph"); |
3055 | val = read_size(data + field->offset, field->size); | 3053 | val = read_size(data + field->offset, field->size); |
@@ -3076,7 +3074,7 @@ static void print_graph_nested(struct trace_seq *s, | |||
3076 | /* No time */ | 3074 | /* No time */ |
3077 | trace_seq_puts(s, " | "); | 3075 | trace_seq_puts(s, " | "); |
3078 | 3076 | ||
3079 | field = find_field(event, "depth"); | 3077 | field = pevent_find_field(event, "depth"); |
3080 | if (!field) | 3078 | if (!field) |
3081 | die("can't find depth in entry graph"); | 3079 | die("can't find depth in entry graph"); |
3082 | depth = read_size(data + field->offset, field->size); | 3080 | depth = read_size(data + field->offset, field->size); |
@@ -3085,7 +3083,7 @@ static void print_graph_nested(struct trace_seq *s, | |||
3085 | for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++) | 3083 | for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++) |
3086 | trace_seq_putc(s, ' '); | 3084 | trace_seq_putc(s, ' '); |
3087 | 3085 | ||
3088 | field = find_field(event, "func"); | 3086 | field = pevent_find_field(event, "func"); |
3089 | if (!field) | 3087 | if (!field) |
3090 | die("can't find func in entry graph"); | 3088 | die("can't find func in entry graph"); |
3091 | val = read_size(data + field->offset, field->size); | 3089 | val = read_size(data + field->offset, field->size); |
@@ -3120,7 +3118,7 @@ pretty_print_func_ent(struct trace_seq *s, | |||
3120 | trace_seq_puts(s, " | "); | 3118 | trace_seq_puts(s, " | "); |
3121 | } | 3119 | } |
3122 | 3120 | ||
3123 | field = find_field(event, "func"); | 3121 | field = pevent_find_field(event, "func"); |
3124 | if (!field) | 3122 | if (!field) |
3125 | die("function entry does not have func field"); | 3123 | die("function entry does not have func field"); |
3126 | 3124 | ||
@@ -3169,12 +3167,12 @@ pretty_print_func_ret(struct trace_seq *s, | |||
3169 | trace_seq_puts(s, " | "); | 3167 | trace_seq_puts(s, " | "); |
3170 | } | 3168 | } |
3171 | 3169 | ||
3172 | field = find_field(event, "rettime"); | 3170 | field = pevent_find_field(event, "rettime"); |
3173 | if (!field) | 3171 | if (!field) |
3174 | die("can't find rettime in return graph"); | 3172 | die("can't find rettime in return graph"); |
3175 | rettime = read_size(data + field->offset, field->size); | 3173 | rettime = read_size(data + field->offset, field->size); |
3176 | 3174 | ||
3177 | field = find_field(event, "calltime"); | 3175 | field = pevent_find_field(event, "calltime"); |
3178 | if (!field) | 3176 | if (!field) |
3179 | die("can't find calltime in return graph"); | 3177 | die("can't find calltime in return graph"); |
3180 | calltime = read_size(data + field->offset, field->size); | 3178 | calltime = read_size(data + field->offset, field->size); |
@@ -3187,7 +3185,7 @@ pretty_print_func_ret(struct trace_seq *s, | |||
3187 | /* Duration */ | 3185 | /* Duration */ |
3188 | print_graph_duration(s, duration); | 3186 | print_graph_duration(s, duration); |
3189 | 3187 | ||
3190 | field = find_field(event, "depth"); | 3188 | field = pevent_find_field(event, "depth"); |
3191 | if (!field) | 3189 | if (!field) |
3192 | die("can't find depth in entry graph"); | 3190 | die("can't find depth in entry graph"); |
3193 | depth = read_size(data + field->offset, field->size); | 3191 | depth = read_size(data + field->offset, field->size); |
diff --git a/parse-events.h b/parse-events.h index a29c295..ff597ef 100644 --- a/parse-events.h +++ b/parse-events.h | |||
@@ -299,6 +299,9 @@ int pevent_parse_event(char *buf, unsigned long size, char *sys); | |||
299 | int pevent_register_event_handler(int id, char *sys_name, char *event_name, | 299 | int pevent_register_event_handler(int id, char *sys_name, char *event_name, |
300 | pevent_event_handler_func func); | 300 | pevent_event_handler_func func); |
301 | 301 | ||
302 | struct format_field *pevent_find_field(struct event *event, const char *name); | ||
303 | |||
304 | |||
302 | /* for debugging */ | 305 | /* for debugging */ |
303 | void pevent_print_funcs(void); | 306 | void pevent_print_funcs(void); |
304 | void pevent_print_printk(void); | 307 | void pevent_print_printk(void); |
diff --git a/test_plugin.c b/test_plugin.c index 3a23556..802c7e0 100644 --- a/test_plugin.c +++ b/test_plugin.c | |||
@@ -4,13 +4,36 @@ | |||
4 | 4 | ||
5 | #include "parse-events.h" | 5 | #include "parse-events.h" |
6 | 6 | ||
7 | static int get_offset(struct trace_seq *s, struct event *event, char *name) | ||
8 | { | ||
9 | struct format_field *field; | ||
10 | |||
11 | field = pevent_find_field(event, name); | ||
12 | if (field) | ||
13 | return field->offset; | ||
14 | |||
15 | trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name); | ||
16 | return -1; | ||
17 | } | ||
18 | |||
7 | static int timer_expire_handler(struct trace_seq *s, void *data, int size, | 19 | static int timer_expire_handler(struct trace_seq *s, void *data, int size, |
8 | struct event *event) | 20 | struct event *event) |
9 | { | 21 | { |
10 | void *hrtimer = data + 16; | 22 | void *hrtimer; |
11 | long long now = *(long long *)(data + 24); | 23 | long long now; |
24 | int offset; | ||
12 | int ret; | 25 | int ret; |
13 | 26 | ||
27 | offset = get_offset(s, event, "hrtimer"); | ||
28 | if (offset < 0) | ||
29 | return 0; | ||
30 | hrtimer = *(void **)(data + offset); | ||
31 | |||
32 | offset = get_offset(s, event, "now"); | ||
33 | if (offset < 0) | ||
34 | return 0; | ||
35 | now = *(long long *)(data + offset); | ||
36 | |||
14 | ret = trace_seq_printf(s, "hrtimer=%p now=%llu", | 37 | ret = trace_seq_printf(s, "hrtimer=%p now=%llu", |
15 | hrtimer, now); | 38 | hrtimer, now); |
16 | return ret; | 39 | return ret; |
@@ -19,12 +42,33 @@ static int timer_expire_handler(struct trace_seq *s, void *data, int size, | |||
19 | static int timer_start_handler(struct trace_seq *s, void *data, int size, | 42 | static int timer_start_handler(struct trace_seq *s, void *data, int size, |
20 | struct event *event) | 43 | struct event *event) |
21 | { | 44 | { |
22 | void *hrtimer = data + 16; | 45 | void *hrtimer; |
23 | void *function = data + 24; | 46 | void *function; |
24 | long long expires = *(long long *)(data + 32); | 47 | long long expires; |
25 | long long soft = *(long long *)(data + 40); | 48 | long long soft; |
49 | int offset; | ||
26 | int ret; | 50 | int ret; |
27 | 51 | ||
52 | offset = get_offset(s, event, "hrtimer"); | ||
53 | if (offset < 0) | ||
54 | return 0; | ||
55 | hrtimer = *(void **)(data + offset); | ||
56 | |||
57 | offset = get_offset(s, event, "function"); | ||
58 | if (offset < 0) | ||
59 | return 0; | ||
60 | function = *(void **)(data + offset); | ||
61 | |||
62 | offset = get_offset(s, event, "expires"); | ||
63 | if (offset < 0) | ||
64 | return 0; | ||
65 | expires = *(long long *)(data + offset); | ||
66 | |||
67 | offset = get_offset(s, event, "softexpires"); | ||
68 | if (offset < 0) | ||
69 | return 0; | ||
70 | soft = *(long long *)(data + offset); | ||
71 | |||
28 | ret = trace_seq_printf(s, "hrtimer=%p function=%pf expires=%llu softexpires=%llu", | 72 | ret = trace_seq_printf(s, "hrtimer=%p function=%pf expires=%llu softexpires=%llu", |
29 | hrtimer, function, | 73 | hrtimer, function, |
30 | expires, soft); | 74 | expires, soft); |