LTTng is a framework to collect kernel tracepoint logs with low overhead (see 5.5 in Desnoyers’ thesis for eval). Instrumenting the kernel is done in two parts: adding a kernel tracepoint, and writing the LTTng adaptation layer. The process is documented in a section of the LTTng docs, however there are a few points that required fixing to make the adaptation layer work, detailed here.
The docs (at the time of writing of this post) show the following adaptation header:
#undef TRACE_SYSTEM #define TRACE_SYSTEM hello #if !defined(_TRACE_HELLO_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_HELLO_H #include <linux/tracepoint.h> LTTNG_TRACEPOINT_EVENT( /* format identical to mainline version for those */ hello_world, TP_PROTO(int foo, const char* bar), TP_ARGS(foo, bar), /* possible differences */ TP_STRUCT__entry( __field(int, my_int) __field(char, char0) __field(char, char1) __string(product, bar) ), /* notice the use of tp_assign()/tp_strcpy() and no semicolons */ TP_fast_assign( tp_assign(my_int, foo) tp_assign(char0, bar[0]) tp_assign(char1, bar[1]) tp_strcpy(product, bar) ), /* This one is actually not used by LTTng either, but must be * present for the moment. */ TP_printk("", 0) /* no semicolon after this either */ ) #endif /* other difference: do NOT include <trace/define_trace.h> */ #include "../../../probes/define_trace.h"
Correct #include
Compiling our module, with the described changes produced an error:
In file included from linux-stable-3.10-trace/include/linux/module.h:18:0, from lttng-modules/probes/lttng-probe-tracelight.c:1: lttng-modules/probes/../instrumentation/events/lttng-module/../../../probes/../instrumentation/events/lttng-module/tracelight.h:17:11: error: expected ‘)’ before ‘struct’ TP_PROTO(struct inet_sock *inet, size_t len), ^ linux-stable-3.10-trace/include/linux/tracepoint.h:107:27: note: in definition of macro ‘TP_PROTO’ #define TP_PROTO(args...) args ^
We fixed those by removing “#include <linux/tracepoint.h>” and instead adding “#include “../../../probes/lttng-tracepoint-event.h” as the first include.
Include guards
The next hurdle was many warnings that LTTNG_TRACEPOINT_EVENT is redefined:
In file included from lttng-modules/probes/../instrumentation/events/lttng-module/../../../probes/../instrumentation/events/lttng-module/tracelight.h:8:0, from lttng-modules/probes/../instrumentation/events/lttng-module/../../../probes/define_trace.h:129, from lttng-modules/probes/../instrumentation/events/lttng-module/tracelight.h:208, from lttng-modules/probes/lttng-probe-tracelight.c:14: /mnt/sdb1/yonch/unison/tracelight/lttng-modules/probes/../instrumentation/events/lttng-module/../../../probes/../instrumentation/events/lttng-module/../../../probes/lttng-tracepoint-event.h:38:0: warning: "LTTNG_TRACEPOINT_EVENT" redefined [enabled by default] #define LTTNG_TRACEPOINT_EVENT(name, proto, args, struct, assign, print) \ ^ In file included from lttng-modules/probes/../instrumentation/events/lttng-module/tracelight.h:208:0, from lttng-modules/probes/lttng-probe-tracelight.c:14: /mnt/sdb1/yonch/unison/tracelight/lttng-modules/probes/../instrumentation/events/lttng-module/../../../probes/define_trace.h:75:0: note: this is the location of the previous definition #define LTTNG_TRACEPOINT_EVENT(name, proto, args, tstruct, assign, print) ^
Other LTTng headers in lttng-modules have changed their include guards from the linux kernel’s tracepoint files. For example:
#if !defined(_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ)
versus LTTng:
#if !defined(LTTNG_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ)
Having separate macros to guard the kernel header and the LTTng adaptation header fixed the warnings.
Translating macros
Here’s a quick translation for some of the macros:
TRACE_EVENT = LTTNG_TRACEPOINT_EVENT
DECLARE_EVENT_CLASS = LTTNG_TRACEPOINT_EVENT_CLASS
DEFINE_EVENT = LTTNG_TRACEPOINT_EVENT_INSTANCE
Fixing semicolons
While the kernel tracepoints require a semicolon (;) after DEFINE_EVENT, these cause problems for LTTng, for example:
CC [M] lttng-modules/probes/lttng-probe-tracelight-udp.o In file included from lttng-modules/probes/../instrumentation/events/lttng-module/../../../probes/lttng-events.h:406:0, from lttng-modules/probes/../instrumentation/events/lttng-module/../../../probes/define_trace.h:136, from lttng-modules/probes/../instrumentation/events/lttng-module/tracelight_udp.h:83, from lttng-modules/probes/lttng-probe-tracelight-udp.c:14: lttng-modules/probes/../instrumentation/events/lttng-module/../../../probes/../instrumentation/events/lttng-module/tracelight_udp.h:45:2: error: expected expression before ‘;’ token ); ^ make[4]: *** [lttng-modules/probes/lttng-probe-tracelight-udp.o] Error 1
Removing all semicolons after the LTTNG_TRACEPOINT_* macros fixes this.
Multiple adaptation headers in one lttng-probe-*.c file – doesn’t work
Not everyone might encounter this, but if you’re trying to #include multiple LTTng adaptation headers in one file, this does not seem to be supported (at least not in the git repo of mid-January 2015). Both cases failed: (1) multiple headers are included for the same TRACE_SYSTEM (2) multiple headers with different TRACE_SYSTEMs. The macros redefine some functions, causing a compile error. FYI!
Happy LTTng’ing!