1*61046927SAndroid Build Coastguard Worker /**************************************************************************
2*61046927SAndroid Build Coastguard Worker *
3*61046927SAndroid Build Coastguard Worker * Copyright 2008 VMware, Inc.
4*61046927SAndroid Build Coastguard Worker * All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the
8*61046927SAndroid Build Coastguard Worker * "Software"), to deal in the Software without restriction, including
9*61046927SAndroid Build Coastguard Worker * without limitation the rights to use, copy, modify, merge, publish,
10*61046927SAndroid Build Coastguard Worker * distribute, sub license, and/or sell copies of the Software, and to
11*61046927SAndroid Build Coastguard Worker * permit persons to whom the Software is furnished to do so, subject to
12*61046927SAndroid Build Coastguard Worker * the following conditions:
13*61046927SAndroid Build Coastguard Worker *
14*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the
15*61046927SAndroid Build Coastguard Worker * next paragraph) shall be included in all copies or substantial portions
16*61046927SAndroid Build Coastguard Worker * of the Software.
17*61046927SAndroid Build Coastguard Worker *
18*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*61046927SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21*61046927SAndroid Build Coastguard Worker * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22*61046927SAndroid Build Coastguard Worker * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23*61046927SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24*61046927SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25*61046927SAndroid Build Coastguard Worker *
26*61046927SAndroid Build Coastguard Worker **************************************************************************/
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker /**
29*61046927SAndroid Build Coastguard Worker * @file
30*61046927SAndroid Build Coastguard Worker * Cross-platform debugging helpers.
31*61046927SAndroid Build Coastguard Worker *
32*61046927SAndroid Build Coastguard Worker * For now it just has assert and printf replacements, but it might be extended
33*61046927SAndroid Build Coastguard Worker * with stack trace reports and more advanced logging in the near future.
34*61046927SAndroid Build Coastguard Worker *
35*61046927SAndroid Build Coastguard Worker * @author Jose Fonseca <[email protected]>
36*61046927SAndroid Build Coastguard Worker */
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker #ifndef U_DEBUG_H_
39*61046927SAndroid Build Coastguard Worker #define U_DEBUG_H_
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
42*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
43*61046927SAndroid Build Coastguard Worker #include <string.h>
44*61046927SAndroid Build Coastguard Worker #if !defined(_WIN32)
45*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
46*61046927SAndroid Build Coastguard Worker #include <unistd.h>
47*61046927SAndroid Build Coastguard Worker #endif
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker #include "util/os_misc.h"
50*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
51*61046927SAndroid Build Coastguard Worker #include "util/detect_os.h"
52*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
53*61046927SAndroid Build Coastguard Worker
54*61046927SAndroid Build Coastguard Worker #if DETECT_OS_HAIKU
55*61046927SAndroid Build Coastguard Worker /* Haiku provides debug_printf in libroot with OS.h */
56*61046927SAndroid Build Coastguard Worker #include <OS.h>
57*61046927SAndroid Build Coastguard Worker #endif
58*61046927SAndroid Build Coastguard Worker
59*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus
60*61046927SAndroid Build Coastguard Worker extern "C" {
61*61046927SAndroid Build Coastguard Worker #endif
62*61046927SAndroid Build Coastguard Worker
63*61046927SAndroid Build Coastguard Worker enum util_debug_type
64*61046927SAndroid Build Coastguard Worker {
65*61046927SAndroid Build Coastguard Worker UTIL_DEBUG_TYPE_OUT_OF_MEMORY = 1,
66*61046927SAndroid Build Coastguard Worker UTIL_DEBUG_TYPE_ERROR,
67*61046927SAndroid Build Coastguard Worker UTIL_DEBUG_TYPE_SHADER_INFO,
68*61046927SAndroid Build Coastguard Worker UTIL_DEBUG_TYPE_PERF_INFO,
69*61046927SAndroid Build Coastguard Worker UTIL_DEBUG_TYPE_INFO,
70*61046927SAndroid Build Coastguard Worker UTIL_DEBUG_TYPE_FALLBACK,
71*61046927SAndroid Build Coastguard Worker UTIL_DEBUG_TYPE_CONFORMANCE,
72*61046927SAndroid Build Coastguard Worker };
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard Worker /**
75*61046927SAndroid Build Coastguard Worker * Structure that contains a callback for debug messages from the driver back
76*61046927SAndroid Build Coastguard Worker * to the gallium frontend.
77*61046927SAndroid Build Coastguard Worker */
78*61046927SAndroid Build Coastguard Worker struct util_debug_callback
79*61046927SAndroid Build Coastguard Worker {
80*61046927SAndroid Build Coastguard Worker /**
81*61046927SAndroid Build Coastguard Worker * When set to \c true, the callback may be called asynchronously from a
82*61046927SAndroid Build Coastguard Worker * driver-created thread.
83*61046927SAndroid Build Coastguard Worker */
84*61046927SAndroid Build Coastguard Worker bool async;
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker /**
87*61046927SAndroid Build Coastguard Worker * Callback for the driver to report debug/performance/etc information back
88*61046927SAndroid Build Coastguard Worker * to the gallium frontend.
89*61046927SAndroid Build Coastguard Worker *
90*61046927SAndroid Build Coastguard Worker * \param data user-supplied data pointer
91*61046927SAndroid Build Coastguard Worker * \param id message type identifier, if pointed value is 0, then a
92*61046927SAndroid Build Coastguard Worker * new id is assigned
93*61046927SAndroid Build Coastguard Worker * \param type UTIL_DEBUG_TYPE_*
94*61046927SAndroid Build Coastguard Worker * \param format printf-style format string
95*61046927SAndroid Build Coastguard Worker * \param args args for format string
96*61046927SAndroid Build Coastguard Worker */
97*61046927SAndroid Build Coastguard Worker void (*debug_message)(void *data,
98*61046927SAndroid Build Coastguard Worker unsigned *id,
99*61046927SAndroid Build Coastguard Worker enum util_debug_type type,
100*61046927SAndroid Build Coastguard Worker const char *fmt,
101*61046927SAndroid Build Coastguard Worker va_list args);
102*61046927SAndroid Build Coastguard Worker void *data;
103*61046927SAndroid Build Coastguard Worker };
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker #define _util_printf_format(fmt, list) PRINTFLIKE(fmt, list)
106*61046927SAndroid Build Coastguard Worker
107*61046927SAndroid Build Coastguard Worker void _debug_vprintf(const char *format, va_list ap);
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker static inline void
_debug_printf(const char * format,...)111*61046927SAndroid Build Coastguard Worker _debug_printf(const char *format, ...)
112*61046927SAndroid Build Coastguard Worker {
113*61046927SAndroid Build Coastguard Worker va_list ap;
114*61046927SAndroid Build Coastguard Worker va_start(ap, format);
115*61046927SAndroid Build Coastguard Worker _debug_vprintf(format, ap);
116*61046927SAndroid Build Coastguard Worker va_end(ap);
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker /**
121*61046927SAndroid Build Coastguard Worker * Print debug messages.
122*61046927SAndroid Build Coastguard Worker *
123*61046927SAndroid Build Coastguard Worker * The actual channel used to output debug message is platform specific. To
124*61046927SAndroid Build Coastguard Worker * avoid misformating or truncation, follow these rules of thumb:
125*61046927SAndroid Build Coastguard Worker * - output whole lines
126*61046927SAndroid Build Coastguard Worker * - avoid outputing large strings (512 bytes is the current maximum length
127*61046927SAndroid Build Coastguard Worker * that is guaranteed to be printed in all platforms)
128*61046927SAndroid Build Coastguard Worker */
129*61046927SAndroid Build Coastguard Worker #if !DETECT_OS_HAIKU
130*61046927SAndroid Build Coastguard Worker static inline void
131*61046927SAndroid Build Coastguard Worker debug_printf(const char *format, ...) _util_printf_format(1,2);
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker static inline void
debug_printf(const char * format,...)134*61046927SAndroid Build Coastguard Worker debug_printf(const char *format, ...)
135*61046927SAndroid Build Coastguard Worker {
136*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
137*61046927SAndroid Build Coastguard Worker va_list ap;
138*61046927SAndroid Build Coastguard Worker va_start(ap, format);
139*61046927SAndroid Build Coastguard Worker _debug_vprintf(format, ap);
140*61046927SAndroid Build Coastguard Worker va_end(ap);
141*61046927SAndroid Build Coastguard Worker #else
142*61046927SAndroid Build Coastguard Worker (void) format; /* silence warning */
143*61046927SAndroid Build Coastguard Worker #endif
144*61046927SAndroid Build Coastguard Worker }
145*61046927SAndroid Build Coastguard Worker #endif
146*61046927SAndroid Build Coastguard Worker
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker /*
149*61046927SAndroid Build Coastguard Worker * ... isn't portable so we need to pass arguments in parentheses.
150*61046927SAndroid Build Coastguard Worker *
151*61046927SAndroid Build Coastguard Worker * usage:
152*61046927SAndroid Build Coastguard Worker * debug_printf_once(("answer: %i\n", 42));
153*61046927SAndroid Build Coastguard Worker */
154*61046927SAndroid Build Coastguard Worker #define debug_printf_once(args) \
155*61046927SAndroid Build Coastguard Worker do { \
156*61046927SAndroid Build Coastguard Worker static bool once = true; \
157*61046927SAndroid Build Coastguard Worker if (once) { \
158*61046927SAndroid Build Coastguard Worker once = false; \
159*61046927SAndroid Build Coastguard Worker debug_printf args; \
160*61046927SAndroid Build Coastguard Worker } \
161*61046927SAndroid Build Coastguard Worker } while (0)
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker
164*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
165*61046927SAndroid Build Coastguard Worker #define debug_vprintf(_format, _ap) _debug_vprintf(_format, _ap)
166*61046927SAndroid Build Coastguard Worker #else
167*61046927SAndroid Build Coastguard Worker #define debug_vprintf(_format, _ap) ((void)0)
168*61046927SAndroid Build Coastguard Worker #endif
169*61046927SAndroid Build Coastguard Worker
170*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
171*61046927SAndroid Build Coastguard Worker /**
172*61046927SAndroid Build Coastguard Worker * Disable Win32 interactive error message boxes.
173*61046927SAndroid Build Coastguard Worker *
174*61046927SAndroid Build Coastguard Worker * Should be called as soon as possible for effectiveness.
175*61046927SAndroid Build Coastguard Worker */
176*61046927SAndroid Build Coastguard Worker void
177*61046927SAndroid Build Coastguard Worker debug_disable_win32_error_dialogs(void);
178*61046927SAndroid Build Coastguard Worker #endif
179*61046927SAndroid Build Coastguard Worker
180*61046927SAndroid Build Coastguard Worker
181*61046927SAndroid Build Coastguard Worker /**
182*61046927SAndroid Build Coastguard Worker * Hard-coded breakpoint.
183*61046927SAndroid Build Coastguard Worker */
184*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
185*61046927SAndroid Build Coastguard Worker #define debug_break() os_break()
186*61046927SAndroid Build Coastguard Worker #else /* !MESA_DEBUG */
187*61046927SAndroid Build Coastguard Worker #define debug_break() ((void)0)
188*61046927SAndroid Build Coastguard Worker #endif /* MESA_DEBUG */
189*61046927SAndroid Build Coastguard Worker
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker void
192*61046927SAndroid Build Coastguard Worker debug_get_version_option(const char *name, unsigned *major, unsigned *minor);
193*61046927SAndroid Build Coastguard Worker
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker /**
196*61046927SAndroid Build Coastguard Worker * Output the current function name.
197*61046927SAndroid Build Coastguard Worker */
198*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
199*61046927SAndroid Build Coastguard Worker #define debug_checkpoint() \
200*61046927SAndroid Build Coastguard Worker _debug_printf("%s\n", __func__)
201*61046927SAndroid Build Coastguard Worker #else
202*61046927SAndroid Build Coastguard Worker #define debug_checkpoint() \
203*61046927SAndroid Build Coastguard Worker ((void)0)
204*61046927SAndroid Build Coastguard Worker #endif
205*61046927SAndroid Build Coastguard Worker
206*61046927SAndroid Build Coastguard Worker
207*61046927SAndroid Build Coastguard Worker /**
208*61046927SAndroid Build Coastguard Worker * Output the full source code position.
209*61046927SAndroid Build Coastguard Worker */
210*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
211*61046927SAndroid Build Coastguard Worker #define debug_checkpoint_full() \
212*61046927SAndroid Build Coastguard Worker _debug_printf("%s:%u:%s\n", __FILE__, __LINE__, __func__)
213*61046927SAndroid Build Coastguard Worker #else
214*61046927SAndroid Build Coastguard Worker #define debug_checkpoint_full() \
215*61046927SAndroid Build Coastguard Worker ((void)0)
216*61046927SAndroid Build Coastguard Worker #endif
217*61046927SAndroid Build Coastguard Worker
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker /**
220*61046927SAndroid Build Coastguard Worker * Output a warning message. Muted on release version.
221*61046927SAndroid Build Coastguard Worker */
222*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
223*61046927SAndroid Build Coastguard Worker #define debug_warning(__msg) \
224*61046927SAndroid Build Coastguard Worker _debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __func__, __msg)
225*61046927SAndroid Build Coastguard Worker #else
226*61046927SAndroid Build Coastguard Worker #define debug_warning(__msg) \
227*61046927SAndroid Build Coastguard Worker ((void)0)
228*61046927SAndroid Build Coastguard Worker #endif
229*61046927SAndroid Build Coastguard Worker
230*61046927SAndroid Build Coastguard Worker
231*61046927SAndroid Build Coastguard Worker /**
232*61046927SAndroid Build Coastguard Worker * Emit a warning message, but only once.
233*61046927SAndroid Build Coastguard Worker */
234*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
235*61046927SAndroid Build Coastguard Worker #define debug_warn_once(__msg) \
236*61046927SAndroid Build Coastguard Worker do { \
237*61046927SAndroid Build Coastguard Worker static bool warned = false; \
238*61046927SAndroid Build Coastguard Worker if (!warned) { \
239*61046927SAndroid Build Coastguard Worker _debug_printf("%s:%u:%s: one time warning: %s\n", \
240*61046927SAndroid Build Coastguard Worker __FILE__, __LINE__, __func__, __msg); \
241*61046927SAndroid Build Coastguard Worker warned = true; \
242*61046927SAndroid Build Coastguard Worker } \
243*61046927SAndroid Build Coastguard Worker } while (0)
244*61046927SAndroid Build Coastguard Worker #else
245*61046927SAndroid Build Coastguard Worker #define debug_warn_once(__msg) \
246*61046927SAndroid Build Coastguard Worker ((void)0)
247*61046927SAndroid Build Coastguard Worker #endif
248*61046927SAndroid Build Coastguard Worker
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker /**
251*61046927SAndroid Build Coastguard Worker * Output an error message. Not muted on release version.
252*61046927SAndroid Build Coastguard Worker */
253*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
254*61046927SAndroid Build Coastguard Worker #define debug_error(__msg) \
255*61046927SAndroid Build Coastguard Worker _debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __func__, __msg)
256*61046927SAndroid Build Coastguard Worker #else
257*61046927SAndroid Build Coastguard Worker #define debug_error(__msg) \
258*61046927SAndroid Build Coastguard Worker _debug_printf("error: %s\n", __msg)
259*61046927SAndroid Build Coastguard Worker #endif
260*61046927SAndroid Build Coastguard Worker
261*61046927SAndroid Build Coastguard Worker /**
262*61046927SAndroid Build Coastguard Worker * Output a debug log message to the debug info callback.
263*61046927SAndroid Build Coastguard Worker */
264*61046927SAndroid Build Coastguard Worker #define util_debug_message(cb, type, fmt, ...) do { \
265*61046927SAndroid Build Coastguard Worker static unsigned id = 0; \
266*61046927SAndroid Build Coastguard Worker _util_debug_message(cb, &id, \
267*61046927SAndroid Build Coastguard Worker UTIL_DEBUG_TYPE_ ## type, \
268*61046927SAndroid Build Coastguard Worker fmt, ##__VA_ARGS__); \
269*61046927SAndroid Build Coastguard Worker } while (0)
270*61046927SAndroid Build Coastguard Worker
271*61046927SAndroid Build Coastguard Worker void
272*61046927SAndroid Build Coastguard Worker _util_debug_message(
273*61046927SAndroid Build Coastguard Worker struct util_debug_callback *cb,
274*61046927SAndroid Build Coastguard Worker unsigned *id,
275*61046927SAndroid Build Coastguard Worker enum util_debug_type type,
276*61046927SAndroid Build Coastguard Worker const char *fmt, ...) _util_printf_format(4, 5);
277*61046927SAndroid Build Coastguard Worker
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker /**
280*61046927SAndroid Build Coastguard Worker * Used by debug_dump_enum and debug_dump_flags to describe symbols.
281*61046927SAndroid Build Coastguard Worker */
282*61046927SAndroid Build Coastguard Worker struct debug_named_value
283*61046927SAndroid Build Coastguard Worker {
284*61046927SAndroid Build Coastguard Worker const char *name;
285*61046927SAndroid Build Coastguard Worker uint64_t value;
286*61046927SAndroid Build Coastguard Worker const char *desc;
287*61046927SAndroid Build Coastguard Worker };
288*61046927SAndroid Build Coastguard Worker
289*61046927SAndroid Build Coastguard Worker
290*61046927SAndroid Build Coastguard Worker /**
291*61046927SAndroid Build Coastguard Worker * Some C pre-processor magic to simplify creating named values.
292*61046927SAndroid Build Coastguard Worker *
293*61046927SAndroid Build Coastguard Worker * Example:
294*61046927SAndroid Build Coastguard Worker * @code
295*61046927SAndroid Build Coastguard Worker * static const debug_named_value my_names[] = {
296*61046927SAndroid Build Coastguard Worker * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X),
297*61046927SAndroid Build Coastguard Worker * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y),
298*61046927SAndroid Build Coastguard Worker * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z),
299*61046927SAndroid Build Coastguard Worker * DEBUG_NAMED_VALUE_END
300*61046927SAndroid Build Coastguard Worker * };
301*61046927SAndroid Build Coastguard Worker *
302*61046927SAndroid Build Coastguard Worker * ...
303*61046927SAndroid Build Coastguard Worker * debug_printf("%s = %s\n",
304*61046927SAndroid Build Coastguard Worker * name,
305*61046927SAndroid Build Coastguard Worker * debug_dump_enum(my_names, my_value));
306*61046927SAndroid Build Coastguard Worker * ...
307*61046927SAndroid Build Coastguard Worker * @endcode
308*61046927SAndroid Build Coastguard Worker */
309*61046927SAndroid Build Coastguard Worker #define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (uint64_t)__symbol, NULL}
310*61046927SAndroid Build Coastguard Worker #define DEBUG_NAMED_VALUE_WITH_DESCRIPTION(__symbol, __desc) {#__symbol, (uint64_t)__symbol, __desc}
311*61046927SAndroid Build Coastguard Worker #define DEBUG_NAMED_VALUE_END {NULL, 0, NULL}
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker
314*61046927SAndroid Build Coastguard Worker /**
315*61046927SAndroid Build Coastguard Worker * Convert a enum value to a string.
316*61046927SAndroid Build Coastguard Worker */
317*61046927SAndroid Build Coastguard Worker const char *
318*61046927SAndroid Build Coastguard Worker debug_dump_enum(const struct debug_named_value *names,
319*61046927SAndroid Build Coastguard Worker uint64_t value);
320*61046927SAndroid Build Coastguard Worker
321*61046927SAndroid Build Coastguard Worker /**
322*61046927SAndroid Build Coastguard Worker * Convert binary flags value to a string.
323*61046927SAndroid Build Coastguard Worker */
324*61046927SAndroid Build Coastguard Worker const char *
325*61046927SAndroid Build Coastguard Worker debug_dump_flags(const struct debug_named_value *names,
326*61046927SAndroid Build Coastguard Worker uint64_t value);
327*61046927SAndroid Build Coastguard Worker
328*61046927SAndroid Build Coastguard Worker
329*61046927SAndroid Build Coastguard Worker struct debug_control {
330*61046927SAndroid Build Coastguard Worker const char * string;
331*61046927SAndroid Build Coastguard Worker uint64_t flag;
332*61046927SAndroid Build Coastguard Worker };
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker uint64_t
335*61046927SAndroid Build Coastguard Worker parse_debug_string(const char *debug,
336*61046927SAndroid Build Coastguard Worker const struct debug_control *control);
337*61046927SAndroid Build Coastguard Worker
338*61046927SAndroid Build Coastguard Worker
339*61046927SAndroid Build Coastguard Worker uint64_t
340*61046927SAndroid Build Coastguard Worker parse_enable_string(const char *debug,
341*61046927SAndroid Build Coastguard Worker uint64_t default_value,
342*61046927SAndroid Build Coastguard Worker const struct debug_control *control);
343*61046927SAndroid Build Coastguard Worker
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker bool
346*61046927SAndroid Build Coastguard Worker comma_separated_list_contains(const char *list, const char *s);
347*61046927SAndroid Build Coastguard Worker
348*61046927SAndroid Build Coastguard Worker /**
349*61046927SAndroid Build Coastguard Worker * Get option.
350*61046927SAndroid Build Coastguard Worker *
351*61046927SAndroid Build Coastguard Worker * It is an alias for getenv on Unix and Windows.
352*61046927SAndroid Build Coastguard Worker *
353*61046927SAndroid Build Coastguard Worker */
354*61046927SAndroid Build Coastguard Worker const char *
355*61046927SAndroid Build Coastguard Worker debug_get_option(const char *name, const char *dfault);
356*61046927SAndroid Build Coastguard Worker
357*61046927SAndroid Build Coastguard Worker const char *
358*61046927SAndroid Build Coastguard Worker debug_get_option_cached(const char *name, const char *dfault);
359*61046927SAndroid Build Coastguard Worker
360*61046927SAndroid Build Coastguard Worker bool
361*61046927SAndroid Build Coastguard Worker debug_parse_bool_option(const char *str, bool dfault);
362*61046927SAndroid Build Coastguard Worker
363*61046927SAndroid Build Coastguard Worker bool
364*61046927SAndroid Build Coastguard Worker debug_get_bool_option(const char *name, bool dfault);
365*61046927SAndroid Build Coastguard Worker
366*61046927SAndroid Build Coastguard Worker int64_t
367*61046927SAndroid Build Coastguard Worker debug_parse_num_option(const char *str, int64_t dfault);
368*61046927SAndroid Build Coastguard Worker
369*61046927SAndroid Build Coastguard Worker int64_t
370*61046927SAndroid Build Coastguard Worker debug_get_num_option(const char *name, int64_t dfault);
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker uint64_t
373*61046927SAndroid Build Coastguard Worker debug_parse_flags_option(const char *name,
374*61046927SAndroid Build Coastguard Worker const char *str,
375*61046927SAndroid Build Coastguard Worker const struct debug_named_value *flags,
376*61046927SAndroid Build Coastguard Worker uint64_t dfault);
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker uint64_t
379*61046927SAndroid Build Coastguard Worker debug_get_flags_option(const char *name,
380*61046927SAndroid Build Coastguard Worker const struct debug_named_value *flags,
381*61046927SAndroid Build Coastguard Worker uint64_t dfault);
382*61046927SAndroid Build Coastguard Worker
383*61046927SAndroid Build Coastguard Worker #define DEBUG_GET_ONCE_OPTION(suffix, name, dfault) \
384*61046927SAndroid Build Coastguard Worker static const char * \
385*61046927SAndroid Build Coastguard Worker debug_get_option_ ## suffix (void) \
386*61046927SAndroid Build Coastguard Worker { \
387*61046927SAndroid Build Coastguard Worker static bool initialized = false; \
388*61046927SAndroid Build Coastguard Worker static const char * value; \
389*61046927SAndroid Build Coastguard Worker if (unlikely(!p_atomic_read_relaxed(&initialized))) { \
390*61046927SAndroid Build Coastguard Worker const char *str = debug_get_option_cached(name, dfault); \
391*61046927SAndroid Build Coastguard Worker p_atomic_set(&value, str); \
392*61046927SAndroid Build Coastguard Worker p_atomic_set(&initialized, true); \
393*61046927SAndroid Build Coastguard Worker } \
394*61046927SAndroid Build Coastguard Worker return value; \
395*61046927SAndroid Build Coastguard Worker }
396*61046927SAndroid Build Coastguard Worker
397*61046927SAndroid Build Coastguard Worker static inline bool
__normal_user(void)398*61046927SAndroid Build Coastguard Worker __normal_user(void)
399*61046927SAndroid Build Coastguard Worker {
400*61046927SAndroid Build Coastguard Worker #if defined(_WIN32)
401*61046927SAndroid Build Coastguard Worker return true;
402*61046927SAndroid Build Coastguard Worker #else
403*61046927SAndroid Build Coastguard Worker return geteuid() == getuid() && getegid() == getgid();
404*61046927SAndroid Build Coastguard Worker #endif
405*61046927SAndroid Build Coastguard Worker }
406*61046927SAndroid Build Coastguard Worker
407*61046927SAndroid Build Coastguard Worker #ifndef HAVE_SECURE_GETENV
secure_getenv(const char * name)408*61046927SAndroid Build Coastguard Worker static inline char *secure_getenv(const char *name)
409*61046927SAndroid Build Coastguard Worker {
410*61046927SAndroid Build Coastguard Worker return getenv(name);
411*61046927SAndroid Build Coastguard Worker }
412*61046927SAndroid Build Coastguard Worker #endif
413*61046927SAndroid Build Coastguard Worker
414*61046927SAndroid Build Coastguard Worker #define DEBUG_GET_ONCE_BOOL_OPTION(sufix, name, dfault) \
415*61046927SAndroid Build Coastguard Worker static bool \
416*61046927SAndroid Build Coastguard Worker debug_get_option_ ## sufix (void) \
417*61046927SAndroid Build Coastguard Worker { \
418*61046927SAndroid Build Coastguard Worker static bool initialized = false; \
419*61046927SAndroid Build Coastguard Worker static bool value; \
420*61046927SAndroid Build Coastguard Worker if (unlikely(!p_atomic_read_relaxed(&initialized))) { \
421*61046927SAndroid Build Coastguard Worker const char *str = debug_get_option_cached(name, NULL); \
422*61046927SAndroid Build Coastguard Worker bool parsed_value = debug_parse_bool_option(str, dfault); \
423*61046927SAndroid Build Coastguard Worker p_atomic_set(&value, parsed_value); \
424*61046927SAndroid Build Coastguard Worker p_atomic_set(&initialized, true); \
425*61046927SAndroid Build Coastguard Worker } \
426*61046927SAndroid Build Coastguard Worker return value; \
427*61046927SAndroid Build Coastguard Worker }
428*61046927SAndroid Build Coastguard Worker
429*61046927SAndroid Build Coastguard Worker #define DEBUG_GET_ONCE_NUM_OPTION(sufix, name, dfault) \
430*61046927SAndroid Build Coastguard Worker static int64_t \
431*61046927SAndroid Build Coastguard Worker debug_get_option_ ## sufix (void) \
432*61046927SAndroid Build Coastguard Worker { \
433*61046927SAndroid Build Coastguard Worker static bool initialized = false; \
434*61046927SAndroid Build Coastguard Worker static int64_t value; \
435*61046927SAndroid Build Coastguard Worker if (unlikely(!p_atomic_read_relaxed(&initialized))) { \
436*61046927SAndroid Build Coastguard Worker const char *str = debug_get_option_cached(name, NULL); \
437*61046927SAndroid Build Coastguard Worker int64_t parsed_value = debug_parse_num_option(str, dfault); \
438*61046927SAndroid Build Coastguard Worker p_atomic_set(&value, parsed_value); \
439*61046927SAndroid Build Coastguard Worker p_atomic_set(&initialized, true); \
440*61046927SAndroid Build Coastguard Worker } \
441*61046927SAndroid Build Coastguard Worker return value; \
442*61046927SAndroid Build Coastguard Worker }
443*61046927SAndroid Build Coastguard Worker
444*61046927SAndroid Build Coastguard Worker #define DEBUG_GET_ONCE_FLAGS_OPTION(sufix, name, flags, dfault) \
445*61046927SAndroid Build Coastguard Worker static uint64_t \
446*61046927SAndroid Build Coastguard Worker debug_get_option_ ## sufix (void) \
447*61046927SAndroid Build Coastguard Worker { \
448*61046927SAndroid Build Coastguard Worker static bool initialized = false; \
449*61046927SAndroid Build Coastguard Worker static uint64_t value; \
450*61046927SAndroid Build Coastguard Worker if (unlikely(!p_atomic_read_relaxed(&initialized))) { \
451*61046927SAndroid Build Coastguard Worker const char *str = debug_get_option_cached(name, NULL); \
452*61046927SAndroid Build Coastguard Worker uint64_t parsed_value = debug_parse_flags_option(name, str, flags, dfault); \
453*61046927SAndroid Build Coastguard Worker p_atomic_set(&value, parsed_value); \
454*61046927SAndroid Build Coastguard Worker p_atomic_set(&initialized, true); \
455*61046927SAndroid Build Coastguard Worker } \
456*61046927SAndroid Build Coastguard Worker return value; \
457*61046927SAndroid Build Coastguard Worker }
458*61046927SAndroid Build Coastguard Worker
459*61046927SAndroid Build Coastguard Worker
460*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus
461*61046927SAndroid Build Coastguard Worker }
462*61046927SAndroid Build Coastguard Worker #endif
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker #endif /* U_DEBUG_H_ */
465