* [lttng-dev] [PATCH lttng-ust] Improve tracef/tracelog to use the stack for small strings
@ 2021-05-25 13:44 Norbert Lange via lttng-dev
2021-05-25 13:47 ` Norbert Lange via lttng-dev
0 siblings, 1 reply; 3+ messages in thread
From: Norbert Lange via lttng-dev @ 2021-05-25 13:44 UTC (permalink / raw)
To: lttng-dev
Support two common cases, one being that the resulting message is
small enough to fit into a on-stack buffer.
The seconds being the common 'printf("%s", "Message")' scheme.
Unfortunately, iterating a va_list is destructive,
so it has to be copied before calling vprintf.
The implementation was moved to a separate file,
used by both tracef.c and tracelog.c.
Signed-off-by: Norbert Lange <nolange79@gmail.com>
---
src/common/tracer.h | 2 +
src/lib/lttng-ust-tracepoint/tracef.c | 32 ++-----
.../lttng-ust-tracepoint/tracelog-internal.h | 83 +++++++++++++++++++
src/lib/lttng-ust-tracepoint/tracelog.c | 40 ++-------
4 files changed, 102 insertions(+), 55 deletions(-)
create mode 100644 src/lib/lttng-ust-tracepoint/tracelog-internal.h
diff --git a/src/common/tracer.h b/src/common/tracer.h
index 2affd6ab..8e18c9b5 100644
--- a/src/common/tracer.h
+++ b/src/common/tracer.h
@@ -26,6 +26,8 @@
#define LTTNG_RFLAG_EXTENDED RING_BUFFER_RFLAG_END
#define LTTNG_RFLAG_END (LTTNG_RFLAG_EXTENDED << 1)
+#define LTTNG_TRACE_PRINTF_BUFSIZE 512
+
/*
* LTTng client type enumeration. Used by the consumer to map the
* callbacks from its own address space.
diff --git a/src/lib/lttng-ust-tracepoint/tracef.c b/src/lib/lttng-ust-tracepoint/tracef.c
index c05c7811..92911e1d 100644
--- a/src/lib/lttng-ust-tracepoint/tracef.c
+++ b/src/lib/lttng-ust-tracepoint/tracef.c
@@ -7,6 +7,7 @@
#define _LGPL_SOURCE
#include <stdio.h>
#include "common/macros.h"
+#include "common/tracer.h"
/* The tracepoint definition is public, but the provider definition is hidden. */
#define LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION
@@ -15,39 +16,22 @@
#define LTTNG_UST_TRACEPOINT_DEFINE
#include "lttng-ust-tracef-provider.h"
-static inline
-void lttng_ust___vtracef(const char *fmt, va_list ap)
- __attribute__((always_inline, format(printf, 1, 0)));
-static inline
-void lttng_ust___vtracef(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_tracef___event(msg, len,
- LTTNG_UST_CALLER_IP());
- free(msg);
-end:
- return;
-}
+#include "tracelog-internal.h"
void lttng_ust__vtracef(const char *fmt, va_list ap)
__attribute__((format(printf, 1, 0)));
void lttng_ust__vtracef(const char *fmt, va_list ap)
{
- lttng_ust___vtracef(fmt, ap);
+ LTTNG_UST_TRACELOG_VALIST(fmt, ap,
+ lttng_ust_tracepoint_cb_lttng_ust_tracef___event,
+ msg, len, LTTNG_UST_CALLER_IP());
}
void lttng_ust__tracef(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
void lttng_ust__tracef(const char *fmt, ...)
{
- va_list ap;
-
- va_start(ap, fmt);
- lttng_ust___vtracef(fmt, ap);
- va_end(ap);
+ LTTNG_UST_TRACELOG_VARARG(fmt,
+ lttng_ust_tracepoint_cb_lttng_ust_tracef___event,
+ msg, len, LTTNG_UST_CALLER_IP());
}
diff --git a/src/lib/lttng-ust-tracepoint/tracelog-internal.h b/src/lib/lttng-ust-tracepoint/tracelog-internal.h
new file mode 100644
index 00000000..291ff27c
--- /dev/null
+++ b/src/lib/lttng-ust-tracepoint/tracelog-internal.h
@@ -0,0 +1,83 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright (C) 2013-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2021 Norbert Lange <nolange79@gmail.com>
+ *
+ * Shared helper macro for tracelog and tracef
+ */
+
+#define LTTNG_UST_TRACELOG_VARARG(fmt, callback, ...) \
+ va_list ap; \
+ char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE]; \
+ int len; \
+ char *msg = local_buf; \
+ size_t buflen = sizeof(local_buf); \
+ char *alloc_buff = NULL; \
+\
+ if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) { \
+ va_start(ap, fmt); \
+ msg = va_arg(ap, char *); \
+ va_end(ap); \
+ len = strlen(msg); \
+ } else \
+ for(;;) { \
+ va_start(ap, fmt); \
+ len = vsnprintf(msg, buflen, fmt, ap); \
+ va_end(ap); \
+\
+ if (caa_unlikely(len >= (int)sizeof(local_buf) && !alloc_buff)) { \
+ buflen = (size_t)len + 1U; \
+ len = -1; \
+ alloc_buff = (char *)malloc(buflen); \
+ msg = alloc_buff; \
+ if (!alloc_buff) \
+ break; \
+ } else \
+ break; \
+ } \
+\
+ /* len does not include the final \0 */ \
+ if (caa_likely(len >= 0)) { \
+ callback(__VA_ARGS__); \
+ } \
+ /* Dont call a potentially instrumented forbidden free needlessly. */ \
+ if (caa_unlikely(alloc_buff)) \
+ free(alloc_buff);
+
+#define LTTNG_UST_TRACELOG_VALIST(fmt, ap, callback, ...) \
+ char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE]; \
+ int len; \
+ char *msg = local_buf; \
+ size_t buflen = sizeof(local_buf); \
+ char *alloc_buff = NULL; \
+\
+ if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) { \
+ msg = va_arg(ap, char *); \
+ len = strlen(msg); \
+ } else \
+ for(;;) { \
+ va_list ap2; \
+\
+ va_copy(ap2, ap); \
+ len = vsnprintf(msg, buflen, fmt, ap2); \
+ va_end(ap2); \
+\
+ if (caa_unlikely(len >= (int)sizeof(local_buf) && !alloc_buff)) { \
+ buflen = (size_t)len + 1U; \
+ len = -1; \
+ alloc_buff = (char *)malloc(buflen); \
+ msg = alloc_buff; \
+ if (!alloc_buff) \
+ break; \
+ } else \
+ break; \
+ } \
+\
+ /* len does not include the final \0 */ \
+ if (caa_likely(len >= 0)) { \
+ callback(__VA_ARGS__); \
+ } \
+ /* Dont call a potentially instrumented forbidden free needlessly. */ \
+ if (caa_unlikely(alloc_buff)) \
+ free(alloc_buff);
diff --git a/src/lib/lttng-ust-tracepoint/tracelog.c b/src/lib/lttng-ust-tracepoint/tracelog.c
index 8147d7a3..bd38032c 100644
--- a/src/lib/lttng-ust-tracepoint/tracelog.c
+++ b/src/lib/lttng-ust-tracepoint/tracelog.c
@@ -7,6 +7,7 @@
#define _LGPL_SOURCE
#include <stdio.h>
#include "common/macros.h"
+#include "common/tracer.h"
/* The tracepoint definition is public, but the provider definition is hidden. */
#define LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION
@@ -15,32 +16,9 @@
#define LTTNG_UST_TRACEPOINT_DEFINE
#include "lttng-ust-tracelog-provider.h"
+#include "tracelog-internal.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) \
@@ -53,7 +31,9 @@
int line, const char *func, \
const char *fmt, va_list ap) \
{ \
- lttng_ust___vtracelog_##level(file, line, func, fmt, ap); \
+ LTTNG_UST_TRACELOG_VALIST(fmt, ap, \
+ lttng_ust_tracepoint_cb_lttng_ust_tracelog___##level, \
+ file, line, func, msg, len, LTTNG_UST_CALLER_IP()); \
} \
\
void lttng_ust__tracelog_##level(const char *file, \
@@ -68,11 +48,9 @@
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); \
+ LTTNG_UST_TRACELOG_VARARG(fmt, \
+ lttng_ust_tracepoint_cb_lttng_ust_tracelog___##level, \
+ file, line, func, msg, len, LTTNG_UST_CALLER_IP()); \
}
LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_EMERG)
--
2.30.2
_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [lttng-dev] [PATCH lttng-ust] Improve tracef/tracelog to use the stack for small strings
2021-05-25 13:44 [lttng-dev] [PATCH lttng-ust] Improve tracef/tracelog to use the stack for small strings Norbert Lange via lttng-dev
@ 2021-05-25 13:47 ` Norbert Lange via lttng-dev
0 siblings, 0 replies; 3+ messages in thread
From: Norbert Lange via lttng-dev @ 2021-05-25 13:47 UTC (permalink / raw)
To: lttng-dev
Am Di., 25. Mai 2021 um 15:44 Uhr schrieb Norbert Lange <nolange79@gmail.com>:
>
> Support two common cases, one being that the resulting message is
> small enough to fit into a on-stack buffer.
> The seconds being the common 'printf("%s", "Message")' scheme.
>
> Unfortunately, iterating a va_list is destructive,
> so it has to be copied before calling vprintf.
>
> The implementation was moved to a separate file,
> used by both tracef.c and tracelog.c.
>
> Signed-off-by: Norbert Lange <nolange79@gmail.com>
> ---
> src/common/tracer.h | 2 +
> src/lib/lttng-ust-tracepoint/tracef.c | 32 ++-----
> .../lttng-ust-tracepoint/tracelog-internal.h | 83 +++++++++++++++++++
> src/lib/lttng-ust-tracepoint/tracelog.c | 40 ++-------
> 4 files changed, 102 insertions(+), 55 deletions(-)
> create mode 100644 src/lib/lttng-ust-tracepoint/tracelog-internal.h
>
> diff --git a/src/common/tracer.h b/src/common/tracer.h
> index 2affd6ab..8e18c9b5 100644
> --- a/src/common/tracer.h
> +++ b/src/common/tracer.h
> @@ -26,6 +26,8 @@
> #define LTTNG_RFLAG_EXTENDED RING_BUFFER_RFLAG_END
> #define LTTNG_RFLAG_END (LTTNG_RFLAG_EXTENDED << 1)
>
> +#define LTTNG_TRACE_PRINTF_BUFSIZE 512
> +
> /*
> * LTTng client type enumeration. Used by the consumer to map the
> * callbacks from its own address space.
> diff --git a/src/lib/lttng-ust-tracepoint/tracef.c b/src/lib/lttng-ust-tracepoint/tracef.c
> index c05c7811..92911e1d 100644
> --- a/src/lib/lttng-ust-tracepoint/tracef.c
> +++ b/src/lib/lttng-ust-tracepoint/tracef.c
> @@ -7,6 +7,7 @@
> #define _LGPL_SOURCE
> #include <stdio.h>
> #include "common/macros.h"
> +#include "common/tracer.h"
>
> /* The tracepoint definition is public, but the provider definition is hidden. */
> #define LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION
> @@ -15,39 +16,22 @@
> #define LTTNG_UST_TRACEPOINT_DEFINE
> #include "lttng-ust-tracef-provider.h"
>
> -static inline
> -void lttng_ust___vtracef(const char *fmt, va_list ap)
> - __attribute__((always_inline, format(printf, 1, 0)));
> -static inline
> -void lttng_ust___vtracef(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_tracef___event(msg, len,
> - LTTNG_UST_CALLER_IP());
> - free(msg);
> -end:
> - return;
> -}
> +#include "tracelog-internal.h"
>
> void lttng_ust__vtracef(const char *fmt, va_list ap)
> __attribute__((format(printf, 1, 0)));
> void lttng_ust__vtracef(const char *fmt, va_list ap)
> {
> - lttng_ust___vtracef(fmt, ap);
> + LTTNG_UST_TRACELOG_VALIST(fmt, ap,
> + lttng_ust_tracepoint_cb_lttng_ust_tracef___event,
> + msg, len, LTTNG_UST_CALLER_IP());
> }
>
> void lttng_ust__tracef(const char *fmt, ...)
> __attribute__((format(printf, 1, 2)));
> void lttng_ust__tracef(const char *fmt, ...)
> {
> - va_list ap;
> -
> - va_start(ap, fmt);
> - lttng_ust___vtracef(fmt, ap);
> - va_end(ap);
> + LTTNG_UST_TRACELOG_VARARG(fmt,
> + lttng_ust_tracepoint_cb_lttng_ust_tracef___event,
> + msg, len, LTTNG_UST_CALLER_IP());
> }
> diff --git a/src/lib/lttng-ust-tracepoint/tracelog-internal.h b/src/lib/lttng-ust-tracepoint/tracelog-internal.h
> new file mode 100644
> index 00000000..291ff27c
> --- /dev/null
> +++ b/src/lib/lttng-ust-tracepoint/tracelog-internal.h
> @@ -0,0 +1,83 @@
> +/*
> + * SPDX-License-Identifier: MIT
> + *
> + * Copyright (C) 2013-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> + * Copyright (C) 2021 Norbert Lange <nolange79@gmail.com>
> + *
> + * Shared helper macro for tracelog and tracef
> + */
> +
> +#define LTTNG_UST_TRACELOG_VARARG(fmt, callback, ...) \
> + va_list ap; \
> + char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE]; \
> + int len; \
> + char *msg = local_buf; \
> + size_t buflen = sizeof(local_buf); \
> + char *alloc_buff = NULL; \
> +\
> + if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) { \
> + va_start(ap, fmt); \
> + msg = va_arg(ap, char *); \
> + va_end(ap); \
> + len = strlen(msg); \
> + } else \
> + for(;;) { \
> + va_start(ap, fmt); \
> + len = vsnprintf(msg, buflen, fmt, ap); \
> + va_end(ap); \
> +\
> + if (caa_unlikely(len >= (int)sizeof(local_buf) && !alloc_buff)) { \
> + buflen = (size_t)len + 1U; \
> + len = -1; \
> + alloc_buff = (char *)malloc(buflen); \
> + msg = alloc_buff; \
> + if (!alloc_buff) \
> + break; \
> + } else \
> + break; \
> + } \
> +\
> + /* len does not include the final \0 */ \
> + if (caa_likely(len >= 0)) { \
> + callback(__VA_ARGS__); \
> + } \
> + /* Dont call a potentially instrumented forbidden free needlessly. */ \
> + if (caa_unlikely(alloc_buff)) \
> + free(alloc_buff);
> +
> +#define LTTNG_UST_TRACELOG_VALIST(fmt, ap, callback, ...) \
> + char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE]; \
> + int len; \
> + char *msg = local_buf; \
> + size_t buflen = sizeof(local_buf); \
> + char *alloc_buff = NULL; \
> +\
> + if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) { \
> + msg = va_arg(ap, char *); \
> + len = strlen(msg); \
> + } else \
> + for(;;) { \
> + va_list ap2; \
> +\
> + va_copy(ap2, ap); \
> + len = vsnprintf(msg, buflen, fmt, ap2); \
> + va_end(ap2); \
> +\
> + if (caa_unlikely(len >= (int)sizeof(local_buf) && !alloc_buff)) { \
> + buflen = (size_t)len + 1U; \
> + len = -1; \
> + alloc_buff = (char *)malloc(buflen); \
> + msg = alloc_buff; \
> + if (!alloc_buff) \
> + break; \
> + } else \
> + break; \
> + } \
> +\
> + /* len does not include the final \0 */ \
> + if (caa_likely(len >= 0)) { \
> + callback(__VA_ARGS__); \
> + } \
> + /* Dont call a potentially instrumented forbidden free needlessly. */ \
> + if (caa_unlikely(alloc_buff)) \
> + free(alloc_buff);
> diff --git a/src/lib/lttng-ust-tracepoint/tracelog.c b/src/lib/lttng-ust-tracepoint/tracelog.c
> index 8147d7a3..bd38032c 100644
> --- a/src/lib/lttng-ust-tracepoint/tracelog.c
> +++ b/src/lib/lttng-ust-tracepoint/tracelog.c
> @@ -7,6 +7,7 @@
> #define _LGPL_SOURCE
> #include <stdio.h>
> #include "common/macros.h"
> +#include "common/tracer.h"
>
> /* The tracepoint definition is public, but the provider definition is hidden. */
> #define LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION
> @@ -15,32 +16,9 @@
> #define LTTNG_UST_TRACEPOINT_DEFINE
> #include "lttng-ust-tracelog-provider.h"
>
> +#include "tracelog-internal.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) \
> @@ -53,7 +31,9 @@
> int line, const char *func, \
> const char *fmt, va_list ap) \
> { \
> - lttng_ust___vtracelog_##level(file, line, func, fmt, ap); \
> + LTTNG_UST_TRACELOG_VALIST(fmt, ap, \
> + lttng_ust_tracepoint_cb_lttng_ust_tracelog___##level, \
> + file, line, func, msg, len, LTTNG_UST_CALLER_IP()); \
> } \
> \
> void lttng_ust__tracelog_##level(const char *file, \
> @@ -68,11 +48,9 @@
> 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); \
> + LTTNG_UST_TRACELOG_VARARG(fmt, \
> + lttng_ust_tracepoint_cb_lttng_ust_tracelog___##level, \
> + file, line, func, msg, len, LTTNG_UST_CALLER_IP()); \
> }
>
> LTTNG_UST_TRACELOG_CB(LTTNG_UST_TRACEPOINT_LOGLEVEL_EMERG)
> --
> 2.30.2
>
This is to be applied on top of:
https://review.lttng.org/c/lttng-ust/+/5927 Move tracef/tracelog
symbols to liblttng-ust-tracepoint.so
So consider this a WIP for feedback.
Norbert
_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
^ permalink raw reply [flat|nested] 3+ messages in thread
* [lttng-dev] [PATCH lttng-ust] Improve tracelog handling, reduce exported functions
@ 2021-05-20 12:18 Norbert Lange via lttng-dev
2021-05-20 12:18 ` [lttng-dev] [PATCH lttng-ust] Improve tracef/tracelog to use the stack for small strings Norbert Lange via lttng-dev
0 siblings, 1 reply; 3+ messages in thread
From: Norbert Lange via lttng-dev @ 2021-05-20 12:18 UTC (permalink / raw)
To: lttng-dev
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@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(<tng_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(<tng_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@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [lttng-dev] [PATCH lttng-ust] Improve tracef/tracelog to use the stack for small strings
2021-05-20 12:18 [lttng-dev] [PATCH lttng-ust] Improve tracelog handling, reduce exported functions Norbert Lange via lttng-dev
@ 2021-05-20 12:18 ` Norbert Lange via lttng-dev
0 siblings, 0 replies; 3+ messages in thread
From: Norbert Lange via lttng-dev @ 2021-05-20 12:18 UTC (permalink / raw)
To: lttng-dev
Support two common cases, one being that the resulting message is
small enough to fit into a on-stack buffer.
The seconds being the common 'printf("%s", "Message")' scheme.
Unfortunately, iterating a va_list is destructive,
so it has to be copied before calling vprintf.
This will result in the function never becoming inlined,
thus the helper function was manually "inlined".
Signed-off-by: Norbert Lange <nolange79@gmail.com>
---
src/common/tracer.h | 2 +
src/lib/lttng-ust/tracef.c | 83 ++++++++++++++++++++++++---------
src/lib/lttng-ust/tracelog.c | 90 ++++++++++++++++++++++++------------
3 files changed, 122 insertions(+), 53 deletions(-)
diff --git a/src/common/tracer.h b/src/common/tracer.h
index 2affd6ab..8e18c9b5 100644
--- a/src/common/tracer.h
+++ b/src/common/tracer.h
@@ -26,6 +26,8 @@
#define LTTNG_RFLAG_EXTENDED RING_BUFFER_RFLAG_END
#define LTTNG_RFLAG_END (LTTNG_RFLAG_EXTENDED << 1)
+#define LTTNG_TRACE_PRINTF_BUFSIZE 512
+
/*
* LTTng client type enumeration. Used by the consumer to map the
* callbacks from its own address space.
diff --git a/src/lib/lttng-ust/tracef.c b/src/lib/lttng-ust/tracef.c
index c05c7811..21af5b9e 100644
--- a/src/lib/lttng-ust/tracef.c
+++ b/src/lib/lttng-ust/tracef.c
@@ -7,6 +7,7 @@
#define _LGPL_SOURCE
#include <stdio.h>
#include "common/macros.h"
+#include "common/tracer.h"
/* The tracepoint definition is public, but the provider definition is hidden. */
#define LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION
@@ -15,30 +16,40 @@
#define LTTNG_UST_TRACEPOINT_DEFINE
#include "lttng-ust-tracef-provider.h"
-static inline
-void lttng_ust___vtracef(const char *fmt, va_list ap)
- __attribute__((always_inline, format(printf, 1, 0)));
-static inline
-void lttng_ust___vtracef(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_tracef___event(msg, len,
- LTTNG_UST_CALLER_IP());
- free(msg);
-end:
- return;
-}
-
void lttng_ust__vtracef(const char *fmt, va_list ap)
__attribute__((format(printf, 1, 0)));
void lttng_ust__vtracef(const char *fmt, va_list ap)
{
- lttng_ust___vtracef(fmt, ap);
+ char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE];
+ char *alloc_buff = NULL;
+ char *msg = local_buf;
+ size_t buflen = sizeof(local_buf);
+ int len = -1;
+
+ if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) {
+ msg = va_arg(ap, char *);
+ len = strlen(msg);
+ } else
+ do {
+ va_list ap2;
+
+ if (caa_unlikely(len >= sizeof(local_buf))) {
+ buflen = (size_t)(len) + 1U;
+ alloc_buff = (char *)malloc(buflen);
+ msg = alloc_buff;
+ if (!alloc_buff)
+ return;
+ }
+ va_copy(ap2, ap);
+ len = vsnprintf(msg, buflen, fmt, ap2);
+ va_end(ap2);
+ } while (caa_unlikely(len >= sizeof(local_buf) && !alloc_buff));
+
+ /* len does not include the final \0 */
+ if (caa_likely(len >= 0))
+ lttng_ust_tracepoint_cb_lttng_ust_tracef___event(msg, len,
+ LTTNG_UST_CALLER_IP());
+ free(alloc_buff);
}
void lttng_ust__tracef(const char *fmt, ...)
@@ -46,8 +57,34 @@ void lttng_ust__tracef(const char *fmt, ...)
void lttng_ust__tracef(const char *fmt, ...)
{
va_list ap;
+ char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE];
+ char *alloc_buff = NULL;
+ char *msg = local_buf;
+ size_t buflen = sizeof(local_buf);
+ int len = -1;
- va_start(ap, fmt);
- lttng_ust___vtracef(fmt, ap);
- va_end(ap);
+ if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) {
+ va_start(ap, fmt);
+ msg = va_arg(ap, char *);
+ va_end(ap);
+ len = strlen(msg);
+ } else
+ do {
+ if (caa_unlikely(len >= sizeof(local_buf))) {
+ buflen = (size_t)(len) + 1U;
+ alloc_buff = (char *)malloc(buflen);
+ msg = alloc_buff;
+ if (!alloc_buff)
+ return;
+ }
+ va_start(ap, fmt);
+ len = vsnprintf(msg, buflen, fmt, ap);
+ va_end(ap);
+ } while (caa_unlikely(len >= sizeof(local_buf) && !alloc_buff));
+
+ /* len does not include the final \0 */
+ if (caa_likely(len >= 0))
+ lttng_ust_tracepoint_cb_lttng_ust_tracef___event(msg, len,
+ LTTNG_UST_CALLER_IP());
+ free(alloc_buff);
}
diff --git a/src/lib/lttng-ust/tracelog.c b/src/lib/lttng-ust/tracelog.c
index b28c6c78..6889869c 100644
--- a/src/lib/lttng-ust/tracelog.c
+++ b/src/lib/lttng-ust/tracelog.c
@@ -7,6 +7,7 @@
#define _LGPL_SOURCE
#include <stdio.h>
#include "common/macros.h"
+#include "common/tracer.h"
/* The tracepoint definition is public, but the provider definition is hidden. */
#define LTTNG_UST_TRACEPOINT_PROVIDER_HIDDEN_DEFINITION
@@ -31,44 +32,73 @@ 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;
+ char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE];
+ char *alloc_buff = NULL;
+ char *msg = local_buf;
+ size_t buflen = sizeof(local_buf);
+ int len = -1;
+
+ if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) {
+ va_start(ap, fmt);
+ msg = va_arg(ap, char *);
+ va_end(ap);
+ len = strlen(msg);
+ } else
+ do {
+ if (caa_unlikely(len >= sizeof(local_buf))) {
+ buflen = (size_t)(len) + 1U;
+ alloc_buff = (char *)malloc(buflen);
+ msg = alloc_buff;
+ if (!alloc_buff)
+ return;
+ }
+ va_start(ap, fmt);
+ len = vsnprintf(msg, buflen, fmt, ap);
+ va_end(ap);
+ } while (caa_unlikely(len >= sizeof(local_buf) && !alloc_buff));
- va_start(ap, fmt);
- lttng_ust___tracelog_vprintf(callback, source, fmt, ap);
- va_end(ap);
+ /* len does not include the final \0 */
+ if (caa_likely(len >= 0))
+ (*callback)(source->file, source->line, source->func, msg, len,
+ LTTNG_UST_CALLER_IP());
+ free(alloc_buff);
}
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);
+ char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE];
+ char *alloc_buff = NULL;
+ char *msg = local_buf;
+ size_t buflen = sizeof(local_buf);
+ int len = -1;
+
+ if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) {
+ msg = va_arg(ap, char *);
+ len = strlen(msg);
+ } else
+ do {
+ va_list ap2;
+
+ if (caa_unlikely(len >= sizeof(local_buf))) {
+ buflen = (size_t)(len) + 1U;
+ alloc_buff = (char *)malloc(buflen);
+ msg = alloc_buff;
+ if (!alloc_buff)
+ return;
+ }
+ va_copy(ap2, ap);
+ len = vsnprintf(msg, buflen, fmt, ap2);
+ va_end(ap2);
+ } while (caa_unlikely(len >= sizeof(local_buf) && !alloc_buff));
+
+ /* len does not include the final \0 */
+ if (caa_likely(len >= 0))
+ (*callback)(source->file, source->line, source->func, msg, len,
+ LTTNG_UST_CALLER_IP());
+ free(alloc_buff);
}
--
2.30.2
_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-05-25 13:47 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-25 13:44 [lttng-dev] [PATCH lttng-ust] Improve tracef/tracelog to use the stack for small strings Norbert Lange via lttng-dev
2021-05-25 13:47 ` Norbert Lange via lttng-dev
-- strict thread matches above, loose matches on Subject: below --
2021-05-20 12:18 [lttng-dev] [PATCH lttng-ust] Improve tracelog handling, reduce exported functions Norbert Lange via lttng-dev
2021-05-20 12:18 ` [lttng-dev] [PATCH lttng-ust] Improve tracef/tracelog to use the stack for small strings Norbert Lange via lttng-dev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).