diff mbox series

[lttng-ust] Improve tracelog handling, reduce exported functions

Message ID 20210520121807.55428-1-nolange79@gmail.com
State New
Headers show
Series [lttng-ust] Improve tracelog handling, reduce exported functions | expand

Commit Message

Norbert Lange May 20, 2021, 12:18 p.m. UTC
Instead of creating functions for each loglevel, simply pass the
callback as argument.

Further pack all preprocessor information into a struct that
the compiler already can prepare.

Signed-off-by: Norbert Lange <nolange79 at gmail.com>
---
 include/lttng/tracelog.h     |  49 +++++--------
 src/lib/lttng-ust/tracelog.c | 130 +++++++++++++++--------------------
 2 files changed, 75 insertions(+), 104 deletions(-)

Comments

Mathieu Desnoyers May 20, 2021, 2:19 p.m. UTC | #1
----- On May 20, 2021, at 8:18 AM, lttng-dev lttng-dev at lists.lttng.org wrote:

> Instead of creating functions for each loglevel, simply pass the
> callback as argument.
> 
> Further pack all preprocessor information into a struct that
> the compiler already can prepare.

This introduces an ABI break too late in the cycle.

Also, I'm not so keen on adding an indirect call on the fast-path
when it's not absolutely needed.

What is wrong with having one symbol per loglevel ?

Thanks,

Mathieu

> 
> Signed-off-by: Norbert Lange <nolange79 at gmail.com>
> ---
> include/lttng/tracelog.h     |  49 +++++--------
> src/lib/lttng-ust/tracelog.c | 130 +++++++++++++++--------------------
> 2 files changed, 75 insertions(+), 104 deletions(-)
> 
> diff --git a/include/lttng/tracelog.h b/include/lttng/tracelog.h
> index e97c8275..cd5032e3 100644
> --- a/include/lttng/tracelog.h
> +++ b/include/lttng/tracelog.h
> @@ -14,51 +14,40 @@
> extern "C" {
> #endif
> 
> -#define LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(level)					\
> -	extern void lttng_ust__tracelog_##level(const char *file,	\
> -		int line, const char *func, const char *fmt, ...)	\
> -		__attribute__ ((format(printf, 4, 5)));			\
> -									\
> -	extern void lttng_ust__vtracelog_##level(const char *file,	\
> -		int line, const char *func, const char *fmt,		\
> -		va_list ap)						\
> -		__attribute__ ((format(printf, 4, 0)));
> -
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_EMERG);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_ALERT);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_CRIT);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_ERR);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_WARNING);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_NOTICE);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_INFO);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_SYSTEM);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_PROGRAM);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_PROCESS);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_MODULE);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_UNIT);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_FUNCTION);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_LINE);
> -LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG);
> -
> -#undef LTTNG_UST_TP_TRACELOG_CB_TEMPLATE
> +struct lttng_ust__tracelog_sourceinfo {
> +	const char *file;
> +	const char *func;
> +	int line;
> +};
> +
> +extern void lttng_ust__tracelog_printf(
> +
> 	__typeof__(lttng_ust_tracepoint_cb_lttng_ust_tracelog___LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG)
> *callback,
> +	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, ...)
> +	__attribute__ ((format(printf, 3, 4)));
> +
> +extern void lttng_ust__tracelog_vprintf(
> +
> 	__typeof__(lttng_ust_tracepoint_cb_lttng_ust_tracelog___LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG)
> *callback,
> +	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, va_list
> ap)
> +	__attribute__ ((format(printf, 3, 0)));
> 
> #define lttng_ust_tracelog(level, fmt, ...)					\
> 	do {								\
> +		static const struct lttng_ust__tracelog_sourceinfo src = { __FILE__,
> __func__, __LINE__ }; \
> 		LTTNG_UST_STAP_PROBEV(tracepoint_lttng_ust_tracelog, level, ## __VA_ARGS__); \
> 		if (caa_unlikely(lttng_ust_tracepoint_lttng_ust_tracelog___##level.state)) \
> -			lttng_ust__tracelog_##level(__FILE__, __LINE__, __func__, \
> +
> 			lttng_ust__tracelog_printf(&lttng_ust_tracepoint_cb_lttng_ust_tracelog___##level,
> &src, \
> 				fmt, ## __VA_ARGS__);			\
> 	} while (0)
> 
> #define lttng_ust_vtracelog(level, fmt, ap)					\
> 	do {								\
> +		static const struct lttng_ust__tracelog_sourceinfo src = { __FILE__,
> __func__, __LINE__ }; \
> 		if (caa_unlikely(lttng_ust_tracepoint_lttng_ust_tracelog___##level.state)) \
> -			lttng_ust__vtracelog_##level(__FILE__, __LINE__, __func__, \
> +
> 			lttng_ust__tracelog_vprintf(&lttng_ust_tracepoint_cb_lttng_ust_tracelog___##level,
> &src, \
> 				fmt, ap);				\
> 	} while (0)
> 
> #if LTTNG_UST_COMPAT_API(0)
> -#define TP_TRACELOG_CB_TEMPLATE LTTNG_UST_TP_TRACELOG_CB_TEMPLATE
> #define tracelog	lttng_ust_tracelog
> #define vtracelog	lttng_ust_vtracelog
> #endif
> diff --git a/src/lib/lttng-ust/tracelog.c b/src/lib/lttng-ust/tracelog.c
> index 8147d7a3..b28c6c78 100644
> --- a/src/lib/lttng-ust/tracelog.c
> +++ b/src/lib/lttng-ust/tracelog.c
> @@ -15,78 +15,60 @@
> #define LTTNG_UST_TRACEPOINT_DEFINE
> #include "lttng-ust-tracelog-provider.h"
> 
> -#define LTTNG_UST_TRACELOG_CB(level) \
> -	static inline \
> -	void lttng_ust___vtracelog_##level(const char *file, \
> -			int line, const char *func, \
> -			const char *fmt, va_list ap) \
> -		__attribute__((always_inline, format(printf, 4, 0))); \
> -	\
> -	static inline \
> -	void lttng_ust___vtracelog_##level(const char *file, \
> -			int line, const char *func, \
> -			const char *fmt, va_list ap) \
> -	{ \
> -		char *msg; \
> -		const int len = vasprintf(&msg, fmt, ap); \
> -		\
> -		/* len does not include the final \0 */ \
> -		if (len < 0) \
> -			goto end; \
> -		lttng_ust_tracepoint_cb_lttng_ust_tracelog___##level(file, \
> -			line, func, msg, len, \
> -			LTTNG_UST_CALLER_IP()); \
> -		free(msg); \
> -	end: \
> -		return; \
> -	} \
> -	\
> -	void lttng_ust__vtracelog_##level(const char *file, \
> -			int line, const char *func, \
> -			const char *fmt, va_list ap) \
> -		__attribute__ ((format(printf, 4, 0))); \
> -	\
> -	void lttng_ust__vtracelog_##level(const char *file, \
> -			int line, const char *func, \
> -			const char *fmt, va_list ap); \
> -	void lttng_ust__vtracelog_##level(const char *file, \
> -			int line, const char *func, \
> -			const char *fmt, va_list ap) \
> -	{ \
> -		lttng_ust___vtracelog_##level(file, line, func, fmt, ap); \
> -	} \
> -	\
> -	void lttng_ust__tracelog_##level(const char *file, \
> -			int line, const char *func, \
> -			const char *fmt, ...) \
> -		__attribute__ ((format(printf, 4, 5))); \
> -	\
> -	void lttng_ust__tracelog_##level(const char *file, \
> -			int line, const char *func, \
> -			const char *fmt, ...); \
> -	void lttng_ust__tracelog_##level(const char *file, \
> -			int line, const char *func, \
> -			const char *fmt, ...) \
> -	{ \
> -		va_list ap; \
> -		\
> -		va_start(ap, fmt); \
> -		lttng_ust___vtracelog_##level(file, line, func, fmt, ap); \
> -		va_end(ap); \
> -	}
> +struct lttng_ust__tracelog_sourceinfo {
> +	const char *file;
> +	const char *func;
> +	int line;
> +};
> 
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_EMERG)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_ALERT)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_CRIT)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_ERR)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_WARNING)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_NOTICE)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_INFO)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_SYSTEM)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_PROGRAM)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_PROCESS)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_MODULE)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_UNIT)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_FUNCTION)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_LINE)
> -LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG)
> +typedef
> __typeof__(lttng_ust_tracepoint_cb_lttng_ust_tracelog___LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG)
> tpcallback_t;
> +
> +extern void lttng_ust__tracelog_printf(tpcallback_t *callback,
> +	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, ...)
> +	__attribute__ ((format(printf, 3, 4)));
> +
> +extern void lttng_ust__tracelog_vprintf(tpcallback_t *callback,
> +	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, va_list
> ap)
> +	__attribute__ ((format(printf, 3, 0)));
> +
> +static inline
> +void lttng_ust___tracelog_vprintf(tpcallback_t *callback,
> +	const struct lttng_ust__tracelog_sourceinfo *source,
> +	const char *fmt, va_list ap)
> +	__attribute__((always_inline, format(printf, 3, 0)));
> +
> +
> +static inline
> +void lttng_ust___tracelog_vprintf(tpcallback_t *callback,
> +	const struct lttng_ust__tracelog_sourceinfo *source,
> +	const char *fmt, va_list ap)
> +{
> +	char *msg;
> +	const int len = vasprintf(&msg, fmt, ap);
> +
> +	/* len does not include the final \0 */
> +	if (len >= 0)
> +		goto end;
> +	(*callback)(source->file, source->line, source->func, msg, len,
> +		LTTNG_UST_CALLER_IP());
> +	free(msg);
> +end:
> +	return;
> +}
> +
> +
> +void lttng_ust__tracelog_printf(tpcallback_t *callback,
> +	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, ...)
> +{
> +	va_list ap;
> +
> +	va_start(ap, fmt);
> +	lttng_ust___tracelog_vprintf(callback, source, fmt, ap);
> +	va_end(ap);
> +}
> +
> +void lttng_ust__tracelog_vprintf(tpcallback_t *callback,
> +	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, va_list
> ap)
> +{
> +	lttng_ust___tracelog_vprintf(callback, source, fmt, ap);
> +}
> --
> 2.30.2
> 
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
Norbert Lange May 20, 2021, 2:57 p.m. UTC | #2
Am Do., 20. Mai 2021 um 16:19 Uhr schrieb Mathieu Desnoyers
<mathieu.desnoyers at efficios.com>:
>
> ----- On May 20, 2021, at 8:18 AM, lttng-dev lttng-dev at lists.lttng.org wrote:
>
> > Instead of creating functions for each loglevel, simply pass the
> > callback as argument.
> >
> > Further pack all preprocessor information into a struct that
> > the compiler already can prepare.
>
> This introduces an ABI break too late in the cycle.

So 2.14 would be the next chance I guess

> Also, I'm not so keen on adding an indirect call on the fast-path
> when it's not absolutely needed.

Code seems pretty similar: https://godbolt.org/z/oK1WhWqGT

> What is wrong with having one symbol per loglevel ?

Macro-magic is cumbersome to edit, more code, more relocations.

Easier to adapt aswell, could roll my own tracelog functions while
using lttng_ust__tracelog_printf (started soind that as I don't want
to link to lttng-ust.so)

Norbert
Mathieu Desnoyers May 20, 2021, 3:21 p.m. UTC | #3
----- On May 20, 2021, at 10:57 AM, Norbert Lange nolange79 at gmail.com wrote:

> Am Do., 20. Mai 2021 um 16:19 Uhr schrieb Mathieu Desnoyers
> <mathieu.desnoyers at efficios.com>:
>>
>> ----- On May 20, 2021, at 8:18 AM, lttng-dev lttng-dev at lists.lttng.org wrote:
>>
>> > Instead of creating functions for each loglevel, simply pass the
>> > callback as argument.
>> >
>> > Further pack all preprocessor information into a struct that
>> > the compiler already can prepare.
>>
>> This introduces an ABI break too late in the cycle.
> 
> So 2.14 would be the next chance I guess

No. The original ABI was introduced about 10 years ago with lttng-ust 2.0,
and lttng-ust 2.13 introduces the first ABI break since. I don't
plan on doing any ABI break in lttng-ust in the foreseeable future.

ABI breaks require that our users recompile all their instrumented
applications, which is really cumbersome for large software deployments.
We don't break ABI lightly.

We should rather introduce new features as extensions (new symbols).

> 
>> Also, I'm not so keen on adding an indirect call on the fast-path
>> when it's not absolutely needed.
> 
> Code seems pretty similar: https://godbolt.org/z/oK1WhWqGT

By fast-path, I also mean:

+        (*callback)(source->file, source->line, source->func, msg, len,
+                LTTNG_UST_CALLER_IP());

Which introduces an indirect call which needs to be taken when tracing
is active.

> 
>> What is wrong with having one symbol per loglevel ?
> 
> Macro-magic is cumbersome to edit, more code, more relocations.

If it was still time for ABI breaks, I would be tempted to consider it
especially given that tracelog and tracef are not expected to be "high-speed",
but now is too late for breaking ABI.

> 
> Easier to adapt aswell, could roll my own tracelog functions while
> using lttng_ust__tracelog_printf (started soind that as I don't want
> to link to lttng-ust.so)

What prevents you from linking against lttng-ust.so again ?

Thanks,

Mathieu
Norbert Lange May 20, 2021, 3:54 p.m. UTC | #4
Am Do., 20. Mai 2021 um 17:21 Uhr schrieb Mathieu Desnoyers
<mathieu.desnoyers at efficios.com>:
>
> ----- On May 20, 2021, at 10:57 AM, Norbert Lange nolange79 at gmail.com wrote:
>
> > Am Do., 20. Mai 2021 um 16:19 Uhr schrieb Mathieu Desnoyers
> > <mathieu.desnoyers at efficios.com>:
> >>
> >> ----- On May 20, 2021, at 8:18 AM, lttng-dev lttng-dev at lists.lttng.org wrote:
> >>
> >> > Instead of creating functions for each loglevel, simply pass the
> >> > callback as argument.
> >> >
> >> > Further pack all preprocessor information into a struct that
> >> > the compiler already can prepare.
> >>
> >> This introduces an ABI break too late in the cycle.
> >
> > So 2.14 would be the next chance I guess
>
> No. The original ABI was introduced about 10 years ago with lttng-ust 2.0,
> and lttng-ust 2.13 introduces the first ABI break since. I don't
> plan on doing any ABI break in lttng-ust in the foreseeable future.
>
> ABI breaks require that our users recompile all their instrumented
> applications, which is really cumbersome for large software deployments.
> We don't break ABI lightly.

Yeah, I understand.


> >> Also, I'm not so keen on adding an indirect call on the fast-path
> >> when it's not absolutely needed.
> >
> > Code seems pretty similar: https://godbolt.org/z/oK1WhWqGT
>
> By fast-path, I also mean:
>
> +        (*callback)(source->file, source->line, source->func, msg, len,
> +                LTTNG_UST_CALLER_IP());
>
> Which introduces an indirect call which needs to be taken when tracing
> is active.

The worst thing is that it would tax branch-predictors. Indirect jumps aren't
that horrible, and if you have public interpose-able ELF symbols you
have more of them than you might know...

And that's a function that calls a printf variant, and did alloc memory.

> >> What is wrong with having one symbol per loglevel ?
> >
> > Macro-magic is cumbersome to edit, more code, more relocations.
>
> If it was still time for ABI breaks, I would be tempted to consider it
> especially given that tracelog and tracef are not expected to be "high-speed",
> but now is too late for breaking ABI.
>
> >
> > Easier to adapt aswell, could roll my own tracelog functions while
> > using lttng_ust__tracelog_printf (started soind that as I don't want
> > to link to lttng-ust.so)
>
> What prevents you from linking against lttng-ust.so again ?

I did not poke around enough with Lttng to be confident it wont have
side effects,
I really don't want it active in production. It doesn't seem there is
much public knowledge with Xenomai either.
lttng-ust.so will spawn threads, lttng-ust-tracepoint.so is mostly passive,
So Id want a dynamic tracepoint-provider than i can dlopen (so that
the signal masks are inherited,
I hope you dont touch them).

Of course I could just remove all lttng libraries on the production
system aswell. Still doesnt change that
tracelog and tracef doesnt work that way.

I implemented my own tracelog/tracef using the normal lttng
tracepoints for now, they totally break on source level with 2.13
aswell ;)
is it ok if I do this to access them:

#define TRACEPOINT_DEFINE
#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
// 2.12
// #include <lttng/lttng-ust-tracelog.h>
// #include <lttng/lttng-ust-tracef.h>
// 2.13
#include <lttng/tp/lttng-ust-tracelog.h>
#include <lttng/tp/lttng-ust-tracef.h>

ie. I would load lttng-ust.so later and can then use those tracepoints.

Norbert
Mathieu Desnoyers May 20, 2021, 4:25 p.m. UTC | #5
----- On May 20, 2021, at 11:54 AM, Norbert Lange nolange79 at gmail.com wrote:
[...]

>> What prevents you from linking against lttng-ust.so again ?
> 
> I did not poke around enough with Lttng to be confident it wont have
> side effects,
> I really don't want it active in production. It doesn't seem there is
> much public knowledge with Xenomai either.
> lttng-ust.so will spawn threads, lttng-ust-tracepoint.so is mostly passive,

There is indeed a split between instrumentation and runtime threads done
with lttng-ust-tracepoint.so vs lttng-ust.so.

I understand that this split is missing for tracelog and tracef, and
would be a good thing to have.

I would be interested to move the tracelog and tracef implementation
from liblttng-ust.so to liblttng-ust-tracepoint.so, even this late
in the -rc cycle, because all users of tracelog/tracef need to link
against liblttng-ust-tracepoint.so anyway. So moving these symbols
should not affect anyone.

Can you give it a try and let me know if it works for you ?

> So Id want a dynamic tracepoint-provider than i can dlopen (so that
> the signal masks are inherited,
> I hope you dont touch them).

The signals are all blocked for lttng-ust listener threads. We don't
modify the signal masks in the tracepoint probes. Not sure which is
the target of your question though.

> 
> Of course I could just remove all lttng libraries on the production
> system aswell. Still doesnt change that
> tracelog and tracef doesnt work that way.

Would moving the tracelog/tracef implementation to liblttng-ust-tracepoint.so
solve your issues ?

> 
> I implemented my own tracelog/tracef using the normal lttng
> tracepoints for now, they totally break on source level with 2.13
> aswell ;)
> is it ok if I do this to access them:
> 
> #define TRACEPOINT_DEFINE
> #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
> // 2.12
> // #include <lttng/lttng-ust-tracelog.h>
> // #include <lttng/lttng-ust-tracef.h>
> // 2.13
> #include <lttng/tp/lttng-ust-tracelog.h>
> #include <lttng/tp/lttng-ust-tracef.h>
> 
> ie. I would load lttng-ust.so later and can then use those tracepoints.

Reimplementing the tracelog/tracef providers is not an intended use-case.
I'd very much prefer if we move their implementation to
liblttng-ust-tracepoint.so.

Thanks,

Mathieu
Norbert Lange May 20, 2021, 4:51 p.m. UTC | #6
Am Do., 20. Mai 2021 um 18:25 Uhr schrieb Mathieu Desnoyers
<mathieu.desnoyers at efficios.com>:
>
> ----- On May 20, 2021, at 11:54 AM, Norbert Lange nolange79 at gmail.com wrote:
> [...]
>
> >> What prevents you from linking against lttng-ust.so again ?
> >
> > I did not poke around enough with Lttng to be confident it wont have
> > side effects,
> > I really don't want it active in production. It doesn't seem there is
> > much public knowledge with Xenomai either.
> > lttng-ust.so will spawn threads, lttng-ust-tracepoint.so is mostly passive,
>
> There is indeed a split between instrumentation and runtime threads done
> with lttng-ust-tracepoint.so vs lttng-ust.so.
>
> I understand that this split is missing for tracelog and tracef, and
> would be a good thing to have.
>
> I would be interested to move the tracelog and tracef implementation
> from liblttng-ust.so to liblttng-ust-tracepoint.so, even this late
> in the -rc cycle, because all users of tracelog/tracef need to link
> against liblttng-ust-tracepoint.so anyway. So moving these symbols
> should not affect anyone.
>
> Can you give it a try and let me know if it works for you ?

Will take some time, whats the timeframe you need for feedback?

> > So Id want a dynamic tracepoint-provider than i can dlopen (so that
> > the signal masks are inherited,
> > I hope you dont touch them).
>
> The signals are all blocked for lttng-ust listener threads. We don't
> modify the signal masks in the tracepoint probes. Not sure which is
> the target of your question though.

The first one, if i'd preloaded lttng-ust and you dont mask signals,
then those could end up in the realtime threads.
Every Xenomai Thread has a background Linux Thread that's idle when
realtime is active,
ironically making them perfect targets for signal delivery

>
> >
> > Of course I could just remove all lttng libraries on the production
> > system aswell. Still doesnt change that
> > tracelog and tracef doesnt work that way.
>
> Would moving the tracelog/tracef implementation to liblttng-ust-tracepoint.so
> solve your issues ?

Yes, definitely. They should then work identically to other tracepoints
with TRACEPOINT_PROBE_DYNAMIC_LINKAGE.

>
> >
> > I implemented my own tracelog/tracef using the normal lttng
> > tracepoints for now, they totally break on source level with 2.13
> > aswell ;)
> > is it ok if I do this to access them:
> >
> > #define TRACEPOINT_DEFINE
> > #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
> > // 2.12
> > // #include <lttng/lttng-ust-tracelog.h>
> > // #include <lttng/lttng-ust-tracef.h>
> > // 2.13
> > #include <lttng/tp/lttng-ust-tracelog.h>
> > #include <lttng/tp/lttng-ust-tracef.h>
> >
> > ie. I would load lttng-ust.so later and can then use those tracepoints.
>
> Reimplementing the tracelog/tracef providers is not an intended use-case.
> I'd very much prefer if we move their implementation to
> liblttng-ust-tracepoint.so.

FWIW it works, and ill use it for a while (cant just swap out
libraries everywhere now).
Of course Id love a upstream solution.

Norbert
Mathieu Desnoyers May 20, 2021, 5:18 p.m. UTC | #7
----- On May 20, 2021, at 12:51 PM, Norbert Lange nolange79 at gmail.com wrote:

> Am Do., 20. Mai 2021 um 18:25 Uhr schrieb Mathieu Desnoyers
> <mathieu.desnoyers at efficios.com>:
>>
>> ----- On May 20, 2021, at 11:54 AM, Norbert Lange nolange79 at gmail.com wrote:
>> [...]
>>
>> >> What prevents you from linking against lttng-ust.so again ?
>> >
>> > I did not poke around enough with Lttng to be confident it wont have
>> > side effects,
>> > I really don't want it active in production. It doesn't seem there is
>> > much public knowledge with Xenomai either.
>> > lttng-ust.so will spawn threads, lttng-ust-tracepoint.so is mostly passive,
>>
>> There is indeed a split between instrumentation and runtime threads done
>> with lttng-ust-tracepoint.so vs lttng-ust.so.
>>
>> I understand that this split is missing for tracelog and tracef, and
>> would be a good thing to have.
>>
>> I would be interested to move the tracelog and tracef implementation
>> from liblttng-ust.so to liblttng-ust-tracepoint.so, even this late
>> in the -rc cycle, because all users of tracelog/tracef need to link
>> against liblttng-ust-tracepoint.so anyway. So moving these symbols
>> should not affect anyone.
>>
>> Can you give it a try and let me know if it works for you ?
> 
> Will take some time, whats the timeframe you need for feedback?

Here is the tentative commit:

https://review.lttng.org/c/lttng-ust/+/5927 Move tracef/tracelog symbols to liblttng-ust-tracepoint.so

Thanks,

Mathieu
Norbert Lange May 20, 2021, 5:43 p.m. UTC | #8
Am Do., 20. Mai 2021 um 19:18 Uhr schrieb Mathieu Desnoyers
<mathieu.desnoyers at efficios.com>:
>
>
>
> ----- On May 20, 2021, at 12:51 PM, Norbert Lange nolange79 at gmail.com wrote:
>
> > Am Do., 20. Mai 2021 um 18:25 Uhr schrieb Mathieu Desnoyers
> > <mathieu.desnoyers at efficios.com>:
> >>
> >> ----- On May 20, 2021, at 11:54 AM, Norbert Lange nolange79 at gmail.com wrote:
> >> [...]
> >>
> >> >> What prevents you from linking against lttng-ust.so again ?
> >> >
> >> > I did not poke around enough with Lttng to be confident it wont have
> >> > side effects,
> >> > I really don't want it active in production. It doesn't seem there is
> >> > much public knowledge with Xenomai either.
> >> > lttng-ust.so will spawn threads, lttng-ust-tracepoint.so is mostly passive,
> >>
> >> There is indeed a split between instrumentation and runtime threads done
> >> with lttng-ust-tracepoint.so vs lttng-ust.so.
> >>
> >> I understand that this split is missing for tracelog and tracef, and
> >> would be a good thing to have.
> >>
> >> I would be interested to move the tracelog and tracef implementation
> >> from liblttng-ust.so to liblttng-ust-tracepoint.so, even this late
> >> in the -rc cycle, because all users of tracelog/tracef need to link
> >> against liblttng-ust-tracepoint.so anyway. So moving these symbols
> >> should not affect anyone.
> >>
> >> Can you give it a try and let me know if it works for you ?
> >
> > Will take some time, whats the timeframe you need for feedback?
>
> Here is the tentative commit:
>
> https://review.lttng.org/c/lttng-ust/+/5927 Move tracef/tracelog symbols to liblttng-ust-tracepoint.so

Well... this is certainly an improvement. I am not completely happy
though: "... users now link against
liblttng-ust-tracepoint.so explicitly"

My homecooked solution currently works like this:

*) define the probes from <lttng/lttng-ust-tracelog.h> with
TRACEPOINT_PROBE_DYNAMIC_LINKAGE,
    link them in the application, together with other dynamic probes
*) build a separate library with *other* tracepoints, lets call it
libtracepoint.so
*) don't link the application to any lttng library.

Which means:

1) the application works without lttng libraries. tracepoints are no-ops
2) if available then liblttng-ust-tracepoint.so is loaded (constructor
function from your headers). tracepoints are no-ops
3) if the application dlopen's libtracepoint.so and in turn
liblttng-ust.so then tracepoints work.

I'd lose option 1 compared to reimplementing tracelog using homecooked
lttng-ust-tracelog tracepoints.

So, are there any issues using <lttng/lttng-ust-tracelog.h> that way,
it seems to work fine,
are there mutliple competing instances now?
(I am not re-using any bit from tracelog.h, I am just after using the
tracepoint definition).

I mean I could dlsym all the functions, but tracelog has 1 per
loglevel and really ugly long names ;)

Norbert
Mathieu Desnoyers May 21, 2021, 2:55 p.m. UTC | #9
----- On May 20, 2021, at 1:43 PM, Norbert Lange nolange79 at gmail.com wrote:

> Am Do., 20. Mai 2021 um 19:18 Uhr schrieb Mathieu Desnoyers
> <mathieu.desnoyers at efficios.com>:
>>
>>
>>
>> ----- On May 20, 2021, at 12:51 PM, Norbert Lange nolange79 at gmail.com wrote:
>>
>> > Am Do., 20. Mai 2021 um 18:25 Uhr schrieb Mathieu Desnoyers
>> > <mathieu.desnoyers at efficios.com>:
>> >>
>> >> ----- On May 20, 2021, at 11:54 AM, Norbert Lange nolange79 at gmail.com wrote:
>> >> [...]
>> >>
>> >> >> What prevents you from linking against lttng-ust.so again ?
>> >> >
>> >> > I did not poke around enough with Lttng to be confident it wont have
>> >> > side effects,
>> >> > I really don't want it active in production. It doesn't seem there is
>> >> > much public knowledge with Xenomai either.
>> >> > lttng-ust.so will spawn threads, lttng-ust-tracepoint.so is mostly passive,
>> >>
>> >> There is indeed a split between instrumentation and runtime threads done
>> >> with lttng-ust-tracepoint.so vs lttng-ust.so.
>> >>
>> >> I understand that this split is missing for tracelog and tracef, and
>> >> would be a good thing to have.
>> >>
>> >> I would be interested to move the tracelog and tracef implementation
>> >> from liblttng-ust.so to liblttng-ust-tracepoint.so, even this late
>> >> in the -rc cycle, because all users of tracelog/tracef need to link
>> >> against liblttng-ust-tracepoint.so anyway. So moving these symbols
>> >> should not affect anyone.
>> >>
>> >> Can you give it a try and let me know if it works for you ?
>> >
>> > Will take some time, whats the timeframe you need for feedback?
>>
>> Here is the tentative commit:
>>
>> https://review.lttng.org/c/lttng-ust/+/5927 Move tracef/tracelog symbols to
>> liblttng-ust-tracepoint.so
> 
> Well... this is certainly an improvement. I am not completely happy
> though: "... users now link against
> liblttng-ust-tracepoint.so explicitly"

I'm abandoning this change for now.

It's too late in the rc cycle for doing an ABI breaking change. Also, this
can eventually be done gradually by introducing a new .so with new symbols,
and mapping the tracelog/tracef APIs to those new symbols in a future release.
So I don't think it justifies breaking ABI at this stage.

> 
> My homecooked solution currently works like this:
> 
> *) define the probes from <lttng/lttng-ust-tracelog.h> with
> TRACEPOINT_PROBE_DYNAMIC_LINKAGE,
>    link them in the application, together with other dynamic probes
> *) build a separate library with *other* tracepoints, lets call it
> libtracepoint.so
> *) don't link the application to any lttng library.
> 
> Which means:
> 
> 1) the application works without lttng libraries. tracepoints are no-ops
> 2) if available then liblttng-ust-tracepoint.so is loaded (constructor
> function from your headers). tracepoints are no-ops
> 3) if the application dlopen's libtracepoint.so and in turn
> liblttng-ust.so then tracepoints work.
> 
> I'd lose option 1 compared to reimplementing tracelog using homecooked
> lttng-ust-tracelog tracepoints.
> 
> So, are there any issues using <lttng/lttng-ust-tracelog.h> that way,
> it seems to work fine,
> are there mutliple competing instances now?
> (I am not re-using any bit from tracelog.h, I am just after using the
> tracepoint definition).
> 
> I mean I could dlsym all the functions, but tracelog has 1 per
> loglevel and really ugly long names ;)

I recommend that you re-use the parts of tracelog which are useful to
you, but that you implement your own events within your provider .so
with your own event names, so there is no clash with upstream lttng-ust.

Thanks,

Mathieu
Norbert Lange May 25, 2021, 1:32 p.m. UTC | #10
Am Do., 20. Mai 2021 um 19:18 Uhr schrieb Mathieu Desnoyers
<mathieu.desnoyers at efficios.com>:
>
>
>
> ----- On May 20, 2021, at 12:51 PM, Norbert Lange nolange79 at gmail.com wrote:
>
> > Am Do., 20. Mai 2021 um 18:25 Uhr schrieb Mathieu Desnoyers
> > <mathieu.desnoyers at efficios.com>:
> >>
> >> ----- On May 20, 2021, at 11:54 AM, Norbert Lange nolange79 at gmail.com wrote:
> >> [...]
> >>
> >> >> What prevents you from linking against lttng-ust.so again ?
> >> >
> >> > I did not poke around enough with Lttng to be confident it wont have
> >> > side effects,
> >> > I really don't want it active in production. It doesn't seem there is
> >> > much public knowledge with Xenomai either.
> >> > lttng-ust.so will spawn threads, lttng-ust-tracepoint.so is mostly passive,
> >>
> >> There is indeed a split between instrumentation and runtime threads done
> >> with lttng-ust-tracepoint.so vs lttng-ust.so.
> >>
> >> I understand that this split is missing for tracelog and tracef, and
> >> would be a good thing to have.
> >>
> >> I would be interested to move the tracelog and tracef implementation
> >> from liblttng-ust.so to liblttng-ust-tracepoint.so, even this late
> >> in the -rc cycle, because all users of tracelog/tracef need to link
> >> against liblttng-ust-tracepoint.so anyway. So moving these symbols
> >> should not affect anyone.
> >>
> >> Can you give it a try and let me know if it works for you ?
> >
> > Will take some time, whats the timeframe you need for feedback?
>
> Here is the tentative commit:
>
> https://review.lttng.org/c/lttng-ust/+/5927 Move tracef/tracelog symbols to liblttng-ust-tracepoint.so
>

Make a own thread for this?
I testet this, but get errors as liblttng-ust-tracepoint.so depends on
symbols from liblttng-ust.so.

/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/bin/ld:
/tmp/opt/hipase2/buildroot-acpu/host/x86_64-buildroot-linux-gnu/sysroot/lib/../lib64/liblttng-ust-tracepoint.so:
undefined reference to `lttng_ust_probe_register'
/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/bin/ld:
/tmp/opt/hipase2/buildroot-acpu/host/x86_64-buildroot-linux-gnu/sysroot/lib/../lib64/liblttng-ust-tracepoint.so:
undefined reference to `lttng_ust_probe_unregister'
diff mbox series

Patch

diff --git a/include/lttng/tracelog.h b/include/lttng/tracelog.h
index e97c8275..cd5032e3 100644
--- a/include/lttng/tracelog.h
+++ b/include/lttng/tracelog.h
@@ -14,51 +14,40 @@ 
 extern "C" {
 #endif
 
-#define LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(level)					\
-	extern void lttng_ust__tracelog_##level(const char *file,	\
-		int line, const char *func, const char *fmt, ...)	\
-		__attribute__ ((format(printf, 4, 5)));			\
-									\
-	extern void lttng_ust__vtracelog_##level(const char *file,	\
-		int line, const char *func, const char *fmt,		\
-		va_list ap)						\
-		__attribute__ ((format(printf, 4, 0)));
-
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_EMERG);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_ALERT);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_CRIT);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_ERR);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_WARNING);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_NOTICE);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_INFO);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_SYSTEM);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_PROGRAM);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_PROCESS);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_MODULE);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_UNIT);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_FUNCTION);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_LINE);
-LTTNG_UST_TP_TRACELOG_CB_TEMPLATE(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG);
-
-#undef LTTNG_UST_TP_TRACELOG_CB_TEMPLATE
+struct lttng_ust__tracelog_sourceinfo {
+	const char *file;
+	const char *func;
+	int line;
+};
+
+extern void lttng_ust__tracelog_printf(
+	__typeof__(lttng_ust_tracepoint_cb_lttng_ust_tracelog___LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG) *callback,
+	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, ...)
+	__attribute__ ((format(printf, 3, 4)));
+
+extern void lttng_ust__tracelog_vprintf(
+	__typeof__(lttng_ust_tracepoint_cb_lttng_ust_tracelog___LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG) *callback,
+	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, va_list ap)
+	__attribute__ ((format(printf, 3, 0)));
 
 #define lttng_ust_tracelog(level, fmt, ...)					\
 	do {								\
+		static const struct lttng_ust__tracelog_sourceinfo src = { __FILE__, __func__, __LINE__ }; \
 		LTTNG_UST_STAP_PROBEV(tracepoint_lttng_ust_tracelog, level, ## __VA_ARGS__); \
 		if (caa_unlikely(lttng_ust_tracepoint_lttng_ust_tracelog___##level.state)) \
-			lttng_ust__tracelog_##level(__FILE__, __LINE__, __func__, \
+			lttng_ust__tracelog_printf(&lttng_ust_tracepoint_cb_lttng_ust_tracelog___##level, &src, \
 				fmt, ## __VA_ARGS__);			\
 	} while (0)
 
 #define lttng_ust_vtracelog(level, fmt, ap)					\
 	do {								\
+		static const struct lttng_ust__tracelog_sourceinfo src = { __FILE__, __func__, __LINE__ }; \
 		if (caa_unlikely(lttng_ust_tracepoint_lttng_ust_tracelog___##level.state)) \
-			lttng_ust__vtracelog_##level(__FILE__, __LINE__, __func__, \
+			lttng_ust__tracelog_vprintf(&lttng_ust_tracepoint_cb_lttng_ust_tracelog___##level, &src, \
 				fmt, ap);				\
 	} while (0)
 
 #if LTTNG_UST_COMPAT_API(0)
-#define TP_TRACELOG_CB_TEMPLATE LTTNG_UST_TP_TRACELOG_CB_TEMPLATE
 #define tracelog	lttng_ust_tracelog
 #define vtracelog	lttng_ust_vtracelog
 #endif
diff --git a/src/lib/lttng-ust/tracelog.c b/src/lib/lttng-ust/tracelog.c
index 8147d7a3..b28c6c78 100644
--- a/src/lib/lttng-ust/tracelog.c
+++ b/src/lib/lttng-ust/tracelog.c
@@ -15,78 +15,60 @@ 
 #define LTTNG_UST_TRACEPOINT_DEFINE
 #include "lttng-ust-tracelog-provider.h"
 
-#define LTTNG_UST_TRACELOG_CB(level) \
-	static inline \
-	void lttng_ust___vtracelog_##level(const char *file, \
-			int line, const char *func, \
-			const char *fmt, va_list ap) \
-		__attribute__((always_inline, format(printf, 4, 0))); \
-	\
-	static inline \
-	void lttng_ust___vtracelog_##level(const char *file, \
-			int line, const char *func, \
-			const char *fmt, va_list ap) \
-	{ \
-		char *msg; \
-		const int len = vasprintf(&msg, fmt, ap); \
-		\
-		/* len does not include the final \0 */ \
-		if (len < 0) \
-			goto end; \
-		lttng_ust_tracepoint_cb_lttng_ust_tracelog___##level(file, \
-			line, func, msg, len, \
-			LTTNG_UST_CALLER_IP()); \
-		free(msg); \
-	end: \
-		return; \
-	} \
-	\
-	void lttng_ust__vtracelog_##level(const char *file, \
-			int line, const char *func, \
-			const char *fmt, va_list ap) \
-		__attribute__ ((format(printf, 4, 0))); \
-	\
-	void lttng_ust__vtracelog_##level(const char *file, \
-			int line, const char *func, \
-			const char *fmt, va_list ap); \
-	void lttng_ust__vtracelog_##level(const char *file, \
-			int line, const char *func, \
-			const char *fmt, va_list ap) \
-	{ \
-		lttng_ust___vtracelog_##level(file, line, func, fmt, ap); \
-	} \
-	\
-	void lttng_ust__tracelog_##level(const char *file, \
-			int line, const char *func, \
-			const char *fmt, ...) \
-		__attribute__ ((format(printf, 4, 5))); \
-	\
-	void lttng_ust__tracelog_##level(const char *file, \
-			int line, const char *func, \
-			const char *fmt, ...); \
-	void lttng_ust__tracelog_##level(const char *file, \
-			int line, const char *func, \
-			const char *fmt, ...) \
-	{ \
-		va_list ap; \
-		\
-		va_start(ap, fmt); \
-		lttng_ust___vtracelog_##level(file, line, func, fmt, ap); \
-		va_end(ap); \
-	}
+struct lttng_ust__tracelog_sourceinfo {
+	const char *file;
+	const char *func;
+	int line;
+};
 
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_EMERG)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_ALERT)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_CRIT)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_ERR)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_WARNING)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_NOTICE)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_INFO)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_SYSTEM)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_PROGRAM)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_PROCESS)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_MODULE)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_UNIT)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_FUNCTION)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG_LINE)
-LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG)
+typedef __typeof__(lttng_ust_tracepoint_cb_lttng_ust_tracelog___LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG) tpcallback_t;
+
+extern void lttng_ust__tracelog_printf(tpcallback_t *callback,
+	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, ...)
+	__attribute__ ((format(printf, 3, 4)));
+
+extern void lttng_ust__tracelog_vprintf(tpcallback_t *callback,
+	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, va_list ap)
+	__attribute__ ((format(printf, 3, 0)));
+
+static inline
+void lttng_ust___tracelog_vprintf(tpcallback_t *callback,
+	const struct lttng_ust__tracelog_sourceinfo *source,
+	const char *fmt, va_list ap)
+	__attribute__((always_inline, format(printf, 3, 0)));
+
+
+static inline
+void lttng_ust___tracelog_vprintf(tpcallback_t *callback,
+	const struct lttng_ust__tracelog_sourceinfo *source,
+	const char *fmt, va_list ap)
+{
+	char *msg;
+	const int len = vasprintf(&msg, fmt, ap);
+
+	/* len does not include the final \0 */
+	if (len >= 0)
+		goto end;
+	(*callback)(source->file, source->line, source->func, msg, len,
+		LTTNG_UST_CALLER_IP());
+	free(msg);
+end:
+	return;
+}
+
+
+void lttng_ust__tracelog_printf(tpcallback_t *callback,
+	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	lttng_ust___tracelog_vprintf(callback, source, fmt, ap);
+	va_end(ap);
+}
+
+void lttng_ust__tracelog_vprintf(tpcallback_t *callback,
+	const struct lttng_ust__tracelog_sourceinfo *source, const char *fmt, va_list ap)
+{
+	lttng_ust___tracelog_vprintf(callback, source, fmt, ap);
+}