u_debug.h revision a88202d3b02a24a3bfff95c5e375ead44dae4c5e
1/************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 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: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 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 TUNGSTEN GRAPHICS 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. 25 * 26 **************************************************************************/ 27 28/** 29 * @file 30 * Cross-platform debugging helpers. 31 * 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. 34 * 35 * @author Jose Fonseca <jrfonseca@tungstengraphics.com> 36 */ 37 38#ifndef P_DEBUG_H_ 39#define P_DEBUG_H_ 40 41 42#include <stdarg.h> 43 44#include "p_compiler.h" 45 46 47#ifdef __cplusplus 48extern "C" { 49#endif 50 51 52#ifdef DBG 53#ifndef DEBUG 54#define DEBUG 1 55#endif 56#else 57#ifndef NDEBUG 58#define NDEBUG 1 59#endif 60#endif 61 62 63/** 64 * Print debug messages. 65 * 66 * A debug message will be printed regardless of the DEBUG/NDEBUG macros. 67 * 68 * The actual channel used to output debug message is platform specific. To 69 * avoid misformating or truncation, follow these rules of thumb: 70 * - output whole lines 71 * - avoid outputing large strings (512 bytes is the current maximum length 72 * that is guaranteed to be printed in all platforms) 73 */ 74void debug_printf(const char *format, ...); 75 76 77/* Dump a blob in hex to the same place that debug_printf sends its 78 * messages: 79 */ 80void debug_print_blob( const char *name, 81 const void *blob, 82 unsigned size ); 83 84/** 85 * @sa debug_printf 86 */ 87void debug_vprintf(const char *format, va_list ap); 88 89void debug_assert_fail(const char *expr, const char *file, unsigned line); 90 91 92/** Assert macro */ 93#ifdef DEBUG 94#define debug_assert(expr) ((expr) ? (void)0 : debug_assert_fail(#expr, __FILE__, __LINE__)) 95#else 96#define debug_assert(expr) ((void)0) 97#endif 98 99 100#ifdef assert 101#undef assert 102#endif 103#define assert(expr) debug_assert(expr) 104 105 106/** 107 * Set a channel's debug mask. 108 * 109 * uuid is just a random 32 bit integer that uniquely identifies the debugging 110 * channel. 111 * 112 * @note Due to current implementation issues, make sure the lower 8 bits of 113 * UUID are unique. 114 */ 115void debug_mask_set(uint32_t uuid, uint32_t mask); 116 117 118uint32_t debug_mask_get(uint32_t uuid); 119 120 121/** 122 * Conditional debug output. 123 * 124 * This is just a generalization of the debug filtering mechanism used 125 * throughout Gallium. 126 * 127 * You use this function as: 128 * 129 * @code 130 * #define MYDRIVER_UUID 0x12345678 // random 32 bit identifier 131 * 132 * static void inline 133 * mydriver_debug(uint32_t what, const char *format, ...) 134 * { 135 * #ifdef DEBUG 136 * va_list ap; 137 * va_start(ap, format); 138 * debug_mask_vprintf(MYDRIVER_UUID, what, format, ap); 139 * va_end(ap); 140 * #endif 141 * } 142 * 143 * ... 144 * 145 * debug_mask_set(MYDRIVER_UUID, 146 * MYDRIVER_DEBUG_THIS | 147 * MYDRIVER_DEBUG_THAT | 148 * ... ); 149 * 150 * ... 151 * 152 * mydriver_debug(MYDRIVER_DEBUG_THIS, 153 * "this and this happened\n"); 154 * 155 * mydriver_debug(MYDRIVER_DEBUG_THAT, 156 * "that = %f\n", that); 157 * ... 158 * @endcode 159 * 160 * You can also define several variants of mydriver_debug, with hardcoded what. 161 * Note that although macros with variable number of arguments would accomplish 162 * more in less code, they are not portable. 163 */ 164void debug_mask_vprintf(uint32_t uuid, 165 uint32_t what, 166 const char *format, 167 va_list ap); 168 169 170#ifdef DEBUG 171#define debug_warning(__msg) \ 172 debug_printf("%s:%i:warning: %s\n", __FILE__, __LINE__, (__msg)) 173#else 174#define debug_warning(__msg) \ 175 ((void)0) 176#endif 177 178 179/** 180 * Used by debug_dump_enum and debug_dump_flags to describe symbols. 181 */ 182struct debug_named_value 183{ 184 const char *name; 185 unsigned long value; 186}; 187 188 189/** 190 * Some C pre-processor magic to simplify creating named values. 191 * 192 * Example: 193 * @code 194 * static const debug_named_value my_names[] = { 195 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X), 196 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y), 197 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z), 198 * DEBUG_NAMED_VALUE_END 199 * }; 200 * 201 * ... 202 * debug_printf("%s = %s\n", 203 * name, 204 * debug_dump_enum(my_names, my_value)); 205 * ... 206 * @endcode 207 */ 208#define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol} 209#define DEBUG_NAMED_VALUE_END {NULL, 0} 210 211 212/** 213 * Convert a enum value to a string. 214 */ 215const char * 216debug_dump_enum(const struct debug_named_value *names, 217 unsigned long value); 218 219 220/** 221 * Convert binary flags value to a string. 222 */ 223const char * 224debug_dump_flags(const struct debug_named_value *names, 225 unsigned long value); 226 227 228#ifdef __cplusplus 229} 230#endif 231 232#endif /* P_DEBUG_H_ */ 233