u_debug.h revision fcc2598fffe0f0e0412d2a30777f1b4a4ed22249
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 U_DEBUG_H_ 39#define U_DEBUG_H_ 40 41 42#include <stdarg.h> 43 44#include "pipe/p_compiler.h" 45 46 47#ifdef __cplusplus 48extern "C" { 49#endif 50 51 52#if defined(DBG) || defined(DEBUG) 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/* MSVC bebore VC7 does not have the __FUNCTION__ macro */ 64#if defined(_MSC_VER) && _MSC_VER < 1300 65#define __FUNCTION__ "???" 66#endif 67 68 69void _debug_vprintf(const char *format, va_list ap); 70 71 72static INLINE void 73_debug_printf(const char *format, ...) 74{ 75 va_list ap; 76 va_start(ap, format); 77 _debug_vprintf(format, ap); 78 va_end(ap); 79} 80 81 82/** 83 * Print debug messages. 84 * 85 * The actual channel used to output debug message is platform specific. To 86 * avoid misformating or truncation, follow these rules of thumb: 87 * - output whole lines 88 * - avoid outputing large strings (512 bytes is the current maximum length 89 * that is guaranteed to be printed in all platforms) 90 */ 91static INLINE void 92debug_printf(const char *format, ...) 93{ 94#ifdef DEBUG 95 va_list ap; 96 va_start(ap, format); 97 _debug_vprintf(format, ap); 98 va_end(ap); 99#else 100 (void) format; /* silence warning */ 101#endif 102} 103 104 105#ifdef DEBUG 106#define debug_vprintf(_format, _ap) _debug_vprintf(_format, _ap) 107#else 108#define debug_vprintf(_format, _ap) ((void)0) 109#endif 110 111 112#ifdef DEBUG 113/** 114 * Dump a blob in hex to the same place that debug_printf sends its 115 * messages. 116 */ 117void debug_print_blob( const char *name, const void *blob, unsigned size ); 118 119/* Print a message along with a prettified format string 120 */ 121void debug_print_format(const char *msg, unsigned fmt ); 122#else 123#define debug_print_blob(_name, _blob, _size) ((void)0) 124#define debug_print_format(_msg, _fmt) ((void)0) 125#endif 126 127 128/** 129 * Hard-coded breakpoint. 130 */ 131#ifdef DEBUG 132#if (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)) && defined(PIPE_CC_GCC) 133#define debug_break() __asm("int3") 134#elif defined(PIPE_CC_MSVC) 135#define debug_break() __debugbreak() 136#else 137void debug_break(void); 138#endif 139#else /* !DEBUG */ 140#define debug_break() ((void)0) 141#endif /* !DEBUG */ 142 143 144long 145debug_get_num_option(const char *name, long dfault); 146 147void _debug_assert_fail(const char *expr, 148 const char *file, 149 unsigned line, 150 const char *function); 151 152 153/** 154 * Assert macro 155 * 156 * Do not expect that the assert call terminates -- errors must be handled 157 * regardless of assert behavior. 158 */ 159#ifdef DEBUG 160#define debug_assert(expr) ((expr) ? (void)0 : _debug_assert_fail(#expr, __FILE__, __LINE__, __FUNCTION__)) 161#else 162#define debug_assert(expr) ((void)(expr)) 163#endif 164 165 166/** Override standard assert macro */ 167#ifdef assert 168#undef assert 169#endif 170#define assert(expr) debug_assert(expr) 171 172 173/** 174 * Output the current function name. 175 */ 176#ifdef DEBUG 177#define debug_checkpoint() \ 178 _debug_printf("%s\n", __FUNCTION__) 179#else 180#define debug_checkpoint() \ 181 ((void)0) 182#endif 183 184 185/** 186 * Output the full source code position. 187 */ 188#ifdef DEBUG 189#define debug_checkpoint_full() \ 190 _debug_printf("%s:%u:%s", __FILE__, __LINE__, __FUNCTION__) 191#else 192#define debug_checkpoint_full() \ 193 ((void)0) 194#endif 195 196 197/** 198 * Output a warning message. Muted on release version. 199 */ 200#ifdef DEBUG 201#define debug_warning(__msg) \ 202 _debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg) 203#else 204#define debug_warning(__msg) \ 205 ((void)0) 206#endif 207 208 209/** 210 * Output an error message. Not muted on release version. 211 */ 212#ifdef DEBUG 213#define debug_error(__msg) \ 214 _debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg) 215#else 216#define debug_error(__msg) \ 217 _debug_printf("error: %s\n", __msg) 218#endif 219 220 221/** 222 * Used by debug_dump_enum and debug_dump_flags to describe symbols. 223 */ 224struct debug_named_value 225{ 226 const char *name; 227 unsigned long value; 228}; 229 230 231/** 232 * Some C pre-processor magic to simplify creating named values. 233 * 234 * Example: 235 * @code 236 * static const debug_named_value my_names[] = { 237 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X), 238 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y), 239 * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z), 240 * DEBUG_NAMED_VALUE_END 241 * }; 242 * 243 * ... 244 * debug_printf("%s = %s\n", 245 * name, 246 * debug_dump_enum(my_names, my_value)); 247 * ... 248 * @endcode 249 */ 250#define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol} 251#define DEBUG_NAMED_VALUE_END {NULL, 0} 252 253 254/** 255 * Convert a enum value to a string. 256 */ 257const char * 258debug_dump_enum(const struct debug_named_value *names, 259 unsigned long value); 260 261const char * 262debug_dump_enum_noprefix(const struct debug_named_value *names, 263 const char *prefix, 264 unsigned long value); 265 266 267/** 268 * Convert binary flags value to a string. 269 */ 270const char * 271debug_dump_flags(const struct debug_named_value *names, 272 unsigned long value); 273 274 275/** 276 * Get option. 277 * 278 * It is an alias for getenv on Linux. 279 * 280 * On Windows it reads C:\gallium.cfg, which is a text file with CR+LF line 281 * endings with one option per line as 282 * 283 * NAME=value 284 * 285 * This file must be terminated with an extra empty line. 286 */ 287const char * 288debug_get_option(const char *name, const char *dfault); 289 290boolean 291debug_get_bool_option(const char *name, boolean dfault); 292 293long 294debug_get_num_option(const char *name, long dfault); 295 296unsigned long 297debug_get_flags_option(const char *name, 298 const struct debug_named_value *flags, 299 unsigned long dfault); 300 301 302void * 303debug_malloc(const char *file, unsigned line, const char *function, 304 size_t size); 305 306void 307debug_free(const char *file, unsigned line, const char *function, 308 void *ptr); 309 310void * 311debug_calloc(const char *file, unsigned line, const char *function, 312 size_t count, size_t size ); 313 314void * 315debug_realloc(const char *file, unsigned line, const char *function, 316 void *old_ptr, size_t old_size, size_t new_size ); 317 318unsigned long 319debug_memory_begin(void); 320 321void 322debug_memory_end(unsigned long beginning); 323 324 325#if defined(PROFILE) && defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) 326 327void 328debug_profile_start(void); 329 330void 331debug_profile_stop(void); 332 333#endif 334 335 336#ifdef DEBUG 337struct pipe_surface; 338struct pipe_transfer; 339void debug_dump_image(const char *prefix, 340 unsigned format, unsigned cpp, 341 unsigned width, unsigned height, 342 unsigned stride, 343 const void *data); 344void debug_dump_surface(const char *prefix, 345 struct pipe_surface *surface); 346void debug_dump_surface_bmp(const char *filename, 347 struct pipe_surface *surface); 348void debug_dump_transfer_bmp(const char *filename, 349 struct pipe_transfer *transfer); 350#else 351#define debug_dump_image(prefix, format, cpp, width, height, stride, data) ((void)0) 352#define debug_dump_surface(prefix, surface) ((void)0) 353#define debug_dump_surface_bmp(filename, surface) ((void)0) 354#endif 355 356 357#ifdef __cplusplus 358} 359#endif 360 361#endif /* U_DEBUG_H_ */ 362