From: Norbert Lange via lttng-dev <lttng-dev@lists.lttng.org>
To: lttng-dev@lists.lttng.org
Subject: [lttng-dev] [PATCH v2] Improve tracef/tracelog to use the stack for small strings
Date: Mon, 1 Aug 2022 16:35:24 +0200 [thread overview]
Message-ID: <20220801143524.160208-1-norbert.lange@andritz.com> (raw)
From: 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>
---
v2 -> v3:
* Wrap macro in do/while
* drop loop
* other changes in response to feedback
v2:
- move define into src/common/tracer.h
see https://lists.lttng.org/pipermail/lttng-dev/2021-May/029977.html
- moved macro magic into common tracelog-internal.h header
- rebased onto master
---
src/common/tracer.h | 2 +
src/lib/lttng-ust/tracef.c | 32 +++------
src/lib/lttng-ust/tracelog-internal.h | 95 +++++++++++++++++++++++++++
src/lib/lttng-ust/tracelog.c | 40 +++--------
4 files changed, 114 insertions(+), 55 deletions(-)
create mode 100644 src/lib/lttng-ust/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/tracef.c b/src/lib/lttng-ust/tracef.c
index c05c7811..92911e1d 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,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/tracelog-internal.h b/src/lib/lttng-ust/tracelog-internal.h
new file mode 100644
index 00000000..34537023
--- /dev/null
+++ b/src/lib/lttng-ust/tracelog-internal.h
@@ -0,0 +1,95 @@
+/*
+ * 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, ...) \
+ do { \
+ va_list ap; \
+ char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE]; \
+ size_t len = 0; \
+ char *msg = 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 { \
+ int ret; \
+ size_t buflen = sizeof(local_buf); \
+\
+ /* On-stack buffer attempt */ \
+ va_start(ap, fmt); \
+ ret = vsnprintf(msg, buflen, fmt, ap); \
+ va_end(ap); \
+ if (caa_unlikely(ret < 0)) \
+ break; \
+ len = (size_t)ret; \
+\
+ if (caa_unlikely(len >= sizeof(local_buf))) { \
+ buflen = len + 1; \
+ alloc_buff = (char *)malloc(buflen); \
+ if (!alloc_buff) \
+ goto end; \
+ msg = alloc_buff; \
+ va_start(ap, fmt); \
+ ret = vsnprintf(msg, buflen, fmt, ap); \
+ va_end(ap); \
+ lttng_ust_runtime_bug_on(ret < 0 || (size_t)ret != buflen - 1); \
+ len = (size_t)ret; \
+ } \
+ } \
+\
+ callback(__VA_ARGS__); \
+end: \
+ /* Don't call a potentially instrumented forbidden free needlessly. */ \
+ if (caa_unlikely(alloc_buff)) \
+ free(alloc_buff); \
+ } while(0)
+
+#define LTTNG_UST_TRACELOG_VALIST(fmt, ap, callback, ...) \
+ do { \
+ char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE]; \
+ size_t len = 0; \
+ char *msg = 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 { \
+ va_list ap2; \
+ int ret; \
+ size_t buflen = sizeof(local_buf); \
+\
+ va_copy(ap2, ap); \
+ ret = vsnprintf(msg, buflen, fmt, ap2); \
+ va_end(ap2); \
+ if (caa_unlikely(ret < 0)) \
+ break; \
+ len = (size_t)ret; \
+\
+ if (caa_unlikely(len >= sizeof(local_buf))) { \
+ buflen = len + 1; \
+ alloc_buff = (char *)malloc(buflen); \
+ if (!alloc_buff) \
+ goto end; \
+ msg = alloc_buff; \
+ ret = vsnprintf(msg, buflen, fmt, ap); \
+ lttng_ust_runtime_bug_on(ret < 0 || (size_t)ret != buflen - 1); \
+ len = (size_t)ret; \
+ } \
+ } \
+\
+ callback(__VA_ARGS__); \
+end: \
+ /* Don't call a potentially instrumented forbidden free needlessly. */ \
+ if (caa_unlikely(alloc_buff)) \
+ free(alloc_buff); \
+ } while (0)
diff --git a/src/lib/lttng-ust/tracelog.c b/src/lib/lttng-ust/tracelog.c
index 8147d7a3..bd38032c 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
@@ -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.35.1
_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
next reply other threads:[~2022-08-01 14:35 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-01 14:35 Norbert Lange via lttng-dev [this message]
2022-08-01 14:44 ` [lttng-dev] [PATCH v2] Improve tracef/tracelog to use the stack for small strings Norbert Lange via lttng-dev
2022-08-01 15:24 ` Mathieu Desnoyers via lttng-dev
2022-08-01 15:12 ` Mathieu Desnoyers via lttng-dev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220801143524.160208-1-norbert.lange@andritz.com \
--to=lttng-dev@lists.lttng.org \
--cc=nolange79@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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 read-only IMAP folder(s) and NNTP newsgroup(s).