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!