1 /**************************************************************************
3 * Copyright 2008 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
30 * Cross-platform debugging helpers.
32 * For now it just has assert and printf replacements, but it might be extended
33 * with stack trace reports and more advanced logging in the near future.
35 * @author Jose Fonseca <jfonseca@vmware.com>
42 #include "util/os_misc.h"
44 #if defined(PIPE_OS_HAIKU)
45 /* Haiku provides debug_printf in libroot with OS.h */
49 #include "pipe/p_defines.h"
58 #define _util_printf_format(fmt, list) __attribute__ ((format (printf, fmt, list)))
60 #define _util_printf_format(fmt, list)
63 void _debug_vprintf(const char *format
, va_list ap
);
67 _debug_printf(const char *format
, ...)
71 _debug_vprintf(format
, ap
);
77 * Print debug messages.
79 * The actual channel used to output debug message is platform specific. To
80 * avoid misformating or truncation, follow these rules of thumb:
81 * - output whole lines
82 * - avoid outputing large strings (512 bytes is the current maximum length
83 * that is guaranteed to be printed in all platforms)
85 #if !defined(PIPE_OS_HAIKU)
87 debug_printf(const char *format
, ...) _util_printf_format(1,2);
90 debug_printf(const char *format
, ...)
95 _debug_vprintf(format
, ap
);
98 (void) format
; /* silence warning */
105 * ... isn't portable so we need to pass arguments in parentheses.
108 * debug_printf_once(("answer: %i\n", 42));
110 #define debug_printf_once(args) \
112 static boolean once = TRUE; \
121 #define debug_vprintf(_format, _ap) _debug_vprintf(_format, _ap)
123 #define debug_vprintf(_format, _ap) ((void)0)
129 * Dump a blob in hex to the same place that debug_printf sends its
132 void debug_print_blob( const char *name
, const void *blob
, unsigned size
);
134 #define debug_print_blob(_name, _blob, _size) ((void)0)
139 * Disable interactive error message boxes.
141 * Should be called as soon as possible for effectiveness.
144 debug_disable_error_message_boxes(void);
148 * Hard-coded breakpoint.
151 #define debug_break() os_break()
153 #define debug_break() ((void)0)
158 debug_get_num_option(const char *name
, long dfault
);
163 void _debug_assert_fail(const char *expr
,
166 const char *function
)
167 #if defined(__GNUC__) && !defined(DEBUG)
168 __attribute__((noreturn
))
176 * Do not expect that the assert call terminates -- errors must be handled
177 * regardless of assert behavior.
179 * For non debug builds the assert macro will expand to a no-op, so do not
180 * call functions with side effects in the assert expression.
183 #define debug_assert(expr) ((expr) ? (void)0 : _debug_assert_fail(#expr, __FILE__, __LINE__, __FUNCTION__))
185 #define debug_assert(expr) (void)(0 && (expr))
189 /** Override standard assert macro */
193 #define assert(expr) debug_assert(expr)
197 * Output the current function name.
200 #define debug_checkpoint() \
201 _debug_printf("%s\n", __FUNCTION__)
203 #define debug_checkpoint() \
209 * Output the full source code position.
212 #define debug_checkpoint_full() \
213 _debug_printf("%s:%u:%s\n", __FILE__, __LINE__, __FUNCTION__)
215 #define debug_checkpoint_full() \
221 * Output a warning message. Muted on release version.
224 #define debug_warning(__msg) \
225 _debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg)
227 #define debug_warning(__msg) \
233 * Emit a warning message, but only once.
236 #define debug_warn_once(__msg) \
238 static bool warned = FALSE; \
240 _debug_printf("%s:%u:%s: one time warning: %s\n", \
241 __FILE__, __LINE__, __FUNCTION__, __msg); \
246 #define debug_warn_once(__msg) \
252 * Output an error message. Not muted on release version.
255 #define debug_error(__msg) \
256 _debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg)
258 #define debug_error(__msg) \
259 _debug_printf("error: %s\n", __msg)
263 * Output a debug log message to the debug info callback.
265 #define pipe_debug_message(cb, type, fmt, ...) do { \
266 static unsigned id = 0; \
267 if ((cb) && (cb)->debug_message) { \
268 _pipe_debug_message(cb, &id, \
269 PIPE_DEBUG_TYPE_ ## type, \
270 fmt, ##__VA_ARGS__); \
274 struct pipe_debug_callback
;
278 struct pipe_debug_callback
*cb
,
280 enum pipe_debug_type type
,
281 const char *fmt
, ...) _util_printf_format(4, 5);
285 * Used by debug_dump_enum and debug_dump_flags to describe symbols.
287 struct debug_named_value
296 * Some C pre-processor magic to simplify creating named values.
300 * static const debug_named_value my_names[] = {
301 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X),
302 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y),
303 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z),
304 * DEBUG_NAMED_VALUE_END
308 * debug_printf("%s = %s\n",
310 * debug_dump_enum(my_names, my_value));
314 #define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol, NULL}
315 #define DEBUG_NAMED_VALUE_WITH_DESCRIPTION(__symbol, __desc) {#__symbol, (unsigned long)__symbol, __desc}
316 #define DEBUG_NAMED_VALUE_END {NULL, 0, NULL}
320 * Convert a enum value to a string.
323 debug_dump_enum(const struct debug_named_value
*names
,
324 unsigned long value
);
327 debug_dump_enum_noprefix(const struct debug_named_value
*names
,
329 unsigned long value
);
333 * Convert binary flags value to a string.
336 debug_dump_flags(const struct debug_named_value
*names
,
337 unsigned long value
);
341 * Function enter exit loggers
344 int debug_funclog_enter(const char* f
, const int line
, const char* file
);
345 void debug_funclog_exit(const char* f
, const int line
, const char* file
);
346 void debug_funclog_enter_exit(const char* f
, const int line
, const char* file
);
348 #define DEBUG_FUNCLOG_ENTER() \
349 int __debug_decleration_work_around = \
350 debug_funclog_enter(__FUNCTION__, __LINE__, __FILE__)
351 #define DEBUG_FUNCLOG_EXIT() \
353 (void)__debug_decleration_work_around; \
354 debug_funclog_exit(__FUNCTION__, __LINE__, __FILE__); \
357 #define DEBUG_FUNCLOG_EXIT_RET(ret) \
359 (void)__debug_decleration_work_around; \
360 debug_funclog_exit(__FUNCTION__, __LINE__, __FILE__); \
363 #define DEBUG_FUNCLOG_ENTER_EXIT() \
364 debug_funclog_enter_exit(__FUNCTION__, __LINE__, __FILE__)
367 #define DEBUG_FUNCLOG_ENTER() \
368 int __debug_decleration_work_around
369 #define DEBUG_FUNCLOG_EXIT() \
370 do { (void)__debug_decleration_work_around; return; } while(0)
371 #define DEBUG_FUNCLOG_EXIT_RET(ret) \
372 do { (void)__debug_decleration_work_around; return ret; } while(0)
373 #define DEBUG_FUNCLOG_ENTER_EXIT()
380 * It is an alias for getenv on Linux.
382 * On Windows it reads C:\gallium.cfg, which is a text file with CR+LF line
383 * endings with one option per line as
387 * This file must be terminated with an extra empty line.
390 debug_get_option(const char *name
, const char *dfault
);
393 debug_get_bool_option(const char *name
, boolean dfault
);
396 debug_get_num_option(const char *name
, long dfault
);
399 debug_get_flags_option(const char *name
,
400 const struct debug_named_value
*flags
,
403 #define DEBUG_GET_ONCE_OPTION(suffix, name, dfault) \
404 static const char * \
405 debug_get_option_ ## suffix (void) \
407 static boolean first = TRUE; \
408 static const char * value; \
411 value = debug_get_option(name, dfault); \
416 #define DEBUG_GET_ONCE_BOOL_OPTION(sufix, name, dfault) \
418 debug_get_option_ ## sufix (void) \
420 static boolean first = TRUE; \
421 static boolean value; \
424 value = debug_get_bool_option(name, dfault); \
429 #define DEBUG_GET_ONCE_NUM_OPTION(sufix, name, dfault) \
431 debug_get_option_ ## sufix (void) \
433 static boolean first = TRUE; \
437 value = debug_get_num_option(name, dfault); \
442 #define DEBUG_GET_ONCE_FLAGS_OPTION(sufix, name, flags, dfault) \
443 static unsigned long \
444 debug_get_option_ ## sufix (void) \
446 static boolean first = TRUE; \
447 static unsigned long value; \
450 value = debug_get_flags_option(name, flags, dfault); \
460 #endif /* U_DEBUG_H_ */