Commit | Line | Data |
---|---|---|
5e96a467 | 1 | /* |
c0c0989a | 2 | * SPDX-License-Identifier: LGPL-2.1-only |
30ffe279 | 3 | * |
c0c0989a MJ |
4 | * Copyright (C) 2009 Pierre-Marc Fournier |
5 | * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
30ffe279 NC |
6 | */ |
7 | ||
c6e6343c MJ |
8 | #ifndef _UST_COMMON_LOGGING_H |
9 | #define _UST_COMMON_LOGGING_H | |
c0c0989a | 10 | |
30ffe279 NC |
11 | #include <string.h> |
12 | #include <sys/types.h> | |
30ffe279 NC |
13 | #include <errno.h> |
14 | #include <stdarg.h> | |
2b6f4374 | 15 | #include <stdbool.h> |
30ffe279 | 16 | #include <stdio.h> |
c6e6343c MJ |
17 | |
18 | #include <lttng/ust-utils.h> | |
39313bf3 MJ |
19 | #include <urcu/compiler.h> |
20 | #include <urcu/system.h> | |
c6e6343c | 21 | |
9d315d6d MJ |
22 | #include "common/patient.h" |
23 | #include "common/compat/tid.h" | |
24 | #include "common/safe-snprintf.h" | |
30ffe279 | 25 | |
c6e6343c MJ |
26 | enum lttng_ust_log_level { |
27 | LTTNG_UST_LOG_LEVEL_UNKNOWN = 0, | |
39313bf3 | 28 | LTTNG_UST_LOG_LEVEL_SILENT, |
c6e6343c | 29 | LTTNG_UST_LOG_LEVEL_DEBUG, |
5e96a467 MD |
30 | }; |
31 | ||
9ff107a9 MJ |
32 | enum lttng_ust_log_critical_action { |
33 | LTTNG_UST_LOG_CRITICAL_ACTION_UNKNOWN = 0, | |
34 | LTTNG_UST_LOG_CRITICAL_ACTION_NONE, | |
35 | LTTNG_UST_LOG_CRITICAL_ACTION_ABORT, | |
36 | }; | |
37 | ||
39313bf3 | 38 | extern int lttng_ust_log_level /* enum lttng_ust_log_level */ |
1d18d519 | 39 | __attribute__((visibility("hidden"))); |
ddabe860 | 40 | |
9ff107a9 MJ |
41 | extern int lttng_ust_log_critical_action /* enum lttng_ust_log_critical_action */ |
42 | __attribute__((visibility("hidden"))); | |
43 | ||
39313bf3 MJ |
44 | /* |
45 | * Initialize the global log level from the "LTTNG_UST_DEBUG" environment | |
9ff107a9 | 46 | * variable and the global log critical action from "LTTNG_UST_ABORT_ON_CRITICAL". |
39313bf3 MJ |
47 | * |
48 | * This could end up being called concurrently by multiple threads but doesn't | |
49 | * require a mutex since the input is invariant across threads and the result | |
50 | * will be the same. | |
39313bf3 | 51 | */ |
9ff107a9 | 52 | void lttng_ust_logging_init(void) |
1d18d519 | 53 | __attribute__((visibility("hidden"))); |
5e96a467 | 54 | |
7bdd21a4 | 55 | #ifdef LTTNG_UST_DEBUG |
39313bf3 MJ |
56 | static inline |
57 | bool lttng_ust_logging_debug_enabled(void) | |
7bdd21a4 | 58 | { |
2b6f4374 | 59 | return true; |
7bdd21a4 MD |
60 | } |
61 | #else /* #ifdef LTTNG_UST_DEBUG */ | |
39313bf3 MJ |
62 | static inline |
63 | bool lttng_ust_logging_debug_enabled(void) | |
5e96a467 | 64 | { |
39313bf3 MJ |
65 | int current_log_level; |
66 | ||
67 | current_log_level = CMM_LOAD_SHARED(lttng_ust_log_level); | |
68 | ||
69 | /* If the global log level is unknown, lazy-initialize it. */ | |
9ff107a9 MJ |
70 | if (caa_unlikely(current_log_level == LTTNG_UST_LOG_LEVEL_UNKNOWN)) { |
71 | lttng_ust_logging_init(); | |
72 | current_log_level = CMM_LOAD_SHARED(lttng_ust_log_level); | |
73 | } | |
39313bf3 MJ |
74 | |
75 | return current_log_level == LTTNG_UST_LOG_LEVEL_DEBUG; | |
5e96a467 | 76 | } |
39313bf3 | 77 | #endif /* #ifdef LTTNG_UST_DEBUG */ |
5e96a467 | 78 | |
9ff107a9 MJ |
79 | #ifdef LTTNG_UST_ABORT_ON_CRITICAL |
80 | static inline | |
81 | bool lttng_ust_logging_abort_on_critical_enabled(void) | |
82 | { | |
83 | return true; | |
84 | } | |
85 | #else /* #ifdef LTTNG_UST_ABORT_ON_CRITICAL */ | |
86 | static inline | |
87 | bool lttng_ust_logging_abort_on_critical_enabled(void) | |
88 | { | |
89 | int current_log_critical_action; | |
90 | ||
91 | current_log_critical_action = CMM_LOAD_SHARED(lttng_ust_log_critical_action); | |
92 | ||
93 | /* If the global log critical action is unknown, lazy-initialize it. */ | |
94 | if (caa_unlikely(current_log_critical_action == LTTNG_UST_LOG_CRITICAL_ACTION_UNKNOWN)) { | |
95 | lttng_ust_logging_init(); | |
96 | current_log_critical_action = CMM_LOAD_SHARED(lttng_ust_log_critical_action); | |
97 | } | |
98 | ||
99 | return current_log_critical_action == LTTNG_UST_LOG_CRITICAL_ACTION_ABORT; | |
100 | } | |
101 | #endif /* #ifdef LTTNG_UST_ABORT_ON_CRITICAL */ | |
102 | ||
2b6f4374 | 103 | /* |
9ff107a9 | 104 | * The default component for log statements. |
2b6f4374 | 105 | */ |
30ffe279 | 106 | #ifndef UST_COMPONENT |
30ffe279 NC |
107 | #define UST_COMPONENT libust |
108 | #endif | |
109 | ||
c6e6343c | 110 | #define LTTNG_UST_LOG_MAX_LEN 512 |
37ed587a | 111 | |
2b6f4374 MJ |
112 | /* |
113 | * We sometimes print in the tracing path, and tracing can occur in | |
30ffe279 NC |
114 | * signal handlers, so we must use a print method which is signal safe. |
115 | */ | |
c6e6343c | 116 | /* Can't use dynamic allocation. Limit ourselves to LTTNG_UST_LOG_MAX_LEN chars. */ |
648bb724 | 117 | /* Add end of string in case of buffer overflow. */ |
5e96a467 | 118 | #define sigsafe_print_err(fmt, args...) \ |
648bb724 | 119 | do { \ |
c6e6343c MJ |
120 | if (lttng_ust_logging_debug_enabled()) { \ |
121 | char ____buf[LTTNG_UST_LOG_MAX_LEN]; \ | |
7bdd21a4 MD |
122 | int ____saved_errno; \ |
123 | \ | |
124 | ____saved_errno = errno; /* signal-safety */ \ | |
125 | ust_safe_snprintf(____buf, sizeof(____buf), fmt, ## args); \ | |
126 | ____buf[sizeof(____buf) - 1] = 0; \ | |
516d12da | 127 | ust_patient_write(STDERR_FILENO, ____buf, strlen(____buf)); \ |
7bdd21a4 MD |
128 | errno = ____saved_errno; /* signal-safety */ \ |
129 | fflush(stderr); \ | |
130 | } \ | |
648bb724 | 131 | } while (0) |
30ffe279 | 132 | |
c6e6343c | 133 | #define LTTNG_UST_STR_COMPONENT lttng_ust_stringify(UST_COMPONENT) |
30ffe279 | 134 | |
5e96a467 MD |
135 | #define ERRMSG(fmt, args...) \ |
136 | do { \ | |
c6e6343c | 137 | sigsafe_print_err(LTTNG_UST_STR_COMPONENT "[%ld/%ld]: " fmt " (in %s() at " __FILE__ ":" lttng_ust_stringify(__LINE__) ")\n", \ |
5e96a467 | 138 | (long) getpid(), \ |
0f029713 | 139 | (long) lttng_gettid(), \ |
5e96a467 | 140 | ## args, __func__); \ |
5e96a467 | 141 | } while(0) |
30ffe279 | 142 | |
7bdd21a4 MD |
143 | |
144 | #define DBG(fmt, args...) ERRMSG(fmt, ## args) | |
145 | #define DBG_raw(fmt, args...) sigsafe_print_err(fmt, ## args) | |
146 | #define WARN(fmt, args...) ERRMSG("Warning: " fmt, ## args) | |
147 | #define ERR(fmt, args...) ERRMSG("Error: " fmt, ## args) | |
9ff107a9 MJ |
148 | #define CRIT(fmt, args...) \ |
149 | do { \ | |
150 | ERRMSG("Critical: " fmt, ## args); \ | |
151 | if (lttng_ust_logging_abort_on_critical_enabled()) { \ | |
152 | abort(); \ | |
153 | } \ | |
154 | } while(0) | |
30ffe279 | 155 | |
b52af467 | 156 | #if !defined(__GLIBC__) || ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE)) |
9fd26814 MD |
157 | /* |
158 | * Version using XSI strerror_r. | |
159 | */ | |
7bdd21a4 MD |
160 | #define PERROR(call, args...) \ |
161 | do { \ | |
c6e6343c | 162 | if (lttng_ust_logging_debug_enabled()) { \ |
4041a8a7 MJ |
163 | char perror_buf[200] = "Error in strerror_r()"; \ |
164 | strerror_r(errno, perror_buf, \ | |
165 | sizeof(perror_buf)); \ | |
166 | ERRMSG("Error: " call ": %s", ## args, \ | |
167 | perror_buf); \ | |
7bdd21a4 MD |
168 | } \ |
169 | } while(0) | |
30ffe279 | 170 | #else |
9fd26814 MD |
171 | /* |
172 | * Version using GNU strerror_r, for linux with appropriate defines. | |
173 | */ | |
7bdd21a4 MD |
174 | #define PERROR(call, args...) \ |
175 | do { \ | |
c6e6343c | 176 | if (lttng_ust_logging_debug_enabled()) { \ |
4041a8a7 MJ |
177 | char *perror_buf; \ |
178 | char perror_tmp[200]; \ | |
179 | perror_buf = strerror_r(errno, perror_tmp, \ | |
180 | sizeof(perror_tmp)); \ | |
181 | ERRMSG("Error: " call ": %s", ## args, \ | |
182 | perror_buf); \ | |
7bdd21a4 MD |
183 | } \ |
184 | } while(0) | |
30ffe279 NC |
185 | #endif |
186 | ||
5e96a467 MD |
187 | #define BUG_ON(condition) \ |
188 | do { \ | |
b5a3dfa5 | 189 | if (caa_unlikely(condition)) \ |
5e96a467 MD |
190 | ERR("condition not respected (BUG) on line %s:%d", __FILE__, __LINE__); \ |
191 | } while(0) | |
192 | #define WARN_ON(condition) \ | |
193 | do { \ | |
b5a3dfa5 | 194 | if (caa_unlikely(condition)) \ |
5e96a467 MD |
195 | WARN("condition not respected on line %s:%d", __FILE__, __LINE__); \ |
196 | } while(0) | |
30ffe279 NC |
197 | #define WARN_ON_ONCE(condition) WARN_ON(condition) |
198 | ||
c6e6343c | 199 | #endif /* _UST_COMMON_LOGGING_H */ |