462dc772532a1df3a9468e147a25ae72a34acd71
[platform/upstream/gstreamer.git] / gst / gstdebug.h
1 /* Gnome-Streamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20
21 #ifndef __GSTDEBUG_H__
22 #define __GSTDEBUG_H__
23
24 #include <stdio.h>
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29
30 #include <gmodule.h>
31 #include <unistd.h>
32
33 #include <gst/gsttrace.h>
34
35 /* for include files that make too much noise normally */
36 #ifdef GST_DEBUG_FORCE_DISABLE
37 #undef GST_DEBUG_ENABLED
38 #endif
39
40 /* for applications that really really want all the noise */
41 #ifdef GST_DEBUG_FORCE_ENABLE
42 #define GST_DEBUG_ENABLED
43 #endif
44
45
46 #define GST_DEBUG_PREFIX(format,args...) \
47 "DEBUG(%d:%d)" __PRETTY_FUNCTION__ ":%d" format , getpid() , cothread_getcurrent() , __LINE__ , ## args
48
49
50 /* fallback, this should probably be a 'weak' symbol or something */
51 G_GNUC_UNUSED static gchar *_debug_string = NULL;
52
53
54 /**********************************************************************
55  * The following is a DEBUG_ENTER implementation that will wrap the
56  * function it sits at the head of.  It removes the need for a
57  * DEBUG_LEAVE call.  However, it segfaults whenever it gets anywhere
58  * near cothreads.  We will not use it for the moment.
59  */
60 typedef void (*_debug_function_f)();
61 G_GNUC_UNUSED static gchar *_debug_string_pointer = NULL;
62 G_GNUC_UNUSED static GModule *_debug_self_module = NULL;
63
64 #define _DEBUG_ENTER_BUILTIN(format,args...)                                            \
65   static int _debug_in_wrapper = 0;                                                     \
66   gchar *_debug_string = ({                                                             \
67     if (!_debug_in_wrapper) {                                                           \
68       void *_return_value;                                                              \
69       gchar *_debug_string;                                                             \
70       _debug_function_f function;                                                       \
71       void *_function_args = __builtin_apply_args();                                    \
72       _debug_in_wrapper = 1;                                                            \
73       _debug_string = g_strdup_printf(GST_DEBUG_PREFIX(""));                            \
74       _debug_string_pointer = _debug_string;                                            \
75       fprintf(stderr,"%s: entered " __PRETTY_FUNCTION__ format "\n" , _debug_string , ## args ); \
76       if (_debug_self_module == NULL) _debug_self_module = g_module_open(NULL,0);       \
77       g_module_symbol(_debug_self_module,__FUNCTION__,(gpointer *)&function);           \
78       _return_value = __builtin_apply(function,_function_args,64);                      \
79       fprintf(stderr,"%s: left " __PRETTY_FUNCTION__ format "\n" , _debug_string , ## args ); \
80       g_free(_debug_string);                                                            \
81       __builtin_return(_return_value);                                                  \
82     } else {                                                                            \
83       _debug_in_wrapper = 0;                                                            \
84     }                                                                                   \
85     _debug_string_pointer;                                                              \
86   });
87
88 /* WARNING: there's a gcc CPP bug lurking in here.  The extra space before the ##args   *
89  * somehow make the preprocessor leave the _debug_string. If it's removed, the          *
90  * _debug_string somehow gets stripped along with the ##args, and that's all she wrote. */
91 #define _DEBUG_BUILTIN(format,args...)                          \
92   if (_debug_string != (void *)-1) {                            \
93     if (_debug_string)                                          \
94       fprintf(stderr,"%s: " format , _debug_string , ## args);  \
95     else                                                        \
96       fprintf(stderr,GST_DEBUG_PREFIX(": " format , ## args));  \
97   }
98
99 #ifdef GST_DEBUG_ENABLED
100 #define DEBUG(format,args...) \
101   (_debug_string != NULL) ? \
102     fprintf(stderr,GST_DEBUG_PREFIX("%s: "format , _debug_string , ## args )) : \
103     fprintf(stderr,GST_DEBUG_PREFIX(": "format , ## args ))
104 #define DEBUG_ENTER(format, args...) \
105   fprintf(stderr,GST_DEBUG_PREFIX(format": entering\n" , ## args ))
106 #define DEBUG_SET_STRING(format, args...) \
107   gchar *_debug_string = g_strdup_printf(format , ## args )
108 #define DEBUG_ENTER_STRING DEBUG_ENTER("%s",_debug_string)
109 #define DEBUG_LEAVE(format, args...) \
110   if (_debug_string != NULL) g_free(_debug_string),\
111     fprintf(stderr,GST_DEBUG_PREFIX(format": leaving\n" , ## args ))
112 #define DEBUG_LEAVE_STRING DEBUG_LEAVE("%s",_debug_string)
113 #else
114 #define DEBUG(format, args...)
115 #define DEBUG_ENTER(format, args...)
116 #define DEBUG_LEAVE(format, args...)
117 #define DEBUG_SET_STRING(format, args...)
118 #define DEBUG_ENTER_STRING
119 #endif
120
121
122
123 /********** some convenience macros for debugging **********/
124 #define GST_DEBUG_PAD_NAME(pad) \
125   ((pad)->parent != NULL) ? gst_element_get_name(GST_ELEMENT((pad)->parent)) : "''", gst_pad_get_name(pad)
126
127
128
129 /********** function pointer stuff **********/
130 extern GHashTable *__gst_function_pointers;
131
132 #ifdef GST_DEBUG_ENABLED
133 #define GST_DEBUG_FUNCPTR(ptr) _gst_debug_register_funcptr((void *)(ptr), #ptr)
134 #define GST_DEBUG_FUNCPTR_NAME(ptr) _gst_debug_nameof_funcptr((void *)ptr)
135 #else
136 #define GST_DEBUG_FUNCPTR(ptr) (ptr)
137 #define GST_DEBUG_FUNCPTR_NAME(ptr) ""
138 #endif
139
140 static inline void *
141 _gst_debug_register_funcptr (void *ptr, gchar *ptrname) 
142 {
143   if (!__gst_function_pointers) __gst_function_pointers = g_hash_table_new(g_direct_hash,g_direct_equal);
144   if (!g_hash_table_lookup(__gst_function_pointers,ptr))
145     g_hash_table_insert(__gst_function_pointers,ptr,ptrname);
146   return ptr;
147 }
148
149 static inline gchar *
150 _gst_debug_nameof_funcptr (void *ptr) 
151 {
152   gchar *ptrname = __gst_function_pointers ? g_hash_table_lookup(__gst_function_pointers,ptr) : NULL;
153 // FIXME this must go away, it's a major leak
154   if (!ptrname) return g_strdup_printf("%p",ptr);
155   else return ptrname;
156 }
157
158 #endif /* __GST_H__ */