2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstinfo.c: INFO, ERROR, and DEBUG systems
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 #include "gst_private.h"
25 #include "gstelement.h"
28 extern gchar *_gst_progname;
31 /***** Categories and colorization *****/
32 static gchar *_gst_info_category_strings[] = {
63 * gst_get_category_name:
64 * @category: the category to return the name of
66 * Returns: string containing the name of the category
69 gst_get_category_name (gint category) {
70 if ((category >= 0) && (category < GST_CAT_MAX_CATEGORY))
71 return _gst_info_category_strings[category];
79 * 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
81 * 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
82 * Background color codes:
83 * 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
85 const gchar *_gst_category_colors[32] = {
86 [GST_CAT_GST_INIT] = "07;37",
87 [GST_CAT_COTHREADS] = "00;32",
88 [GST_CAT_COTHREAD_SWITCH] = "00;37;42",
89 [GST_CAT_AUTOPLUG] = "00;34",
90 [GST_CAT_AUTOPLUG_ATTEMPT] = "00;36;44",
91 [GST_CAT_PARENTAGE] = "01;37;41", // !!
92 [GST_CAT_STATES] = "00;31",
93 [GST_CAT_PLANNING] = "07;35",
94 [GST_CAT_SCHEDULING] = "00;35",
95 [GST_CAT_DATAFLOW] = "00;32",
96 [GST_CAT_BUFFER] = "00;32",
97 [GST_CAT_CAPS] = "04;34",
98 [GST_CAT_CLOCK] = "00;33", // !!
99 [GST_CAT_ELEMENT_PADS] = "01;37;41", // !!
100 [GST_CAT_ELEMENTFACTORY] = "01;37;41", // !!
101 [GST_CAT_PADS] = "01;37;41", // !!
102 [GST_CAT_PIPELINE] = "01;37;41", // !!
103 [GST_CAT_PLUGIN_LOADING] = "00;36",
104 [GST_CAT_PLUGIN_ERRORS] = "05;31",
105 [GST_CAT_PLUGIN_INFO] = "00;36",
106 [GST_CAT_PROPERTIES] = "00;37;44", // !!
107 [GST_CAT_THREAD] = "00;31",
108 [GST_CAT_TYPES] = "01;37;41", // !!
109 [GST_CAT_XML] = "01;37;41", // !!
110 [GST_CAT_NEGOTIATION] = "07;34",
111 [GST_CAT_REFCOUNTING] = "00;34:42",
112 [GST_CAT_EVENT] = "01;37;41", // !!
117 /* colorization hash - DEPRACATED in favor of above */
118 inline gint _gst_debug_stringhash_color(gchar *file) {
120 while (file[0]) filecolor += *(char *)(file++);
121 filecolor = (filecolor % 6) + 31;
127 /***** DEBUG system *****/
128 GstDebugHandler _gst_debug_handler = gst_default_debug_handler;
129 guint32 _gst_debug_categories = 0x00000000;
132 * gst_default_debug_handler:
133 * @category: category of the DEBUG message
134 * @incore: if the debug handler is for core code.
135 * @file: the file the DEBUG occurs in
136 * @function: the function the DEBUG occurs in
137 * @line: the line number in the file
138 * @debug_string: the current debug_string in the function, if any
139 * @element: pointer to the #GstElement in question
140 * @string: the actual DEBUG string
142 * Prints out the DEBUG mesage in a variant of the following form:
144 * DEBUG(pid:cid):gst_function:542(args): [elementname] something neat happened
147 gst_default_debug_handler (gint category, gboolean incore,
148 const gchar *file, const gchar *function,
149 gint line, const gchar *debug_string,
150 void *element, gchar *string)
153 gchar *elementname = empty,*location = empty;
154 int pthread_id = getpid();
155 int cothread_id = cothread_getcurrent();
156 #ifdef GST_DEBUG_COLOR
157 int pthread_color = pthread_id%6 + 31;
158 int cothread_color = (cothread_id < 0) ? 37 : (cothread_id%6 + 31);
161 if (debug_string == NULL) debug_string = "";
162 // if (category != GST_CAT_GST_INIT)
163 location = g_strdup_printf("%s:%d%s:",function,line,debug_string);
164 if (element && GST_IS_ELEMENT (element))
165 #ifdef GST_DEBUG_COLOR
166 elementname = g_strdup_printf (" \033[04m[%s]\033[00m", GST_OBJECT_NAME (element));
168 elementname = g_strdup_printf (" [%s]", GST_OBJECT_NAME (element));
171 #ifdef GST_DEBUG_COLOR
172 fprintf(stderr,"DEBUG(\033[00;%dm%5d\033[00m:\033[00;%dm%2d\033[00m)\033["
173 "%s;%sm%s%s\033[00m %s",
174 pthread_color,pthread_id,cothread_color,cothread_id,incore?"00":"01",
175 _gst_category_colors[category],location,elementname,string);
177 fprintf(stderr,"DEBUG(%5d:%2d)%s%s %s",
178 pthread_id,cothread_id,location,elementname,string);
179 #endif /* GST_DEBUG_COLOR */
181 if (location != empty) g_free(location);
182 if (elementname != empty) g_free(elementname);
189 * gst_debug_set_categories:
190 * @categories: bitmask of DEBUG categories to enable
192 * Enable the output of DEBUG categories based on the given bitmask.
193 * The bit for any given category is (1 << GST_CAT_...).
196 gst_debug_set_categories (guint32 categories) {
197 _gst_debug_categories = categories;
199 GST_INFO (0, "setting DEBUG categories to 0x%08X",categories);
203 * gst_debug_get_categories:
205 * Returns: the current bitmask of enabled DEBUG categories
206 * The bit for any given category is (1 << GST_CAT_...).
209 gst_debug_get_categories () {
210 return _gst_debug_categories;
214 * gst_debug_enable_category:
215 * @category: the category to enable
217 * Enables the given GST_CAT_... DEBUG category.
220 gst_debug_enable_category (gint category) {
221 _gst_debug_categories |= (1 << category);
222 if (_gst_debug_categories)
223 GST_INFO (0, "setting DEBUG categories to 0x%08X",_gst_debug_categories);
227 * gst_debug_disable_category:
228 * @category: the category to disable
230 * Disables the given GST_CAT_... DEBUG category.
233 gst_debug_disable_category (gint category) {
234 _gst_debug_categories &= ~ (1 << category);
235 if (_gst_debug_categories)
236 GST_INFO (0, "setting DEBUG categories to 0x%08X",_gst_debug_categories);
242 /***** INFO system *****/
243 GstInfoHandler _gst_info_handler = gst_default_info_handler;
244 guint32 _gst_info_categories = 0x00000001;
248 * gst_default_info_handler:
249 * @category: category of the INFO message
250 * @incore: if the info handler is for core code.
251 * @file: the file the INFO occurs in
252 * @function: the function the INFO occurs in
253 * @line: the line number in the file
254 * @debug_string: the current debug_string in the function, if any
255 * @element: pointer to the #GstElement in question
256 * @string: the actual INFO string
258 * Prints out the INFO mesage in a variant of the following form:
260 * INFO:gst_function:542(args): [elementname] something neat happened
263 gst_default_info_handler (gint category, gboolean incore,
264 const gchar *file, const gchar *function,
265 gint line, const gchar *debug_string,
266 void *element, gchar *string)
269 gchar *elementname = empty,*location = empty;
270 int pthread_id = getpid();
271 int cothread_id = cothread_getcurrent();
272 #ifdef GST_DEBUG_COLOR
273 int pthread_color = pthread_id%6 + 31;
274 int cothread_color = (cothread_id < 0) ? 37 : (cothread_id%6 + 31);
277 if (debug_string == NULL) debug_string = "";
278 if (category != GST_CAT_GST_INIT)
279 location = g_strdup_printf("%s:%d%s:",function,line,debug_string);
280 if (element && GST_IS_ELEMENT (element))
281 elementname = g_strdup_printf (" \033[04m[%s]\033[00m", GST_OBJECT_NAME (element));
284 #ifdef GST_DEBUG_ENABLED
286 #ifdef GST_DEBUG_COLOR
287 fprintf(stderr,"\033[01mINFO\033[00m (\033[00;%dm%5d\033[00m:\033[00;%dm%2d\033[00m)\033["
288 GST_DEBUG_CHAR_MODE ";%sm%s%s\033[00m %s\n",
289 pthread_color,pthread_id,cothread_color,cothread_id,
290 _gst_category_colors[category],location,elementname,string);
292 fprintf(stderr,"INFO (%5d:%2d)%s%s %s\n",
293 pthread_id,cothread_id,location,elementname,string);
294 #endif // GST_DEBUG_COLOR
297 #ifdef GST_DEBUG_COLOR
298 fprintf(stderr,"\033[01mINFO\033[00m:\033[" GST_DEBUG_CHAR_MODE ";%sm%s%s\033[00m %s\n",
299 location,elementname,_gst_category_colors[category],string);
301 fprintf(stderr,"INFO:%s%s %s\n",
302 location,elementname,string);
303 #endif // GST_DEBUG_COLOR
307 if (location != empty) g_free(location);
308 if (elementname != empty) g_free(elementname);
314 * gst_info_set_categories:
315 * @categories: bitmask of INFO categories to enable
317 * Enable the output of INFO categories based on the given bitmask.
318 * The bit for any given category is (1 << GST_CAT_...).
321 gst_info_set_categories (guint32 categories) {
322 _gst_info_categories = categories;
324 GST_INFO (0, "setting INFO categories to 0x%08X",categories);
328 * gst_info_get_categories:
330 * Returns: the current bitmask of enabled INFO categories
331 * The bit for any given category is (1 << GST_CAT_...).
334 gst_info_get_categories () {
335 return _gst_info_categories;
339 * gst_info_enable_category:
340 * @category: the category to enable
342 * Enables the given GST_CAT_... INFO category.
345 gst_info_enable_category (gint category) {
346 _gst_info_categories |= (1 << category);
347 if (_gst_info_categories)
348 GST_INFO (0, "setting INFO categories to 0x%08X",_gst_info_categories);
352 * gst_info_disable_category:
353 * @category: the category to disable
355 * Disables the given GST_CAT_... INFO category.
358 gst_info_disable_category (gint category) {
359 _gst_info_categories &= ~ (1 << category);
360 if (_gst_info_categories)
361 GST_INFO (0, "setting INFO categories to 0x%08X",_gst_info_categories);
366 /***** ERROR system *****/
367 GstErrorHandler _gst_error_handler = gst_default_error_handler;
370 * gst_default_error_handler:
371 * @file: the file the ERROR occurs in
372 * @function: the function the INFO occurs in
373 * @line: the line number in the file
374 * @debug_string: the current debug_string in the function, if any
375 * @element: pointer to the #GstElement in question
376 * @object: pointer to a related object
377 * @string: the actual ERROR string
379 * Prints out the given ERROR string in a variant of the following format:
381 * ***** GStreamer ERROR ***** in file gstsomething.c at gst_function:399(arg)
382 * Element: /pipeline/thread/element.src
383 * Error: peer is null!
384 * ***** attempting to stack trace.... *****
386 * At the end, it attempts to print the stack trace via GDB.
389 gst_default_error_handler (gchar *file, gchar *function,
390 gint line, gchar *debug_string,
391 void *element, void *object, gchar *string)
397 // if there are NULL pointers, point them to null strings to clean up output
398 if (!debug_string) debug_string = "";
399 if (!string) string = "";
401 // print out a preamble
402 fprintf(stderr,"***** GStreamer ERROR ***** in file %s at %s:%d%s\n",
403 file,function,line,debug_string);
405 // if there's an element, print out the pertinent information
407 if (GST_IS_OBJECT(element)) {
408 path = gst_object_get_path_string(element);
409 fprintf(stderr,"Element: %s",path);
410 chars = 9 + strlen(path);
413 fprintf(stderr,"Element ptr: %p",element);
414 chars = 15 + sizeof(void*)*2;
418 // if there's an object, print it out as well
420 // attempt to pad the line, or create a new one
422 for (i=0;i<(40-chars)/8+1;i++) fprintf(stderr,"\t");
424 fprintf(stderr,"\n");
426 if (GST_IS_OBJECT(object)) {
427 path = gst_object_get_path_string(object);
428 fprintf(stderr,"Object: %s",path);
431 fprintf(stderr,"Object ptr: %p",object);
435 fprintf(stderr,"\n");
436 fprintf(stderr,"Error: %s\n",string);
440 fprintf(stderr,"***** attempting to stack trace.... *****\n");
442 g_on_error_stack_trace (_gst_progname);
449 /***** DEBUG system *****/
450 GHashTable *__gst_function_pointers = NULL;
453 _gst_debug_nameof_funcptr (void *ptr)
457 if (__gst_function_pointers) {
458 if ((ptrname = g_hash_table_lookup(__gst_function_pointers,ptr)))
459 return g_strdup(ptrname);
460 } else if (dladdr(ptr,&dlinfo) && dlinfo.dli_sname) {
461 return g_strdup(dlinfo.dli_sname);
463 return g_strdup_printf("%p",ptr);