Commit | Line | Data |
---|---|---|
1c0569ec NL |
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) |