CMS 3D CMS Logo

IgTrace.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
00002 
00003 #include "IgTools/IgTrace/src/IgTrace.h"
00004 #include "IgTools/IgTrace/src/IgTraceAtomic.h"
00005 #include "IgTools/IgHook/interface/IgHookTrace.h"
00006 #include <sys/types.h>
00007 #include <sys/time.h>
00008 #include <cstdlib>
00009 #include <cstdio>
00010 #include <cstdarg>
00011 #include <cerrno>
00012 #include <cstring>
00013 #include <unistd.h>
00014 
00015 #ifdef __APPLE__
00016 # include <crt_externs.h>
00017 # define program_invocation_name **_NSGetArgv()
00018 #endif
00019 
00020 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00021 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00022 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00023 
00025 struct IgTraceFilter
00026 {
00027     IgTraceFilter       *nextFilter;
00028     char                *extraInfo;
00029     char                *functionName;
00030     char                *libraryName;
00031 };
00032 
00033 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00034 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00035 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00036 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00037 
00038 // Data for this profiler module
00039 static IgTraceAtomic    s_enabled       = 0;
00040 static bool             s_initialized   = false;
00041 static bool             s_activated     = false;
00042 static volatile int     s_quitting      = 0;
00043 static IgTraceFilter    *s_filters      = 0;
00044 
00045 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00046 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00047 
00054 bool
00055 IgTrace::initialize (void)
00056 {
00057     if (! s_initialized)
00058     {
00059         s_initialized = true;
00060 
00061         const char *options = IgTrace::options ();
00062         if (! options || ! *options)
00063         {
00064             IgTrace::debug ("$IGTRACE not set, not tracing this process\n");
00065             return s_activated = false;
00066         }
00067         while (options && *options)
00068         {
00069             while (*options == ' ' || *options == ',')
00070                 ++options;
00071 
00072             if (! strncmp (options, "igtrace:reject='", 16))
00073             {
00074                 options += 16;
00075 
00076                 const char *info = options;
00077                 int infolen = 0;
00078                 while (*options && *options != '\'' && *options != ':')
00079                     ++options, ++infolen;
00080                 if (*options == ':')
00081                     ++options;
00082 
00083                 const char *func = options;
00084                 int funclen = 0;
00085                 while (*options && *options != '\'' && *options != ':')
00086                     ++options, ++funclen;
00087                 if (*options == ':')
00088                     ++options;
00089 
00090                 const char *lib = options;
00091                 int liblen = 0;
00092                 while (*options && *options != '\'' && *options != ':')
00093                     ++options, ++liblen;
00094 
00095                 IgTraceFilter *f = new IgTraceFilter;
00096                 f->nextFilter = 0;
00097                 f->extraInfo     = (infolen ? strndup (info, infolen) : 0);
00098                 f->functionName  = (funclen ? strndup (func, funclen) : 0);
00099                 f->libraryName   = (liblen  ? strndup (lib,  liblen)  : 0);
00100 
00101                 IgTraceFilter **chain = &s_filters;
00102                 while (*chain)
00103                     chain = &(*chain)->nextFilter;
00104     
00105                 *chain = f;
00106 
00107                 while (*options && *options != '\'')
00108                     ++options;
00109             }
00110             else
00111                 options++;
00112 
00113             while (*options && *options != ',' && *options != ' ')
00114                 options++;
00115         }
00116 
00117         const char *target = getenv ("IGTRACE_TARGET");
00118         if (target && ! strstr (program_invocation_name, target))
00119         {
00120             IgTrace::debug ("Current process not selected for tracing:"
00121                             " process '%s' does not match '%s'\n",
00122                             program_invocation_name, target);
00123             return s_activated = false;
00124         }
00125 
00126         IgTrace::debug ("Activated in %s\n", program_invocation_name);
00127         IgTrace::debug ("Options: %s\n", IgTrace::options ());
00128         s_activated = true;
00129         s_enabled = 1;
00130     }
00131 
00132     if (! s_activated)
00133         return false;
00134 
00135     return true;
00136 }
00137 
00143 bool
00144 IgTrace::enabled (void)
00145 {
00146     return s_enabled > 0;
00147 }
00148 
00154 bool
00155 IgTrace::enable (void)
00156 {
00157     IgTraceAtomic newval = IgTraceAtomicInc (&s_enabled);
00158     return newval > 0;
00159 }
00160 
00166 bool
00167 IgTrace::disable (void)
00168 {
00169     IgTraceAtomic newval = IgTraceAtomicDec (&s_enabled);
00170     return newval >= 0;
00171 }
00172 
00174 const char *
00175 IgTrace::options (void)
00176 {
00177      static const char *s_options = getenv ("IGTRACE");
00178      return s_options;
00179 }
00180 
00182 int
00183 IgTrace::panic (const char *file, int line, const char *func, const char *expr)
00184 {
00185     IgTrace::disable ();
00186 
00187 #if __linux
00188     fprintf (stderr, "%s: ", program_invocation_name);
00189 #endif
00190     fprintf (stderr, "%s:%d: %s: assertion failure: %s\n", file, line, func, expr);
00191 
00192     void *trace [128];
00193     int levels = IgHookTrace::stacktrace (trace, 128);
00194     for (int i = 2; i < levels; ++i)
00195     {
00196         const char      *sym = 0;
00197         const char      *lib = 0;
00198         int             offset = 0;
00199         int             liboffset = 0;
00200         IgHookTrace::symbol (trace [i], sym, lib, offset, liboffset);
00201         fprintf (stderr, "  %p %s + %d [%s + %d]\n", trace [i], sym, offset, lib, liboffset);
00202     }
00203 
00204     // abort ();
00205     IgTrace::enable ();
00206     return 1;
00207 }
00208 
00211 void
00212 IgTrace::debug (const char *format, ...)
00213 {
00214     static const char *debugging = getenv ("IGTRACE_DEBUGGING");
00215     if (debugging)
00216     {
00217         timeval tv;
00218         gettimeofday (&tv, 0);
00219         fprintf (stderr, "*** IgTrace(%lu, %.3f): ",
00220                  (unsigned long) getpid(),
00221                  tv.tv_sec + 1e-6*tv.tv_usec);
00222 
00223         va_list args;
00224         va_start (args, format);
00225         vfprintf (stderr, format, args);
00226         va_end (args);
00227     }
00228 }
00229 
00231 const char *
00232 IgTrace::program (void)
00233 {
00234     return program_invocation_name;
00235 }
00236 
00238 bool
00239 IgTrace::filter (const char *info, void *stack [], int depth)
00240 {
00241     bool pass = true;
00242     IgTraceFilter *f = s_filters;
00243     while (f && pass)
00244     {
00245         if (info && f->extraInfo && strstr (info, f->extraInfo))
00246             pass = false;
00247 
00248         for (int i = 0; i < depth && pass; ++i)
00249         {
00250             bool        passthis = true;
00251             const char  *sym = 0;
00252             const char  *lib = 0;
00253             int         junk = 0;
00254             
00255             if (! IgHookTrace::symbol (stack[i], sym, lib, junk, junk))
00256                 continue;
00257 
00258             if (passthis && sym && f->functionName && strstr (sym, f->functionName))
00259                 passthis = false;
00260 
00261             if (passthis && lib && f->libraryName && strstr (lib, f->libraryName))
00262                 passthis = false;
00263 
00264             if (! passthis)
00265                 pass = false;
00266         }
00267 
00268         f = f->nextFilter;
00269     }
00270 
00271     return pass;
00272 }
00273 
00275 static bool autoboot = IgTrace::initialize ();

Generated on Tue Jun 9 17:38:09 2009 for CMSSW by  doxygen 1.5.4