Improve tracef/tracelog to use the stack for small strings
[lttng-ust.git] / src / lib / lttng-ust / tracelog-internal.h
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright (C) 2013-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 * Copyright (C) 2021 Norbert Lange <nolange79@gmail.com>
6 *
7 * Shared helper macro for tracelog and tracef.
8 */
9
10 #define LTTNG_UST_TRACELOG_VARARG(fmt, callback, ...) \
11 do { \
12 char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE]; \
13 char *alloc_buff = NULL, *msg = local_buf; \
14 size_t len = 0; \
15 va_list ap; \
16 \
17 if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) { \
18 va_start(ap, fmt); \
19 msg = va_arg(ap, char *); \
20 va_end(ap); \
21 len = strlen(msg); \
22 } else { \
23 size_t buflen = sizeof(local_buf); \
24 int ret; \
25 \
26 /* On-stack buffer attempt */ \
27 va_start(ap, fmt); \
28 ret = vsnprintf(msg, buflen, fmt, ap); \
29 va_end(ap); \
30 if (caa_unlikely(ret < 0)) \
31 break; \
32 len = (size_t)ret; \
33 \
34 if (caa_unlikely(len >= sizeof(local_buf))) { \
35 buflen = len + 1; \
36 alloc_buff = (char *)malloc(buflen); \
37 if (!alloc_buff) \
38 goto end; \
39 msg = alloc_buff; \
40 va_start(ap, fmt); \
41 ret = vsnprintf(msg, buflen, fmt, ap); \
42 va_end(ap); \
43 lttng_ust_runtime_bug_on(ret < 0 || (size_t)ret != buflen - 1); \
44 len = (size_t)ret; \
45 } \
46 } \
47 \
48 callback(__VA_ARGS__); \
49 end: \
50 /* Don't call a potentially instrumented forbidden free needlessly. */ \
51 if (caa_unlikely(alloc_buff)) \
52 free(alloc_buff); \
53 } while(0)
54
55 #define LTTNG_UST_TRACELOG_VALIST(fmt, ap, callback, ...) \
56 do { \
57 char local_buf[LTTNG_TRACE_PRINTF_BUFSIZE]; \
58 char *alloc_buff = NULL, *msg = local_buf; \
59 size_t len = 0; \
60 \
61 if (caa_unlikely(fmt[0] == '%' && fmt[1] == 's' && fmt[2] == '\0')) { \
62 msg = va_arg(ap, char *); \
63 len = strlen(msg); \
64 } else { \
65 size_t buflen = sizeof(local_buf); \
66 va_list ap2; \
67 int ret; \
68 \
69 va_copy(ap2, ap); \
70 ret = vsnprintf(msg, buflen, fmt, ap2); \
71 va_end(ap2); \
72 if (caa_unlikely(ret < 0)) \
73 break; \
74 len = (size_t)ret; \
75 \
76 if (caa_unlikely(len >= sizeof(local_buf))) { \
77 buflen = len + 1; \
78 alloc_buff = (char *)malloc(buflen); \
79 if (!alloc_buff) \
80 goto end; \
81 msg = alloc_buff; \
82 ret = vsnprintf(msg, buflen, fmt, ap); \
83 lttng_ust_runtime_bug_on(ret < 0 || (size_t)ret != buflen - 1); \
84 len = (size_t)ret; \
85 } \
86 } \
87 \
88 callback(__VA_ARGS__); \
89 end: \
90 /* Don't call a potentially instrumented forbidden free needlessly. */ \
91 if (caa_unlikely(alloc_buff)) \
92 free(alloc_buff); \
93 } while (0)
This page took 0.031205 seconds and 4 git commands to generate.