[lttng-dev] [RFC PATCH lttng-ust] Produce section with tracepoint callsite addresses
Mathieu Desnoyers
mathieu.desnoyers at efficios.com
Mon Sep 14 14:16:09 EDT 2015
----- On Sep 2, 2015, at 5:49 PM, Simon Marchi simon.marchi at polymtl.ca wrote:
> There used to be an integration between lttng-ust 0.x and gdb, where gdb
> could list locations of ust tracepoints and put its own tracepoints
> there. That means that this old-style lttng-ust marker:
>
> trace_mark(ust, bar33, "str %s", "FOOBAZ");
>
> could be used to set a gdb tracepoint like this:
>
> (gdb) strace -m ust/bar33
>
> Later, support for SystemTap and DTrace tracepoints was added in the
> form of probe points. Therefore, it's possible to list static probes
> found in the program like this:
>
> (gdb) info probes
> Type Provider Name Where Semaphore Object
> stap ze_provider ze_tracepoint 0x00000000004004f1
>
> It's then possible to do many fun things with it, including setting a
> breakpoint at its location:
>
> (gdb) b -probe ze_provider:ze_tracepoint
> Breakpoint 1 at 0x4004f1
>
> I'd like if gdb was able to do the same for lttng-ust tracepoints.
> Currently, you can make lttng-ust's tracepoint appear as SystemTap
> probes (--with-sdt), so one could argue that it already works, but it
> would be preferrable to have "native" support.
Indeed.
>
> This patch adds a section in the ELF (__lttng_callsites) and records
> pairs of pointers in it:
>
> <address of corresponding struct tracepoint> <callsite address>
>
> so that it's possible to determine where each tracepoint is used (and
> supporting tracepoints being called at multiple locations). I made a
> prototype of gdb that reads the content of this section, available here:
>
> https://github.com/simark/binutils-gdb.git
>
> This is the result (not very exciting, but still):
>
> (gdb) info probes
> Type Provider Name Where Semaphore Object
> lttng sample_component message 0x0000000000400ced n/a
> /home/emaisin/build/lttng-ust/doc/examples/easy-ust/sample
>
> I'd like to know what you think about the way the information is laid
> out in the ELF. What should I be concerned about, especially in terms of
> future-proofing and portability? One thing I am aware of is that the
> use of an 8 bytes pointer for 32-bits architectures is not optimal (we
> are wasting _4 bytes_ every time), but I couldn't find a way to tell gas
> "push a data word the size of a pointer". We would probably have to
> get an architecture-specific macro to define the right assembler
> directive for a pointer.
>
> Thanks in advance for the comments!
We should probably handle tracelog() and tracef() instrumentation
facilities too.
About the 32 vs 64-bit: the Linux kernel has a macro called ASM_PTR()
which does something like this. Basically, use preprocessor ifdefs
to find out the size of long, and define a ASM_PTR with the right
string result accordingly. Then use this macro in the assembly.
See liburcu CAA_BITS_PER_LONG which can be used for this.
> ---
> include/lttng/tracepoint.h | 16 +++++++++++++++-
> 1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h
> index 4bc4fc9..04d3aa6 100644
> --- a/include/lttng/tracepoint.h
> +++ b/include/lttng/tracepoint.h
> @@ -53,13 +53,17 @@ extern "C" {
>
> #define tracepoint(provider, name, ...) \
> do { \
> + asm(".pushsection __lttng_callsites, \"a\", @progbits\n" \
> + ".8byte __tracepoint_" #provider "___" #name "\n" \
> + ".8byte 456f\n" \
Why 456 ? Could it simply be 1f ? It's relative to this asm snippet anyway,
so I'm not sure why we would care about number clashes.
> + " .popsection\n" \
> + "456:\n"); \
> STAP_PROBEV(provider, name, ## __VA_ARGS__); \
> if (tracepoint_enabled(provider, name)) \
> do_tracepoint(provider, name, __VA_ARGS__); \
> } while (0)
>
> #define TP_ARGS(...) __VA_ARGS__
> -
> /*
> * TP_ARGS takes tuples of type, argument separated by a comma.
> * It can take up to 10 tuples (which means that less than 10 tuples is
> @@ -323,6 +327,16 @@ extern struct lttng_ust_tracepoint * const
> __start___tracepoints_ptrs[]
> __attribute__((weak, visibility("hidden")));
> extern struct lttng_ust_tracepoint * const __stop___tracepoints_ptrs[]
> __attribute__((weak, visibility("hidden")));
> +extern void * const __start___lttng_callsites[]
> + __attribute__((weak, visibility("hidden")));
> +extern void * const __stop___lttng_callsites[]
If it's specific to lttng tracepoints, the name should say so. E.g.
we may need something else for lttng tracef and tracelog.
> + __attribute__((weak, visibility("hidden")));
> +
> +/*
> + * Make sure __start/stop__lttng_callsites symbols are generated.
> + */
> +static const void * const ___start__lttng_callsites __attribute__((used)) =
> __start___lttng_callsites;
> +static const void * const ___stop__lttng_callsites __attribute__((used)) =
> __stop___lttng_callsites;
Did you test this in various build configurations ?
- Executable with single instrumented .o,
- Executable with many instrumented .o,
- .so with one instrumented .o,
- .so with many .o,
- Instrumented exec + lib.
We should add those tests into lttng-ust.
Thanks,
Mathieu
>
> /*
> * When TRACEPOINT_PROBE_DYNAMIC_LINKAGE is defined, we do not emit a
> --
> 2.5.1
>
>
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list