globus_common 18.14
Loading...
Searching...
No Matches
globus_debug.h
Go to the documentation of this file.
1/*
2 * Copyright 1999-2006 University of Chicago
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
22#ifndef GLOBUS_DEBUG_H
23#define GLOBUS_DEBUG_H
24
26#include "globus_time.h"
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#ifdef BUILD_DEBUG
33
34typedef struct
35{
36 unsigned levels;
37 unsigned timestamp_levels;
38 FILE * file;
39 globus_bool_t thread_ids;
40 globus_bool_t using_file;
41} globus_debug_handle_t;
42
43void
44globus_debug_init(
45 const char * env_name,
46 const char * level_names,
47 globus_debug_handle_t * handle);
48
49#define GlobusDebugThreadId() globus_thread_self()
50
51/* call in same file as module_activate func (before (de)activate funcs) */
52#define GlobusDebugDefine(module_name) \
53 extern globus_debug_handle_t globus_i_##module_name##_debug_handle; \
54 void globus_i_##module_name##_debug_printf(const char * fmt, ...) \
55 { \
56 va_list ap; \
57 \
58 if(!globus_i_##module_name##_debug_handle.file) \
59 return; \
60 \
61 va_start(ap, fmt); \
62 if(globus_i_##module_name##_debug_handle.thread_ids) \
63 { \
64 char buf[4096]; /* XXX better not use a fmt bigger than this */ \
65 sprintf( \
66 buf, "%lu::%s", (unsigned long) globus_thread_self().dummy, fmt);\
67 vfprintf(globus_i_##module_name##_debug_handle.file, buf, ap); \
68 } \
69 else \
70 { \
71 vfprintf(globus_i_##module_name##_debug_handle.file, fmt, ap); \
72 } \
73 va_end(ap); \
74 } \
75 void globus_i_##module_name##_debug_time_printf(const char * fmt, ...) \
76 { \
77 va_list ap; \
78 char buf[4096]; /* XXX better not use a fmt bigger than this */ \
79 globus_abstime_t current_time; \
80 \
81 if(!globus_i_##module_name##_debug_handle.file) \
82 return; \
83 \
84 GlobusTimeAbstimeGetCurrent(current_time); \
85 va_start(ap, fmt); \
86 if(globus_i_##module_name##_debug_handle.thread_ids) \
87 { \
88 globus_thread_t __self = GlobusDebugThreadId(); \
89 sprintf(buf, "%lu:%lu.%.9lu::%s", \
90 (unsigned long) __self.dummy, \
91 (unsigned long) current_time.tv_sec, \
92 (unsigned long) current_time.tv_nsec, \
93 fmt); \
94 vfprintf(globus_i_##module_name##_debug_handle.file, buf, ap); \
95 } \
96 else \
97 { \
98 sprintf(buf, "%lu.%.9lu::%s", \
99 (unsigned long) current_time.tv_sec, \
100 (unsigned long) current_time.tv_nsec, \
101 fmt); \
102 vfprintf(globus_i_##module_name##_debug_handle.file, buf, ap); \
103 } \
104 va_end(ap); \
105 } \
106 void globus_i_##module_name##_debug_fwrite( \
107 const void *ptr, size_t size, size_t nmemb) \
108 { \
109 if(globus_i_##module_name##_debug_handle.file) \
110 fwrite(ptr, size, nmemb, \
111 globus_i_##module_name##_debug_handle.file); \
112 } \
113 globus_debug_handle_t globus_i_##module_name##_debug_handle
114
115/* call this in a header file (if needed externally) */
116#define GlobusDebugDeclare(module_name) \
117 extern void globus_i_##module_name##_debug_printf(const char *, ...); \
118 extern void globus_i_##module_name##_debug_time_printf(const char *, ...);\
119 extern void globus_i_##module_name##_debug_fwrite( \
120 const void *ptr, size_t size, size_t nmemb); \
121 extern globus_debug_handle_t globus_i_##module_name##_debug_handle
122
123/* call this in module activate func
124 *
125 * 'levels' is a space separated list of level names that can be used in env
126 * they will map to a 2^i value (so, list them in same order as value)
127 *
128 * will look in env for {module_name}_DEBUG whose value is:
129 * <levels> [, [ [ # ] <file name>] [, <flags> [, <timestamp_levels>] ] ]
130 * where <levels> can be a single numeric or '|' separated level names
131 * <file name> is a debug output file... can be empty. stderr by default
132 * if a '#' precedes the filename, the file will be overwritten on each run
133 * otherwise, the default is to append to the existing (if one exists)
134 * <flags> 0 default (or any of the following to enable:
135 * 1 show thread ids
136 * 2 append pid to debug filename
137 * <timestamp_levels> similar to <levels>. specifies which levels to print
138 * timestamps with. default is none.
139 * Also, users can use the ALL level in their env setting to turn on
140 * all levels or precede the list of levels with '^' to enable all levels
141 * except those.
142 */
143#define GlobusDebugInit(module_name, levels) \
144 globus_debug_init( \
145 #module_name "_DEBUG", \
146 #levels, \
147 &globus_i_##module_name##_debug_handle)
148
149/* call this in module deactivate func */
150#define GlobusDebugDestroy(module_name) \
151 do \
152 { \
153 if(globus_i_##module_name##_debug_handle.using_file) \
154 { \
155 fclose(globus_i_##module_name##_debug_handle.file); \
156 } \
157 globus_i_##module_name##_debug_handle.file = GLOBUS_NULL; \
158 } while(0)
159
160/* use this to print a message unconditionally (message must be enclosed in
161 * parenthesis and contains a format and possibly var args
162 */
163#define GlobusDebugMyPrintf(module_name, message) \
164 globus_i_##module_name##_debug_printf message
165#define GlobusDebugMyTimePrintf(module_name, message) \
166 globus_i_##module_name##_debug_time_printf message
167
168#define GlobusDebugMyFwrite(module_name, buffer, size, count) \
169 globus_i_##module_name##_debug_fwrite((buffer), (size), (count))
170
171#define GlobusDebugMyFile(module_name) \
172 (globus_i_##module_name##_debug_handle.file)
173
174/* use this in an if() to debug enable blocks of code
175 * for example
176 *
177 * if(GlobusDebugTrue(MY_MODULE, VERIFICATION))
178 * {
179 * compute stats
180 * GlobusDebugMyPrintf(MY_MODULE, "Stats = %d\n", stats);
181 * }
182 */
183#define GlobusDebugTrue(module_name, level) \
184 (globus_i_##module_name##_debug_handle.levels & (level))
185
186#define GlobusDebugTimeTrue(module_name, level) \
187 (globus_i_##module_name##_debug_handle.timestamp_levels & (level))
188
189/* most likely wrap this with your own macro,
190 * so you don't need to pass module_name all the time
191 * 'message' needs to be wrapped with parens and contains a format and
192 * possibly var args
193 */
194#define GlobusDebugPrintf(module_name, level, message) \
195 do \
196 { \
197 if(GlobusDebugTrue(module_name, level)) \
198 { \
199 if(!GlobusDebugTimeTrue(module_name, level)) \
200 { \
201 GlobusDebugMyPrintf(module_name, message); \
202 } \
203 else \
204 { \
205 GlobusDebugMyTimePrintf(module_name, message); \
206 } \
207 } \
208 } while(0)
209
210#define GlobusDebugFwrite(module_name, level, buffer, size, count) \
211 do \
212 { \
213 if(GlobusDebugTrue(module_name, level)) \
214 { \
215 GlobusDebugMyFwrite(module_name, buffer, size, count); \
216 } \
217 } while(0)
218
219#else
220
221#define GlobusDebugThreadId() 0
222#define GlobusDebugDeclare(module_name)
223#define GlobusDebugDefine(module_name)
224#define GlobusDebugInit(module_name, levels) do {} while(0)
225#define GlobusDebugDestroy(module_name) do {} while(0)
226#define GlobusDebugPrintf(module_name, level, message) do {} while(0)
227#define GlobusDebugFwrite(module_name, level, buffer, size, count) \
228 do {} while(0)
229#define GlobusDebugMyPrintf(module_name, message) do {} while(0)
230#define GlobusDebugMyTimePrintf(module_name, message) do {} while(0)
231#define GlobusDebugMyFwrite(module_name, buffer, size, count) do {} while(0)
232#define GlobusDebugMyFile(module_name) (stderr)
233#define GlobusDebugTrue(module_name, level) 0
234#define GlobusDebugTimeTrue(module_name, level) 0
235
236#endif
237
238#ifdef __cplusplus
239}
240#endif
241
242#endif /* GLOBUS_DEBUG_H */
Include System Headers.
Time Types and Macros.
int globus_bool_t
Boolean type.
Definition globus_types.h:93