00001
00015 #define _GK_ERROR_C_
00016
00017
00018 #include <GKlib.h>
00019
00020
00021
00022
00023 #define MAX_JBUFS 128
00024 CMK_THREADLOCAL int gk_cur_jbufs=-1;
00025 CMK_THREADLOCAL jmp_buf gk_jbufs[MAX_JBUFS];
00026 CMK_THREADLOCAL jmp_buf gk_jbuf;
00027
00028 typedef void (*gksighandler_t)(int);
00029
00030
00031 static CMK_THREADLOCAL gksighandler_t old_SIGMEM_handler;
00032 static CMK_THREADLOCAL gksighandler_t old_SIGERR_handler;
00033 static CMK_THREADLOCAL gksighandler_t old_SIGMEM_handlers[MAX_JBUFS];
00034 static CMK_THREADLOCAL gksighandler_t old_SIGERR_handlers[MAX_JBUFS];
00035
00036
00037
00038 static CMK_THREADLOCAL int gk_exit_on_error = 1;
00039
00040
00041
00044
00045 void gk_set_exit_on_error(int value)
00046 {
00047 gk_exit_on_error = value;
00048 }
00049
00050
00051
00052
00055
00056 void errexit(char *f_str,...)
00057 {
00058 va_list argp;
00059
00060 va_start(argp, f_str);
00061 vfprintf(stderr, f_str, argp);
00062 va_end(argp);
00063
00064 if (strlen(f_str) == 0 || f_str[strlen(f_str)-1] != '\n')
00065 fprintf(stderr,"\n");
00066 fflush(stderr);
00067
00068 if (gk_exit_on_error)
00069 exit(-2);
00070
00071
00072 }
00073
00074
00075
00078
00079 void gk_errexit(int signum, char *f_str,...)
00080 {
00081 va_list argp;
00082
00083 va_start(argp, f_str);
00084 vfprintf(stderr, f_str, argp);
00085 va_end(argp);
00086
00087 fprintf(stderr,"\n");
00088 fflush(stderr);
00089
00090 if (gk_exit_on_error)
00091 raise(signum);
00092 }
00093
00094
00095
00099
00100 int gk_sigtrap()
00101 {
00102 if (gk_cur_jbufs+1 >= MAX_JBUFS)
00103 return 0;
00104
00105 gk_cur_jbufs++;
00106
00107 old_SIGMEM_handlers[gk_cur_jbufs] = signal(SIGMEM, gk_sigthrow);
00108 old_SIGERR_handlers[gk_cur_jbufs] = signal(SIGERR, gk_sigthrow);
00109
00110 return 1;
00111 }
00112
00113
00114
00117
00118 int gk_siguntrap()
00119 {
00120 if (gk_cur_jbufs == -1)
00121 return 0;
00122
00123 signal(SIGMEM, old_SIGMEM_handlers[gk_cur_jbufs]);
00124 signal(SIGERR, old_SIGERR_handlers[gk_cur_jbufs]);
00125
00126 gk_cur_jbufs--;
00127
00128 return 1;
00129 }
00130
00131
00132
00136
00137 void gk_sigthrow(int signum)
00138 {
00139 longjmp(gk_jbufs[gk_cur_jbufs], signum);
00140 }
00141
00142
00143
00144
00145
00146
00147 void gk_SetSignalHandlers()
00148 {
00149 old_SIGMEM_handler = signal(SIGMEM, gk_NonLocalExit_Handler);
00150 old_SIGERR_handler = signal(SIGERR, gk_NonLocalExit_Handler);
00151 }
00152
00153
00154
00155
00156
00157 void gk_UnsetSignalHandlers()
00158 {
00159 signal(SIGMEM, old_SIGMEM_handler);
00160 signal(SIGERR, old_SIGERR_handler);
00161 }
00162
00163
00164
00165
00166
00167
00168 void gk_NonLocalExit_Handler(int signum)
00169 {
00170 longjmp(gk_jbuf, signum);
00171 }
00172
00173
00174
00176
00177 char *gk_strerror(int errnum)
00178 {
00179 #if defined(WIN32) || defined(__MINGW32__)
00180 return strerror(errnum);
00181 #else
00182 #ifndef SUNOS
00183 static CMK_THREADLOCAL char buf[1024];
00184
00185
00186 #ifdef __GNUC__
00187 #pragma GCC diagnostic push
00188 #pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
00189 #endif
00190 strerror_r(errnum, buf, 1024);
00191 #ifdef __GNUC__
00192 #pragma GCC diagnostic pop
00193 #endif
00194
00195 buf[1023] = '\0';
00196 return buf;
00197 #else
00198 return strerror(errnum);
00199 #endif
00200 #endif
00201 }
00202
00203
00204
00205
00206
00207
00208 void PrintBackTrace()
00209 {
00210 #ifdef HAVE_EXECINFO_H
00211 void *array[10];
00212 int i, size;
00213 char **strings;
00214
00215 size = backtrace(array, 10);
00216 strings = backtrace_symbols(array, size);
00217
00218 printf("Obtained %d stack frames.\n", size);
00219 for (i=0; i<size; i++) {
00220 printf("%s\n", strings[i]);
00221 }
00222 free(strings);
00223 #endif
00224 }