Since Linux v3.15 (specifically, the following commit), the event name is
optionally moved to another structure.
commit de7b2973903c6cc50b31ee5682a69b2219b9919d
Author: Mathieu Desnoyers <mathieu.desnoyers(a)efficios.com>
Date: Tue Apr 8 17:26:21 2014 -0400
tracepoint: Use struct pointer instead of name hash for reg/unreg tracepoints
- char *name;
+ union {
+ char *name;
+ /* Set TRACE_EVENT_FL_TRACEPOINT flag when using "tp" */
+ struct tracepoint *tp;
+ };
This patch handles this in the trace extension so that both kernels with and
without that commit work.
---
extensions/trace.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 42 insertions(+), 4 deletions(-)
diff --git a/extensions/trace.c b/extensions/trace.c
index a09f6a1..8639fb2 100644
--- a/extensions/trace.c
+++ b/extensions/trace.c
@@ -988,19 +988,42 @@ static void ftrace_destroy_event_types(void)
free(ftrace_common_fields);
}
+#define TRACE_EVENT_FL_TRACEPOINT 0x40
+
static
int ftrace_get_event_type_name(ulong call, char *name, int len)
{
static int inited;
static int name_offset;
+ static int flags_offset;
+ static int tp_name_offset;
+ uint flags;
ulong name_addr;
- if (!inited) {
- inited = 1;
- name_offset = MEMBER_OFFSET("ftrace_event_call", "name");
- }
+ if (inited)
+ goto work;
+
+ inited = 1;
+ name_offset = MEMBER_OFFSET("ftrace_event_call", "name");
+ if (name_offset >= 0)
+ goto work;
+ name_offset = ANON_MEMBER_OFFSET("ftrace_event_call", "name");
+ if (name_offset < 0)
+ return -1;
+
+ flags_offset = MEMBER_OFFSET("ftrace_event_call", "flags");
+ if (flags_offset < 0)
+ return -1;
+
+ tp_name_offset = MEMBER_OFFSET("tracepoint", "name");
+ if (tp_name_offset < 0)
+ return -1;
+
+ inited = 2;
+
+work:
if (name_offset < 0)
return -1;
@@ -1008,6 +1031,21 @@ int ftrace_get_event_type_name(ulong call, char *name, int len)
"read ftrace_event_call name_addr", RETURN_ON_ERROR))
return -1;
+ if (inited == 2) {
+ if (!readmem(call + flags_offset, KVADDR, &flags,
+ sizeof(flags), "read ftrace_event_call flags",
+ RETURN_ON_ERROR))
+ return -1;
+
+ if (flags & TRACE_EVENT_FL_TRACEPOINT) {
+ if (!readmem(name_addr + tp_name_offset, KVADDR,
+ &name_addr, sizeof(name_addr),
+ "read tracepoint name", RETURN_ON_ERROR))
+ return -1;
+ }
+
+ }
+
if (!read_string(name_addr, name, len))
return -1;
--
2.1.4