3 * Mesa debugging and error handling functions.
7 * Mesa 3-D graphics library
9 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
37 #include "debug_output.h"
42 #include "util/hash_table.h"
43 #include "util/simple_list.h"
46 static FILE *LogFile
= NULL
;
50 output_if_debug(const char *prefixString
, const char *outputString
,
53 static int debug
= -1;
55 /* Init the local 'debug' var once.
56 * Note: the _mesa_init_debug() function should have been called
57 * by now so MESA_DEBUG_FLAGS will be initialized.
60 /* If MESA_LOG_FILE env var is set, log Mesa errors, warnings,
61 * etc to the named file. Otherwise, output to stderr.
63 const char *logFile
= getenv("MESA_LOG_FILE");
65 LogFile
= fopen(logFile
, "w");
69 /* in debug builds, print messages unless MESA_DEBUG="silent" */
70 if (MESA_DEBUG_FLAGS
& DEBUG_SILENT
)
75 /* in release builds, be silent unless MESA_DEBUG is set */
76 debug
= getenv("MESA_DEBUG") != NULL
;
80 /* Now only print the string if we're required to do so. */
83 fprintf(LogFile
, "%s: %s", prefixString
, outputString
);
85 fprintf(LogFile
, "%s", outputString
);
87 fprintf(LogFile
, "\n");
91 /* stderr from windows applications without console is not usually
92 * visible, so communicate with the debugger instead */
95 _mesa_snprintf(buf
, sizeof(buf
), "%s: %s%s", prefixString
, outputString
, newline
? "\n" : "");
96 OutputDebugStringA(buf
);
104 * Return the file handle to use for debug/logging. Defaults to stderr
105 * unless MESA_LOG_FILE is defined.
108 _mesa_get_log_file(void)
116 * When a new type of error is recorded, print a message describing
117 * previous errors which were accumulated.
120 flush_delayed_errors( struct gl_context
*ctx
)
122 char s
[MAX_DEBUG_MESSAGE_LENGTH
];
124 if (ctx
->ErrorDebugCount
) {
125 _mesa_snprintf(s
, MAX_DEBUG_MESSAGE_LENGTH
, "%d similar %s errors",
126 ctx
->ErrorDebugCount
,
127 _mesa_enum_to_string(ctx
->ErrorValue
));
129 output_if_debug("Mesa", s
, GL_TRUE
);
131 ctx
->ErrorDebugCount
= 0;
137 * Report a warning (a recoverable error condition) to stderr if
138 * either DEBUG is defined or the MESA_DEBUG env var is set.
140 * \param ctx GL context.
141 * \param fmtString printf()-like format string.
144 _mesa_warning( struct gl_context
*ctx
, const char *fmtString
, ... )
146 char str
[MAX_DEBUG_MESSAGE_LENGTH
];
148 va_start( args
, fmtString
);
149 (void) _mesa_vsnprintf( str
, MAX_DEBUG_MESSAGE_LENGTH
, fmtString
, args
);
153 flush_delayed_errors( ctx
);
155 output_if_debug("Mesa warning", str
, GL_TRUE
);
160 * Report an internal implementation problem.
161 * Prints the message to stderr via fprintf().
163 * \param ctx GL context.
164 * \param fmtString problem description string.
167 _mesa_problem( const struct gl_context
*ctx
, const char *fmtString
, ... )
170 char str
[MAX_DEBUG_MESSAGE_LENGTH
];
171 static int numCalls
= 0;
178 va_start( args
, fmtString
);
179 _mesa_vsnprintf( str
, MAX_DEBUG_MESSAGE_LENGTH
, fmtString
, args
);
181 fprintf(stderr
, "Mesa %s implementation error: %s\n",
182 PACKAGE_VERSION
, str
);
183 fprintf(stderr
, "Please report at " PACKAGE_BUGREPORT
"\n");
189 should_output(struct gl_context
*ctx
, GLenum error
, const char *fmtString
)
191 static GLint debug
= -1;
193 /* Check debug environment variable only once:
196 const char *debugEnv
= getenv("MESA_DEBUG");
199 if (debugEnv
&& strstr(debugEnv
, "silent"))
212 if (ctx
->ErrorValue
!= error
||
213 ctx
->ErrorDebugFmtString
!= fmtString
) {
214 flush_delayed_errors( ctx
);
215 ctx
->ErrorDebugFmtString
= fmtString
;
216 ctx
->ErrorDebugCount
= 0;
219 ctx
->ErrorDebugCount
++;
226 _mesa_gl_vdebug(struct gl_context
*ctx
,
228 enum mesa_debug_source source
,
229 enum mesa_debug_type type
,
230 enum mesa_debug_severity severity
,
231 const char *fmtString
,
234 char s
[MAX_DEBUG_MESSAGE_LENGTH
];
237 _mesa_debug_get_id(id
);
239 len
= _mesa_vsnprintf(s
, MAX_DEBUG_MESSAGE_LENGTH
, fmtString
, args
);
241 _mesa_log_msg(ctx
, source
, type
, *id
, severity
, len
, s
);
246 _mesa_gl_debug(struct gl_context
*ctx
,
248 enum mesa_debug_source source
,
249 enum mesa_debug_type type
,
250 enum mesa_debug_severity severity
,
251 const char *fmtString
, ...)
254 va_start(args
, fmtString
);
255 _mesa_gl_vdebug(ctx
, id
, source
, type
, severity
, fmtString
, args
);
261 * Record an OpenGL state error. These usually occur when the user
262 * passes invalid parameters to a GL function.
264 * If debugging is enabled (either at compile-time via the DEBUG macro, or
265 * run-time via the MESA_DEBUG environment variable), report the error with
268 * \param ctx the GL context.
269 * \param error the error value.
270 * \param fmtString printf() style format string, followed by optional args
273 _mesa_error( struct gl_context
*ctx
, GLenum error
, const char *fmtString
, ... )
275 GLboolean do_output
, do_log
;
276 /* Ideally this would be set up by the caller, so that we had proper IDs
277 * per different message.
279 static GLuint error_msg_id
= 0;
281 _mesa_debug_get_id(&error_msg_id
);
283 do_output
= should_output(ctx
, error
, fmtString
);
285 mtx_lock(&ctx
->DebugMutex
);
287 do_log
= _mesa_debug_is_message_enabled(ctx
->Debug
,
288 MESA_DEBUG_SOURCE_API
,
289 MESA_DEBUG_TYPE_ERROR
,
291 MESA_DEBUG_SEVERITY_HIGH
);
296 mtx_unlock(&ctx
->DebugMutex
);
298 if (do_output
|| do_log
) {
299 char s
[MAX_DEBUG_MESSAGE_LENGTH
], s2
[MAX_DEBUG_MESSAGE_LENGTH
];
303 va_start(args
, fmtString
);
304 len
= _mesa_vsnprintf(s
, MAX_DEBUG_MESSAGE_LENGTH
, fmtString
, args
);
307 if (len
>= MAX_DEBUG_MESSAGE_LENGTH
) {
308 /* Too long error message. Whoever calls _mesa_error should use
315 len
= _mesa_snprintf(s2
, MAX_DEBUG_MESSAGE_LENGTH
, "%s in %s",
316 _mesa_enum_to_string(error
), s
);
317 if (len
>= MAX_DEBUG_MESSAGE_LENGTH
) {
323 /* Print the error to stderr if needed. */
325 output_if_debug("Mesa: User error", s2
, GL_TRUE
);
328 /* Log the error via ARB_debug_output if needed.*/
330 _mesa_log_msg(ctx
, MESA_DEBUG_SOURCE_API
, MESA_DEBUG_TYPE_ERROR
,
331 error_msg_id
, MESA_DEBUG_SEVERITY_HIGH
, len
, s2
);
335 /* Set the GL context error state for glGetError. */
336 _mesa_record_error(ctx
, error
);
340 _mesa_error_no_memory(const char *caller
)
342 GET_CURRENT_CONTEXT(ctx
);
343 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "out of memory in %s", caller
);
347 * Report debug information. Print error message to stderr via fprintf().
348 * No-op if DEBUG mode not enabled.
350 * \param ctx GL context.
351 * \param fmtString printf()-style format string, followed by optional args.
354 _mesa_debug( const struct gl_context
*ctx
, const char *fmtString
, ... )
357 char s
[MAX_DEBUG_MESSAGE_LENGTH
];
359 va_start(args
, fmtString
);
360 _mesa_vsnprintf(s
, MAX_DEBUG_MESSAGE_LENGTH
, fmtString
, args
);
362 output_if_debug("Mesa", s
, GL_FALSE
);
370 _mesa_log(const char *fmtString
, ...)
372 char s
[MAX_DEBUG_MESSAGE_LENGTH
];
374 va_start(args
, fmtString
);
375 _mesa_vsnprintf(s
, MAX_DEBUG_MESSAGE_LENGTH
, fmtString
, args
);
377 output_if_debug("", s
, GL_FALSE
);
382 * Report debug information from the shader compiler via GL_ARB_debug_output.
384 * \param ctx GL context.
385 * \param type The namespace to which this message belongs.
386 * \param id The message ID within the given namespace.
387 * \param msg The message to output. Must be null-terminated.
390 _mesa_shader_debug(struct gl_context
*ctx
, GLenum type
, GLuint
*id
,
393 enum mesa_debug_source source
= MESA_DEBUG_SOURCE_SHADER_COMPILER
;
394 enum mesa_debug_severity severity
= MESA_DEBUG_SEVERITY_HIGH
;
397 _mesa_debug_get_id(id
);
401 /* Truncate the message if necessary. */
402 if (len
>= MAX_DEBUG_MESSAGE_LENGTH
)
403 len
= MAX_DEBUG_MESSAGE_LENGTH
- 1;
405 _mesa_log_msg(ctx
, source
, type
, *id
, severity
, len
, msg
);