globus_debug.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 1999-2006 University of Chicago
00003  * 
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  * 
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00022 #ifndef GLOBUS_DEBUG_H
00023 #define GLOBUS_DEBUG_H
00024 
00025 #include "globus_common_include.h"
00026 #include "globus_time.h"
00027 
00028 #ifdef __cplusplus
00029 extern "C" {
00030 #endif
00031 
00032 #ifdef BUILD_DEBUG
00033 
00034 typedef struct
00035 {
00036     unsigned                            levels;
00037     unsigned                            timestamp_levels;
00038     FILE *                              file;
00039     globus_bool_t                       thread_ids;
00040     globus_bool_t                       using_file;
00041 } globus_debug_handle_t;
00042 
00043 void
00044 globus_debug_init(
00045     const char *                        env_name,
00046     const char *                        level_names,
00047     globus_debug_handle_t *             handle);
00048 
00049 #define GlobusDebugThreadId() globus_thread_self()
00050 
00051 /* call in same file as module_activate func (before (de)activate funcs) */
00052 #define GlobusDebugDefine(module_name)                                      \
00053     extern globus_debug_handle_t globus_i_##module_name##_debug_handle;     \
00054     void globus_i_##module_name##_debug_printf(const char * fmt, ...)       \
00055     {                                                                       \
00056         va_list ap;                                                         \
00057                                                                             \
00058         if(!globus_i_##module_name##_debug_handle.file)                     \
00059             return;                                                         \
00060                                                                             \
00061         va_start(ap, fmt);                                                  \
00062         if(globus_i_##module_name##_debug_handle.thread_ids)                \
00063         {                                                                   \
00064             char buf[4096]; /* XXX better not use a fmt bigger than this */ \
00065             sprintf(                                                        \
00066                 buf, "%lu::%s", (unsigned long) globus_thread_self().dummy, fmt);\
00067             vfprintf(globus_i_##module_name##_debug_handle.file, buf, ap);  \
00068         }                                                                   \
00069         else                                                                \
00070         {                                                                   \
00071             vfprintf(globus_i_##module_name##_debug_handle.file, fmt, ap);  \
00072         }                                                                   \
00073         va_end(ap);                                                         \
00074     }                                                                       \
00075     void globus_i_##module_name##_debug_time_printf(const char * fmt, ...)  \
00076     {                                                                       \
00077         va_list ap;                                                         \
00078         char buf[4096]; /* XXX better not use a fmt bigger than this */     \
00079         globus_abstime_t current_time;                                      \
00080                                                                             \
00081         if(!globus_i_##module_name##_debug_handle.file)                     \
00082             return;                                                         \
00083                                                                             \
00084         GlobusTimeAbstimeGetCurrent(current_time);                          \
00085         va_start(ap, fmt);                                                  \
00086         if(globus_i_##module_name##_debug_handle.thread_ids)                \
00087         {                                                                   \
00088             globus_thread_t __self = GlobusDebugThreadId();                 \
00089             sprintf(buf, "%lu:%lu.%.9lu::%s",                               \
00090                 (unsigned long) __self.dummy,                               \
00091                 (unsigned long) current_time.tv_sec,                        \
00092                 (unsigned long) current_time.tv_nsec,                       \
00093                 fmt);                                                       \
00094             vfprintf(globus_i_##module_name##_debug_handle.file, buf, ap);  \
00095         }                                                                   \
00096         else                                                                \
00097         {                                                                   \
00098             sprintf(buf, "%lu.%.9lu::%s",                                   \
00099                 (unsigned long) current_time.tv_sec,                        \
00100                 (unsigned long) current_time.tv_nsec,                       \
00101                 fmt);                                                       \
00102             vfprintf(globus_i_##module_name##_debug_handle.file, buf, ap);  \
00103         }                                                                   \
00104         va_end(ap);                                                         \
00105     }                                                                       \
00106     void globus_i_##module_name##_debug_fwrite(                             \
00107         const void *ptr, size_t size, size_t  nmemb)                        \
00108     {                                                                       \
00109         if(globus_i_##module_name##_debug_handle.file)                      \
00110             fwrite(ptr, size, nmemb,                                        \
00111                 globus_i_##module_name##_debug_handle.file);                \
00112     }                                                                       \
00113     globus_debug_handle_t globus_i_##module_name##_debug_handle
00114 
00115 /* call this in a header file (if needed externally) */
00116 #define GlobusDebugDeclare(module_name)                                     \
00117     extern void globus_i_##module_name##_debug_printf(const char *, ...);   \
00118     extern void globus_i_##module_name##_debug_time_printf(const char *, ...);\
00119     extern void globus_i_##module_name##_debug_fwrite(                      \
00120         const void *ptr, size_t size, size_t nmemb);                        \
00121     extern globus_debug_handle_t globus_i_##module_name##_debug_handle
00122 
00123 /* call this in module activate func
00124  *
00125  * 'levels' is a space separated list of level names that can be used in env
00126  *    they will map to a 2^i value (so, list them in same order as value)
00127  *
00128  * will look in env for {module_name}_DEBUG whose value is:
00129  * <levels> [, [ [ # ] <file name>] [, <flags> [, <timestamp_levels>] ] ]
00130  * where <levels> can be a single numeric or '|' separated level names
00131  * <file name> is a debug output file... can be empty.  stderr by default
00132  *    if a '#' precedes the filename, the file will be overwritten on each run
00133  *    otherwise, the default is to append to the existing (if one exists)
00134  * <flags> 0 default (or any of the following to enable:
00135  *         1 show thread ids
00136  *         2 append pid to debug filename
00137  * <timestamp_levels> similar to <levels>. specifies which levels to print
00138  *   timestamps with.  default is none.
00139  * Also, users can use the ALL level in their env setting to turn on 
00140  * all levels or precede the list of levels with '^' to enable all levels
00141  * except those.
00142  */
00143 #define GlobusDebugInit(module_name, levels)                                \
00144     globus_debug_init(                                                      \
00145         #module_name "_DEBUG",                                              \
00146         #levels,                                                            \
00147         &globus_i_##module_name##_debug_handle)
00148 
00149 /* call this in module deactivate func */
00150 #define GlobusDebugDestroy(module_name)                                     \
00151     do                                                                      \
00152     {                                                                       \
00153         if(globus_i_##module_name##_debug_handle.using_file)                \
00154         {                                                                   \
00155             fclose(globus_i_##module_name##_debug_handle.file);             \
00156         }                                                                   \
00157         globus_i_##module_name##_debug_handle.file = GLOBUS_NULL;           \
00158     } while(0)
00159 
00160 /* use this to print a message unconditionally (message must be enclosed in
00161  * parenthesis and contains a format and possibly var args
00162  */
00163 #define GlobusDebugMyPrintf(module_name, message)                           \
00164     globus_i_##module_name##_debug_printf message
00165 #define GlobusDebugMyTimePrintf(module_name, message)                       \
00166     globus_i_##module_name##_debug_time_printf message
00167 
00168 #define GlobusDebugMyFwrite(module_name, buffer, size, count)               \
00169     globus_i_##module_name##_debug_fwrite((buffer), (size), (count))
00170 
00171 #define GlobusDebugMyFile(module_name)                                      \
00172     (globus_i_##module_name##_debug_handle.file)
00173     
00174 /* use this in an if() to debug enable blocks of code 
00175  * for example
00176  * 
00177  * if(GlobusDebugTrue(MY_MODULE, VERIFICATION))
00178  * {
00179  *    compute stats
00180  *    GlobusDebugMyPrintf(MY_MODULE, "Stats = %d\n", stats);
00181  * }
00182  */
00183 #define GlobusDebugTrue(module_name, level)                                 \
00184     (globus_i_##module_name##_debug_handle.levels & (level))
00185 
00186 #define GlobusDebugTimeTrue(module_name, level)                             \
00187     (globus_i_##module_name##_debug_handle.timestamp_levels & (level))
00188 
00189 /* most likely wrap this with your own macro,
00190  * so you don't need to pass module_name all the time
00191  * 'message' needs to be wrapped with parens and contains a format and
00192  * possibly var args
00193  */
00194 #define GlobusDebugPrintf(module_name, level, message)                      \
00195     do                                                                      \
00196     {                                                                       \
00197         if(GlobusDebugTrue(module_name, level))                             \
00198         {                                                                   \
00199             if(!GlobusDebugTimeTrue(module_name, level))                    \
00200             {                                                               \
00201                 GlobusDebugMyPrintf(module_name, message);                  \
00202             }                                                               \
00203             else                                                            \
00204             {                                                               \
00205                 GlobusDebugMyTimePrintf(module_name, message);              \
00206             }                                                               \
00207         }                                                                   \
00208     } while(0)
00209 
00210 #define GlobusDebugFwrite(module_name, level, buffer, size, count)          \
00211     do                                                                      \
00212     {                                                                       \
00213         if(GlobusDebugTrue(module_name, level))                             \
00214         {                                                                   \
00215             GlobusDebugMyFwrite(module_name, buffer, size, count);          \
00216         }                                                                   \
00217     } while(0)
00218 
00219 #else
00220 
00221 #define GlobusDebugThreadId()                                   0
00222 #define GlobusDebugDeclare(module_name)
00223 #define GlobusDebugDefine(module_name)
00224 #define GlobusDebugInit(module_name, levels)                    do {} while(0)
00225 #define GlobusDebugDestroy(module_name)                         do {} while(0)
00226 #define GlobusDebugPrintf(module_name, level, message)          do {} while(0)
00227 #define GlobusDebugFwrite(module_name, level, buffer, size, count)          \
00228                                                                 do {} while(0)
00229 #define GlobusDebugMyPrintf(module_name, message)               do {} while(0)
00230 #define GlobusDebugMyTimePrintf(module_name, message)           do {} while(0)
00231 #define GlobusDebugMyFwrite(module_name, buffer, size, count)   do {} while(0)
00232 #define GlobusDebugMyFile(module_name)                          (stderr)
00233 #define GlobusDebugTrue(module_name, level)                     0
00234 #define GlobusDebugTimeTrue(module_name, level)                 0
00235 
00236 #endif
00237 
00238 #ifdef __cplusplus
00239 }
00240 #endif
00241 
00242 #endif /* GLOBUS_DEBUG_H */

Generated on 17 Mar 2017 for globus_common by  doxygen 1.4.7