Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
debugtrace.h
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 #ifndef _MCW_DEBUGTRACE_
00008 #define _MCW_DEBUGTRACE_
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 #ifndef TWO_TWO
00029 
00030 
00031 #  define TWO_ONE(x,y) x ## y
00032 #  define TWO_TWO(x,y) TWO_ONE(x,y)
00033 #endif
00034 
00035 
00036 #ifdef USE_TRACING
00037 
00038 #define DEBUG_MAX_DEPTH 1024  
00039 
00040 #define DBG_label DBG_labels[DBG_trace]
00041 
00042 
00043 
00044 #ifdef DONT_USE_MCW_MALLOC
00045 
00046 # define MCHECK 
00047 # define MPROBE 
00048 
00049 #else
00050 
00051 # define MCHECK                           \
00052    do{ char * mc = MCW_MALLOC_status ;    \
00053         if( mc != NULL ) printf("** Memory usage: %s\n",mc) ; } while(0)
00054 
00055 # define MPROBE do{ if( !DBG_trace ) (void)MCW_MALLOC_status ; } while(0)
00056 
00057 #endif
00058 
00059 #define TRACEBACK DBG_traceback()  
00060 
00061 
00062 
00063 
00064 
00065 #include <signal.h>
00066 #include <unistd.h>
00067 
00068 #ifdef _DEBUGTRACE_MAIN_
00069    char * DBG_rout[DEBUG_MAX_DEPTH] = { "Bottom of Debug Stack" } ;
00070    int DBG_num   = 1 ;
00071    int DBG_trace = 0 ;   
00072 
00073    char * DBG_labels[3] = { "Trace=OFF " , "Trace=LOW " , "Trace=HIGH" } ;
00074 
00075    char last_status[1024] = "\0" ;  
00076 
00077 void DBG_traceback(void)
00078 { int tt ;
00079   if( last_status[0] != '\0' )
00080     fprintf(stderr,"Last STATUS: %s\n",last_status) ;
00081   for( tt=DBG_num-1; tt >= 1 ; tt-- )
00082     fprintf(stderr,"%*.*s%s\n",tt+1,tt+1," ",DBG_rout[tt]) ;
00083 }
00084 
00085 void DBG_sigfunc(int sig)   
00086 {
00087    char * sname ; int ii ;
00088    static volatile int fff=0 ;
00089    if( fff ) _exit(1); else fff=1 ;
00090    switch(sig){
00091      default:      sname = "unknown" ; break ;
00092      case SIGPIPE: sname = "SIGPIPE" ; break ;
00093      case SIGSEGV: sname = "SIGSEGV" ; break ;
00094      case SIGBUS:  sname = "SIGBUS"  ; break ;
00095      case SIGINT:  sname = "SIGINT"  ; break ;
00096    }
00097    fprintf(stderr,"\nFatal Signal %d (%s) received\n",sig,sname) ;
00098    if( last_status[0] != '\0' )
00099      fprintf(stderr,"Last STATUS: %s\n",last_status) ;
00100    if( DBG_num >= 0 ){
00101      for( ii=DBG_num-1; ii >= 0 ; ii-- )
00102        fprintf(stderr,"%*.*s%s\n",ii+1,ii+1," ",DBG_rout[ii]) ;
00103    } else {
00104      fprintf(stderr,"[No debug tracing stack: DBG_num=%d]\n",DBG_num) ;
00105    }
00106    fprintf(stderr,"*** Program Abort ***\n") ; fflush(stderr) ;
00107    MPROBE ; exit(1) ;
00108 }
00109 
00110 
00111 
00112 
00113 
00114 #else 
00115    extern char * DBG_rout[DEBUG_MAX_DEPTH] ;
00116    extern int DBG_num ;
00117    extern int DBG_trace ;
00118    extern char * DBG_labels[3] ;
00119    extern void DBG_sigfunc(int) ;
00120    extern void DBG_traceback(void) ;
00121    extern char last_status[1024] ;
00122 #endif 
00123 
00124 #define DBG_SIGNALS ( signal(SIGPIPE,DBG_sigfunc) , \
00125                       signal(SIGSEGV,DBG_sigfunc) , \
00126                       signal(SIGINT ,DBG_sigfunc) , \
00127                       signal(SIGBUS ,DBG_sigfunc)  )
00128 
00129 
00130 
00131 
00132 #define DBG_LEADER_IN  "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
00133 #define DBG_LEADER_OUT "-----------------------------------------------------------"
00134 
00135 #define ENTRY(rout) do{ static char * rrr = (rout) ;  DBG_rout[DBG_num++] = rrr ; \
00136                         if( DBG_trace ){                                         \
00137                           printf("%*.*s%s [%d]: ENTRY (file=%s line=%d)\n",     \
00138                                  DBG_num,DBG_num,DBG_LEADER_IN,rrr,DBG_num,    \
00139                                  __FILE__ , __LINE__ ) ;                      \
00140                           MCHECK ; fflush(stdout) ; }                        \
00141                         last_status[0] = '\0' ;                             \
00142                     } while(0)
00143 
00144 #define DBROUT      DBG_rout[DBG_num-1]
00145 
00146 #define DBEXIT      do{ if( DBG_trace ){                                      \
00147                           printf("%*.*s%s [%d]: EXIT (file=%s line=%d)\n",     \
00148                                  DBG_num,DBG_num,DBG_LEADER_OUT,DBROUT,DBG_num, \
00149                                  __FILE__ , __LINE__ );                         \
00150                           MCHECK ; fflush(stdout) ; }                           \
00151                         DBG_num = (DBG_num>1) ? DBG_num-1 : 1 ;                 \
00152                         last_status[0] = '\0' ;                                 \
00153                     } while(0)
00154 
00155 
00156 
00157 #define mainENTRY(rout)                                            \
00158   do{ char *e=getenv("AFNI_TRACE");                                \
00159       if( e != NULL )                                              \
00160          DBG_trace = (*e=='y') ? 1 : (*e=='Y') ? 2 : 0 ;           \
00161       DBG_SIGNALS ; ENTRY(rout) ;                        } while(0)
00162 
00163 #define PRINT_TRACING (DBG_trace > 1)
00164 
00165 #define STATUS(str)                                              \
00166   do{ if(PRINT_TRACING){                                          \
00167         MCHECK ;                                                   \
00168         printf("%*.*s%s -- %s\n",DBG_num,DBG_num," ",DBROUT,(str)); \
00169         fflush(stdout) ; }                                           \
00170       strncpy(last_status,str,1023); last_status[1023]='\0';          \
00171   } while(0)
00172 
00173 
00174 #else 
00175 
00176 #  define ENTRY(rout)   
00177 #  define DBEXIT        
00178 #  define DBROUT        
00179 #  define STATUS(str)   
00180 #  define DBG_SIGNALS   
00181 #  define MCHECK        
00182 #  define MPROBE        
00183 #  define TRACEBACK     
00184 #  define PRINT_TRACING 0
00185 #  define DBG_trace     0          
00186 
00187 #  ifdef _DEBUGTRACE_MAIN_
00188       void DBG_sigfunc(int sig){} 
00189 #  else
00190       extern void DBG_sigfunc(int) ;
00191 #  endif
00192 
00193 #  define mainENTRY(rout) 
00194 
00195 #endif 
00196 
00197 
00198 
00199 
00200 #undef RETURN
00201 #undef EXRETURN
00202 #undef EXIT
00203 
00204 #define RETURN(val) do{ DBEXIT    ; return (val) ; } while(0)
00205 #define EXRETURN    do{ DBEXIT    ; return       ; } while(0)
00206 #define EXIT(n)     do{ TRACEBACK ; exit(n)      ; } while(0)
00207 
00208 
00209 
00210 #ifndef MCHECK
00211 # define MCHECK 
00212 # define MPROBE 
00213 #endif
00214 
00215 
00216 #include <stdarg.h>
00217 extern void INFO_message   ( char *fmt , ... ) ;  
00218 extern void ININFO_message ( char *fmt , ... ) ;
00219 extern void WARNING_message( char *fmt , ... ) ;
00220 extern void ERROR_message  ( char *fmt , ... ) ;
00221 extern void ERROR_exit     ( char *fmt , ... ) ;
00222 #define FATAL_ERROR_message ERROR_exit
00223 
00224 
00225 #endif