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