[0e1846] | 1 | /**************************************** |
---|
| 2 | * Computer Algebra System SINGULAR * |
---|
| 3 | ****************************************/ |
---|
| 4 | /* |
---|
| 5 | * ABSTRACT - interupt handling |
---|
| 6 | */ |
---|
[b5dd9b] | 7 | #include "kernel/mod2.h" |
---|
[9f7665] | 8 | |
---|
[b5dd9b] | 9 | #include "omalloc/omalloc.h" |
---|
[9f7665] | 10 | |
---|
[b5dd9b] | 11 | #include "reporter/si_signals.h" |
---|
| 12 | #include "Singular/fevoices.h" |
---|
[b60bfe] | 13 | |
---|
[2d5de0e] | 14 | #include "misc/options.h" |
---|
[b5dd9b] | 15 | #include "Singular/tok.h" |
---|
| 16 | #include "Singular/ipshell.h" |
---|
| 17 | #include "Singular/cntrlc.h" |
---|
| 18 | #include "Singular/feOpt.h" |
---|
| 19 | #include "Singular/misc_ip.h" |
---|
| 20 | #include "Singular/links/silink.h" |
---|
| 21 | #include "Singular/links/ssiLink.h" |
---|
[dc0898] | 22 | |
---|
[d6681d] | 23 | /* undef, if you don't want GDB to come up on error */ |
---|
[b39d4d] | 24 | |
---|
[b60bfe] | 25 | #define CALL_GDB |
---|
| 26 | |
---|
[d6681d] | 27 | #if defined(__OPTIMIZE__) && defined(CALL_GDB) |
---|
| 28 | #undef CALL_GDB |
---|
| 29 | #endif |
---|
| 30 | |
---|
[337d5b] | 31 | #ifdef TIME_WITH_SYS_TIME |
---|
| 32 | #include <time.h> |
---|
| 33 | #ifdef HAVE_SYS_TIME_H |
---|
| 34 | #include <sys/time.h> |
---|
| 35 | #endif |
---|
| 36 | #else |
---|
| 37 | #ifdef HAVE_SYS_TIME_H |
---|
| 38 | #include <sys/time.h> |
---|
| 39 | #else |
---|
| 40 | #include <time.h> |
---|
| 41 | #endif |
---|
| 42 | #endif |
---|
| 43 | #ifdef HAVE_SYS_TIMES_H |
---|
| 44 | #include <sys/times.h> |
---|
| 45 | #endif |
---|
| 46 | |
---|
| 47 | #define INTERACTIVE 0 |
---|
| 48 | #define STACK_TRACE 1 |
---|
| 49 | |
---|
| 50 | #ifdef CALL_GDB |
---|
| 51 | static void debug (int); |
---|
[a5da6f] | 52 | static void debug_stop (char *const*args); |
---|
[337d5b] | 53 | #endif |
---|
| 54 | #ifndef __OPTIMIZE__ |
---|
[a5da6f] | 55 | static void stack_trace (char *const*args); |
---|
[337d5b] | 56 | #endif |
---|
[0e1846] | 57 | |
---|
[85ab8cd] | 58 | si_link pipeLastLink=NULL; |
---|
[655e1f] | 59 | BOOLEAN singular_in_batchmode=FALSE; |
---|
[85ab8cd] | 60 | |
---|
[2e4ec14] | 61 | void sig_pipe_hdl(int /*sig*/) |
---|
[85ab8cd] | 62 | { |
---|
| 63 | if (pipeLastLink!=NULL) |
---|
| 64 | { |
---|
| 65 | slClose(pipeLastLink); |
---|
| 66 | pipeLastLink=NULL; |
---|
| 67 | WerrorS("pipe failed"); |
---|
| 68 | } |
---|
| 69 | } |
---|
| 70 | |
---|
[659a7a] | 71 | volatile BOOLEAN do_shutdown = FALSE; |
---|
| 72 | volatile int defer_shutdown = 0; |
---|
| 73 | |
---|
[2e4ec14] | 74 | void sig_term_hdl(int /*sig*/) |
---|
[7626c5f] | 75 | { |
---|
[659a7a] | 76 | do_shutdown = TRUE; |
---|
| 77 | if (!defer_shutdown) |
---|
[b60bfe] | 78 | { |
---|
[659a7a] | 79 | m2_end(1); |
---|
[b60bfe] | 80 | } |
---|
[7626c5f] | 81 | } |
---|
| 82 | |
---|
[d5bd816] | 83 | /*---------------------------------------------------------------------* |
---|
[2d5de0e] | 84 | * File scope Variables (Variables shared by several functions in |
---|
[d5bd816] | 85 | * the same file ) |
---|
| 86 | * |
---|
| 87 | *---------------------------------------------------------------------*/ |
---|
[0e1846] | 88 | /* data */ |
---|
[07dacd] | 89 | jmp_buf si_start_jmpbuf; |
---|
[0e1846] | 90 | int siRandomStart; |
---|
[07dacd] | 91 | short si_restart=0; |
---|
[0e1846] | 92 | |
---|
[5812c69] | 93 | typedef void (*si_hdl_typ)(int); |
---|
| 94 | |
---|
[7c96c03] | 95 | |
---|
[0e1846] | 96 | /*0 implementation*/ |
---|
[d5bd816] | 97 | /*---------------------------------------------------------------------* |
---|
| 98 | * Functions declarations |
---|
| 99 | * |
---|
| 100 | *---------------------------------------------------------------------*/ |
---|
[b60bfe] | 101 | void sigint_handler(int /*sig*/); |
---|
[d5bd816] | 102 | |
---|
[7c96c03] | 103 | si_hdl_typ si_set_signal ( int sig, si_hdl_typ signal_handler); |
---|
[d5bd816] | 104 | |
---|
| 105 | /*---------------------------------------------------------------------*/ |
---|
[337d5b] | 106 | /** |
---|
[d5bd816] | 107 | * @brief meta function for binding a signal to an handler |
---|
| 108 | |
---|
| 109 | @param[in] sig Signal number |
---|
| 110 | @param[in] signal_handler Pointer to signal handler |
---|
| 111 | |
---|
| 112 | @return value of signal() |
---|
| 113 | **/ |
---|
| 114 | /*---------------------------------------------------------------------*/ |
---|
[85ab8cd] | 115 | si_hdl_typ si_set_signal ( int sig, si_hdl_typ signal_handler) |
---|
[d5bd816] | 116 | { |
---|
[72de5f] | 117 | #if 0 |
---|
[7c96c03] | 118 | si_hdl_typ retval=signal (sig, (si_hdl_typ)signal_handler); |
---|
| 119 | if (retval == SIG_ERR) |
---|
| 120 | { |
---|
[d5bd816] | 121 | fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig); |
---|
| 122 | } |
---|
[bdda8c2] | 123 | si_siginterrupt(sig, 0); |
---|
[72de5f] | 124 | /*system calls will be restarted if interrupted by the specified |
---|
| 125 | * signal sig. This is the default behavior in Linux. |
---|
| 126 | */ |
---|
| 127 | #else |
---|
| 128 | struct sigaction new_action,old_action; |
---|
[61512d3] | 129 | memset(&new_action, 0, sizeof(struct sigaction)); |
---|
[72de5f] | 130 | |
---|
| 131 | /* Set up the structure to specify the new action. */ |
---|
| 132 | new_action.sa_handler = signal_handler; |
---|
| 133 | if (sig==SIGINT) |
---|
| 134 | sigemptyset (&new_action.sa_mask); |
---|
| 135 | else |
---|
| 136 | new_action.sa_flags = SA_RESTART; |
---|
| 137 | |
---|
[bdda8c2] | 138 | int r=si_sigaction (sig, &new_action, &old_action); |
---|
[72de5f] | 139 | si_hdl_typ retval=(si_hdl_typ)old_action.sa_handler; |
---|
| 140 | if (r == -1) |
---|
| 141 | { |
---|
| 142 | fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig); |
---|
| 143 | retval=SIG_ERR; |
---|
| 144 | } |
---|
[206aed] | 145 | #endif |
---|
[d5bd816] | 146 | return retval; |
---|
[7c96c03] | 147 | } /* si_set_signal */ |
---|
[d5bd816] | 148 | |
---|
[0e1846] | 149 | |
---|
[d5bd816] | 150 | /*---------------------------------------------------------------------*/ |
---|
[319eab] | 151 | #if defined(__linux__) && defined(__i386) |
---|
[4f818c] | 152 | #if !defined(HAVE_SIGCONTEXT) && !defined(HAVE_ASM_SIGCONTEXT_H) |
---|
[c7a653] | 153 | // we need the following structure sigcontext_struct. |
---|
| 154 | // if configure finds asm/singcontext.h we assume |
---|
| 155 | // that this file contains the structure and is included |
---|
| 156 | // via signal.h |
---|
[0e1846] | 157 | struct sigcontext_struct { |
---|
| 158 | unsigned short gs, __gsh; |
---|
| 159 | unsigned short fs, __fsh; |
---|
| 160 | unsigned short es, __esh; |
---|
| 161 | unsigned short ds, __dsh; |
---|
| 162 | unsigned long edi; |
---|
| 163 | unsigned long esi; |
---|
| 164 | unsigned long ebp; |
---|
| 165 | unsigned long esp; |
---|
| 166 | unsigned long ebx; |
---|
| 167 | unsigned long edx; |
---|
| 168 | unsigned long ecx; |
---|
| 169 | unsigned long eax; |
---|
| 170 | unsigned long trapno; |
---|
| 171 | unsigned long err; |
---|
| 172 | unsigned long eip; |
---|
| 173 | unsigned short cs, __csh; |
---|
| 174 | unsigned long eflags; |
---|
| 175 | unsigned long esp_at_signal; |
---|
| 176 | unsigned short ss, __ssh; |
---|
| 177 | unsigned long i387; |
---|
| 178 | unsigned long oldmask; |
---|
| 179 | unsigned long cr2; |
---|
| 180 | }; |
---|
[337d5b] | 181 | #endif |
---|
[f72aa03] | 182 | #define HAVE_SIGSTRUCT |
---|
[0e1846] | 183 | typedef struct sigcontext_struct sigcontext; |
---|
[f72aa03] | 184 | #endif |
---|
[337d5b] | 185 | |
---|
[319eab] | 186 | #if defined(__linux__) && defined(__amd64) |
---|
[f72aa03] | 187 | #define HAVE_SIGSTRUCT |
---|
| 188 | #endif |
---|
[0e1846] | 189 | |
---|
[d5bd816] | 190 | |
---|
[337d5b] | 191 | #if defined(HAVE_SIGSTRUCT) |
---|
[d5bd816] | 192 | /*2---------------------------------------------------------------------*/ |
---|
[337d5b] | 193 | /** |
---|
| 194 | * @brief signal handler for run time errors, linux/i386, x86_64 version |
---|
[d5bd816] | 195 | |
---|
[337d5b] | 196 | @param[in] sig |
---|
| 197 | @param[in] s |
---|
[d5bd816] | 198 | **/ |
---|
| 199 | /*---------------------------------------------------------------------*/ |
---|
[0e1846] | 200 | void sigsegv_handler(int sig, sigcontext s) |
---|
| 201 | { |
---|
[92644b] | 202 | fprintf(stderr,"Singular : signal %d (v: %d):\n",sig,SINGULAR_VERSION); |
---|
[0e1846] | 203 | if (sig!=SIGINT) |
---|
| 204 | { |
---|
[f9d901] | 205 | fprintf(stderr,"current line:>>%s<<\n",my_yylinebuf); |
---|
[1270db] | 206 | fprintf(stderr,"Segment fault/Bus error occurred at %lx because of %lx (r:%d)\n" |
---|
[0e1846] | 207 | "please inform the authors\n", |
---|
[c7a653] | 208 | #ifdef __i386__ |
---|
[28fc7b] | 209 | (long)s.eip, |
---|
[c7a653] | 210 | #else /* x86_64*/ |
---|
[28fc7b] | 211 | (long)s.rip, |
---|
[c7a653] | 212 | #endif |
---|
| 213 | (long)s.cr2,siRandomStart); |
---|
[0e1846] | 214 | } |
---|
[337d5b] | 215 | #ifdef __OPTIMIZE__ |
---|
[07dacd] | 216 | if(si_restart<3) |
---|
| 217 | { |
---|
| 218 | si_restart++; |
---|
[73481b] | 219 | fputs("trying to restart...\n",stderr); |
---|
[07dacd] | 220 | init_signals(); |
---|
| 221 | longjmp(si_start_jmpbuf,1); |
---|
| 222 | } |
---|
[337d5b] | 223 | #endif /* __OPTIMIZE__ */ |
---|
| 224 | #ifdef CALL_GDB |
---|
[788fdf] | 225 | if (sig!=SIGINT) |
---|
[9803fb] | 226 | { |
---|
| 227 | if (singular_in_batchmode) debug(STACK_TRACE); |
---|
| 228 | else debug(INTERACTIVE); |
---|
| 229 | } |
---|
[337d5b] | 230 | #endif /* CALL_GDB */ |
---|
[0e1846] | 231 | exit(0); |
---|
| 232 | } |
---|
| 233 | |
---|
[d5bd816] | 234 | /*---------------------------------------------------------------------*/ |
---|
[337d5b] | 235 | #elif defined(SunOS) /*SPARC_SUNOS*/ |
---|
[0e1846] | 236 | /*2 |
---|
| 237 | * signal handler for run time errors, sparc sunos 4 version |
---|
| 238 | */ |
---|
| 239 | void sigsegv_handler(int sig, int code, struct sigcontext *scp, char *addr) |
---|
| 240 | { |
---|
[92644b] | 241 | fprintf(stderr,"Singular : signal %d, code %d (v: %d):\n", |
---|
| 242 | sig,code,SINGULAR_VERSION); |
---|
[0e1846] | 243 | if ((sig!=SIGINT)&&(sig!=SIGABRT)) |
---|
| 244 | { |
---|
[f9d901] | 245 | fprintf(stderr,"current line:>>%s<<\n",my_yylinebuf); |
---|
[0e1846] | 246 | fprintf(stderr,"Segment fault/Bus error occurred at %x (r:%d)\n" |
---|
| 247 | "please inform the authors\n", |
---|
| 248 | (int)addr,siRandomStart); |
---|
| 249 | } |
---|
[337d5b] | 250 | #ifdef __OPTIMIZE__ |
---|
[97eb91] | 251 | if(si_restart<3) |
---|
| 252 | { |
---|
| 253 | si_restart++; |
---|
[73481b] | 254 | fputs("trying to restart...\n",stderr); |
---|
[97eb91] | 255 | init_signals(); |
---|
| 256 | longjmp(si_start_jmpbuf,1); |
---|
| 257 | } |
---|
[337d5b] | 258 | #endif /* __OPTIMIZE__ */ |
---|
| 259 | #ifdef CALL_GDB |
---|
[0e1846] | 260 | if (sig!=SIGINT) debug(STACK_TRACE); |
---|
[337d5b] | 261 | #endif /* CALL_GDB */ |
---|
[0e1846] | 262 | exit(0); |
---|
| 263 | } |
---|
[b60bfe] | 264 | |
---|
[337d5b] | 265 | #else |
---|
[0e1846] | 266 | |
---|
[d5bd816] | 267 | /*---------------------------------------------------------------------*/ |
---|
[0e1846] | 268 | /*2 |
---|
| 269 | * signal handler for run time errors, general version |
---|
| 270 | */ |
---|
| 271 | void sigsegv_handler(int sig) |
---|
| 272 | { |
---|
[92644b] | 273 | fprintf(stderr,"Singular : signal %d (v: %d):\n", |
---|
| 274 | sig,SINGULAR_VERSION); |
---|
[0e1846] | 275 | if (sig!=SIGINT) |
---|
| 276 | { |
---|
[f9d901] | 277 | fprintf(stderr,"current line:>>%s<<\n",my_yylinebuf); |
---|
[0e1846] | 278 | fprintf(stderr,"Segment fault/Bus error occurred (r:%d)\n" |
---|
| 279 | "please inform the authors\n", |
---|
| 280 | siRandomStart); |
---|
| 281 | } |
---|
[337d5b] | 282 | #ifdef __OPTIMIZE__ |
---|
[97eb91] | 283 | if(si_restart<3) |
---|
| 284 | { |
---|
| 285 | si_restart++; |
---|
[73481b] | 286 | fputs("trying to restart...\n",stderr); |
---|
[97eb91] | 287 | init_signals(); |
---|
| 288 | longjmp(si_start_jmpbuf,1); |
---|
| 289 | } |
---|
[337d5b] | 290 | #endif /* __OPTIMIZE__ */ |
---|
| 291 | #ifdef CALL_GDB |
---|
[0e1846] | 292 | if (sig!=SIGINT) debug(STACK_TRACE); |
---|
[337d5b] | 293 | #endif /* CALL_GDB */ |
---|
[0e1846] | 294 | exit(0); |
---|
| 295 | } |
---|
[337d5b] | 296 | #endif |
---|
[d5bd816] | 297 | |
---|
[b60bfe] | 298 | |
---|
[0e1846] | 299 | /*2 |
---|
| 300 | * signal handler for SIGINT |
---|
| 301 | */ |
---|
[32cb7a] | 302 | int sigint_handler_cnt=0; |
---|
[2e4ec14] | 303 | void sigint_handler(int /*sig*/) |
---|
[0e1846] | 304 | { |
---|
[66415e1] | 305 | mflush(); |
---|
[337d5b] | 306 | #ifdef HAVE_FEREAD |
---|
[0fa9018] | 307 | if (fe_is_raw_tty) fe_temp_reset(); |
---|
[337d5b] | 308 | #endif /* HAVE_FEREAD */ |
---|
[32cb7a] | 309 | char default_opt=' '; |
---|
| 310 | if ((feOptSpec[FE_OPT_CNTRLC].value!=NULL) |
---|
| 311 | && ((char*)(feOptSpec[FE_OPT_CNTRLC].value))[0]) |
---|
| 312 | { default_opt=((char*)(feOptSpec[FE_OPT_CNTRLC].value))[0]; } |
---|
[66415e1] | 313 | loop |
---|
| 314 | { |
---|
[e8a30d] | 315 | int cnt=0; |
---|
[2272c33] | 316 | int c; |
---|
[32cb7a] | 317 | |
---|
| 318 | if (singular_in_batchmode) |
---|
[2272c33] | 319 | { |
---|
[eed07e8] | 320 | c = 'q'; |
---|
[2272c33] | 321 | } |
---|
[32cb7a] | 322 | else if (default_opt!=' ') |
---|
| 323 | { |
---|
| 324 | c = default_opt; |
---|
| 325 | } |
---|
[2272c33] | 326 | else |
---|
| 327 | { |
---|
[eed07e8] | 328 | fprintf(stderr,"// ** Interrupt at cmd:`%s` in line:'%s'\n", |
---|
| 329 | Tok2Cmdname(iiOp),my_yylinebuf); |
---|
[fc2f76] | 330 | if (feOptValue(FE_OPT_EMACS) == NULL) |
---|
[eed07e8] | 331 | { |
---|
[8af20e] | 332 | fputs("abort after this command(a), abort immediately(r), print backtrace(b), continue(c) or quit Singular(q) ?",stderr); |
---|
| 333 | fflush(stderr);fflush(stdin); |
---|
[eed07e8] | 334 | c = fgetc(stdin); |
---|
| 335 | } |
---|
| 336 | else |
---|
| 337 | { |
---|
| 338 | c = 'a'; |
---|
| 339 | } |
---|
[2272c33] | 340 | } |
---|
[337d5b] | 341 | |
---|
[2272c33] | 342 | switch(c) |
---|
[66415e1] | 343 | { |
---|
[32cb7a] | 344 | case 'q': case EOF: |
---|
[66415e1] | 345 | m2_end(2); |
---|
[07dacd] | 346 | case 'r': |
---|
[32cb7a] | 347 | if (sigint_handler_cnt<3) |
---|
| 348 | { |
---|
| 349 | sigint_handler_cnt++; |
---|
| 350 | fputs("** Warning: Singular should be restarted as soon as possible **\n",stderr); |
---|
| 351 | fflush(stderr); |
---|
[8e884e] | 352 | extern void my_yy_flush(); |
---|
| 353 | my_yy_flush(); |
---|
| 354 | currentVoice=feInitStdin(NULL); |
---|
[32cb7a] | 355 | longjmp(si_start_jmpbuf,1); |
---|
| 356 | } |
---|
| 357 | else |
---|
| 358 | { |
---|
| 359 | fputs("** tried too often, try another possibility **\n",stderr); |
---|
| 360 | fflush(stderr); |
---|
| 361 | } |
---|
| 362 | break; |
---|
[09e228] | 363 | case 'b': |
---|
| 364 | VoiceBackTrack(); |
---|
| 365 | break; |
---|
[e8a30d] | 366 | case 'a': |
---|
| 367 | siCntrlc++; |
---|
[66415e1] | 368 | case 'c': |
---|
[fc2f76] | 369 | if ((feOptValue(FE_OPT_EMACS) == NULL) && (default_opt!=' ')) |
---|
[32cb7a] | 370 | { |
---|
| 371 | /* Read until a newline or EOF */ |
---|
| 372 | while (c != EOF && c != '\n') c = fgetc(stdin); |
---|
| 373 | } |
---|
[7c96c03] | 374 | si_set_signal(SIGINT ,(si_hdl_typ)sigint_handler); |
---|
[07dacd] | 375 | return; |
---|
[50b2df] | 376 | //siCntrlc ++; |
---|
[7c96c03] | 377 | //if (siCntrlc>2) si_set_signal(SIGINT,(si_hdl_typ) sigsegv_handler); |
---|
| 378 | //else si_set_signal(SIGINT,(si_hdl_typ) sigint_handler); |
---|
[66415e1] | 379 | } |
---|
[e8a30d] | 380 | cnt++; |
---|
| 381 | if(cnt>5) m2_end(2); |
---|
[66415e1] | 382 | } |
---|
[0e1846] | 383 | } |
---|
| 384 | |
---|
[e8a30d] | 385 | //void test_int() |
---|
| 386 | //{ |
---|
| 387 | // if (siCntrlc!=0) |
---|
| 388 | // { |
---|
| 389 | // int saveecho = si_echo; |
---|
| 390 | // siCntrlc = FALSE; |
---|
[7c96c03] | 391 | // si_set_signal(SIGINT ,sigint_handler); |
---|
[e8a30d] | 392 | // iiDebug(); |
---|
| 393 | // si_echo = saveecho; |
---|
| 394 | // } |
---|
| 395 | //} |
---|
[0e1846] | 396 | |
---|
[d5bd816] | 397 | # ifndef __OPTIMIZE__ |
---|
[ccae2f] | 398 | volatile int si_stop_stack_trace_x; |
---|
[d5bd816] | 399 | # ifdef CALL_GDB |
---|
[577d19f] | 400 | static void debug (int method) |
---|
[0e1846] | 401 | { |
---|
[8a6c6a] | 402 | if (feOptValue(FE_OPT_NO_TTY)) |
---|
| 403 | { |
---|
| 404 | dReportError("Caught Signal 11"); |
---|
| 405 | return; |
---|
| 406 | } |
---|
[0e1846] | 407 | int pid; |
---|
| 408 | char buf[16]; |
---|
[1faa87] | 409 | char * args[4] = { (char*)"gdb", (char*)"Singular", NULL, NULL }; |
---|
[577d19f] | 410 | |
---|
[337d5b] | 411 | #ifdef HAVE_FEREAD |
---|
[0fa9018] | 412 | if (fe_is_raw_tty) fe_temp_reset(); |
---|
[337d5b] | 413 | #endif /* HAVE_FEREAD */ |
---|
[0fa9018] | 414 | |
---|
[0e1846] | 415 | sprintf (buf, "%d", getpid ()); |
---|
| 416 | |
---|
| 417 | args[2] = buf; |
---|
| 418 | |
---|
| 419 | pid = fork (); |
---|
| 420 | if (pid == 0) |
---|
| 421 | { |
---|
| 422 | switch (method) |
---|
| 423 | { |
---|
| 424 | case INTERACTIVE: |
---|
[73481b] | 425 | fputs ("\n\nquit with \"p si_stop_stack_trace_x=0\"\n\n\n",stderr); |
---|
[0e1846] | 426 | debug_stop (args); |
---|
| 427 | break; |
---|
| 428 | case STACK_TRACE: |
---|
[73481b] | 429 | fputs ("stack_trace\n",stderr); |
---|
[0e1846] | 430 | stack_trace (args); |
---|
| 431 | break; |
---|
[5687c9] | 432 | default: |
---|
| 433 | // should not be reached: |
---|
| 434 | exit(1); |
---|
[0e1846] | 435 | } |
---|
| 436 | } |
---|
| 437 | else if (pid == -1) |
---|
| 438 | { |
---|
| 439 | perror ("could not fork"); |
---|
| 440 | return; |
---|
| 441 | } |
---|
| 442 | |
---|
| 443 | si_stop_stack_trace_x = 1; |
---|
| 444 | while (si_stop_stack_trace_x) ; |
---|
| 445 | } |
---|
| 446 | |
---|
[a5da6f] | 447 | static void debug_stop (char *const*args) |
---|
[0e1846] | 448 | { |
---|
| 449 | execvp (args[0], args); |
---|
| 450 | perror ("exec failed"); |
---|
| 451 | _exit (0); |
---|
| 452 | } |
---|
[d5bd816] | 453 | # endif /* CALL_GDB */ |
---|
[0e1846] | 454 | |
---|
[a5da6f] | 455 | static void stack_trace (char *const*args) |
---|
[0e1846] | 456 | { |
---|
| 457 | int pid; |
---|
| 458 | int in_fd[2]; |
---|
| 459 | int out_fd[2]; |
---|
| 460 | fd_set fdset; |
---|
| 461 | fd_set readset; |
---|
| 462 | struct timeval tv; |
---|
| 463 | int sel, index, state; |
---|
| 464 | char buffer[256]; |
---|
| 465 | char c; |
---|
| 466 | |
---|
| 467 | if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1)) |
---|
| 468 | { |
---|
| 469 | perror ("could open pipe"); |
---|
[0fa9018] | 470 | m2_end(999); |
---|
[0e1846] | 471 | } |
---|
| 472 | |
---|
| 473 | pid = fork (); |
---|
| 474 | if (pid == 0) |
---|
| 475 | { |
---|
[bdda8c2] | 476 | si_close (0); si_dup2 (in_fd[0],0); /* set the stdin to the in pipe */ |
---|
| 477 | si_close (1); si_dup2 (out_fd[1],1); /* set the stdout to the out pipe */ |
---|
| 478 | si_close (2); si_dup2 (out_fd[1],2); /* set the stderr to the out pipe */ |
---|
[0e1846] | 479 | |
---|
| 480 | execvp (args[0], args); /* exec gdb */ |
---|
| 481 | perror ("exec failed"); |
---|
[0fa9018] | 482 | m2_end(999); |
---|
[0e1846] | 483 | } |
---|
| 484 | else if (pid == -1) |
---|
| 485 | { |
---|
| 486 | perror ("could not fork"); |
---|
[0fa9018] | 487 | m2_end(999); |
---|
[0e1846] | 488 | } |
---|
| 489 | |
---|
| 490 | FD_ZERO (&fdset); |
---|
| 491 | FD_SET (out_fd[0], &fdset); |
---|
| 492 | |
---|
[bdda8c2] | 493 | si_write (in_fd[1], "backtrace\n", 10); |
---|
| 494 | si_write (in_fd[1], "p si_stop_stack_trace_x = 0\n", 28); |
---|
| 495 | si_write (in_fd[1], "quit\n", 5); |
---|
[0e1846] | 496 | |
---|
| 497 | index = 0; |
---|
| 498 | state = 0; |
---|
| 499 | |
---|
| 500 | loop |
---|
| 501 | { |
---|
| 502 | readset = fdset; |
---|
| 503 | tv.tv_sec = 1; |
---|
| 504 | tv.tv_usec = 0; |
---|
| 505 | |
---|
[bdda8c2] | 506 | sel = si_select (FD_SETSIZE, &readset, NULL, NULL, &tv); |
---|
[0e1846] | 507 | if (sel == -1) |
---|
| 508 | break; |
---|
| 509 | |
---|
| 510 | if ((sel > 0) && (FD_ISSET (out_fd[0], &readset))) |
---|
| 511 | { |
---|
[bdda8c2] | 512 | if (si_read (out_fd[0], &c, 1)) |
---|
[0e1846] | 513 | { |
---|
| 514 | switch (state) |
---|
| 515 | { |
---|
| 516 | case 0: |
---|
| 517 | if (c == '#') |
---|
| 518 | { |
---|
| 519 | state = 1; |
---|
| 520 | index = 0; |
---|
| 521 | buffer[index++] = c; |
---|
| 522 | } |
---|
| 523 | break; |
---|
| 524 | case 1: |
---|
| 525 | buffer[index++] = c; |
---|
| 526 | if ((c == '\n') || (c == '\r')) |
---|
| 527 | { |
---|
| 528 | buffer[index] = 0; |
---|
[73481b] | 529 | fputs (buffer,stderr); |
---|
[0e1846] | 530 | state = 0; |
---|
| 531 | index = 0; |
---|
| 532 | } |
---|
| 533 | break; |
---|
| 534 | default: |
---|
| 535 | break; |
---|
| 536 | } |
---|
| 537 | } |
---|
| 538 | } |
---|
[ccae2f] | 539 | else if (si_stop_stack_trace_x==0) |
---|
[0e1846] | 540 | break; |
---|
| 541 | } |
---|
| 542 | |
---|
[bdda8c2] | 543 | si_close (in_fd[0]); |
---|
| 544 | si_close (in_fd[1]); |
---|
| 545 | si_close (out_fd[0]); |
---|
| 546 | si_close (out_fd[1]); |
---|
[0fa9018] | 547 | m2_end(0); |
---|
[0e1846] | 548 | } |
---|
| 549 | |
---|
[d5bd816] | 550 | # endif /* !__OPTIMIZE__ */ |
---|
[dc0898] | 551 | |
---|
[751785e] | 552 | /*2 |
---|
| 553 | * init signal handlers |
---|
| 554 | */ |
---|
| 555 | void init_signals() |
---|
| 556 | { |
---|
[60596c] | 557 | #ifdef SIGSEGV |
---|
[751785e] | 558 | si_set_signal(SIGSEGV,(si_hdl_typ)sigsegv_handler); |
---|
[60596c] | 559 | #endif |
---|
| 560 | #ifdef SIGBUS |
---|
| 561 | si_set_signal(SIGBUS, (si_hdl_typ)sigsegv_handler); |
---|
| 562 | #endif |
---|
| 563 | #ifdef SIGFPE |
---|
[751785e] | 564 | si_set_signal(SIGFPE, (si_hdl_typ)sigsegv_handler); |
---|
[60596c] | 565 | #endif |
---|
| 566 | #ifdef SIGILL |
---|
[751785e] | 567 | si_set_signal(SIGILL, (si_hdl_typ)sigsegv_handler); |
---|
[60596c] | 568 | #endif |
---|
| 569 | #ifdef SIGIOT |
---|
[751785e] | 570 | si_set_signal(SIGIOT, (si_hdl_typ)sigsegv_handler); |
---|
[60596c] | 571 | #endif |
---|
[751785e] | 572 | si_set_signal(SIGINT ,(si_hdl_typ)sigint_handler); |
---|
| 573 | si_set_signal(SIGCHLD, (si_hdl_typ)sig_chld_hdl); |
---|
| 574 | si_set_signal(SIGPIPE, (si_hdl_typ)sig_pipe_hdl); |
---|
| 575 | si_set_signal(SIGTERM, (si_hdl_typ)sig_term_hdl); |
---|
[dc0898] | 576 | } |
---|
[751785e] | 577 | |
---|