source: git/Singular/cntrlc.cc @ 35aab3

spielwiese
Last change on this file since 35aab3 was 502ea2, checked in by Hans Schönemann <hannes@…>, 22 years ago
*hannes: DecAlpha-OSF1 git-svn-id: file:///usr/local/Singular/svn/trunk@5869 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: cntrlc.cc,v 1.40 2002-02-14 15:08:52 Singular Exp $ */
5/*
6* ABSTRACT - interupt handling
7*/
8
9/* includes */
10#ifdef DecAlpha_OSF1
11#define _XOPEN_SOURCE_EXTENDED
12#endif
13#include <stdio.h>
14#include <stddef.h>
15#include <stdlib.h>
16#include <strings.h>
17#include <signal.h>
18#include "mod2.h"
19#include "omalloc.h"
20#include "tok.h"
21#include "ipshell.h"
22#include "febase.h"
23#include "cntrlc.h"
24#include "polys.h"
25#include "feOpt.h"
26#include "version.h"
27#ifdef PAGE_TEST
28#include "page.h"
29#endif
30
31
32/* undef, if you don't want GDB to come up on error */
33
34#if !defined(__alpha)
35#define CALL_GDB
36#endif
37
38#if defined(__OPTIMIZE__) && defined(CALL_GDB)
39#undef CALL_GDB
40#endif
41
42#ifdef unix
43#ifndef hpux
44#include <unistd.h>
45#include <sys/types.h>
46
47#ifdef TIME_WITH_SYS_TIME
48# include <time.h>
49# ifdef HAVE_SYS_TIME_H
50#   include <sys/time.h>
51# endif
52#else
53# ifdef HAVE_SYS_TIME_H
54#   include <sys/time.h>
55# else
56#   include <time.h>
57# endif
58#endif
59#ifdef HAVE_SYS_TIMES_H
60#include <sys/times.h>
61#endif
62
63#define INTERACTIVE 0
64#define STACK_TRACE 1
65#ifdef CALL_GDB
66static void debug (int);
67static void debug_stop (char **);
68#endif
69#ifndef __OPTIMIZE__
70static void stack_trace (char **);
71static void stack_trace_sigchld (int);
72#endif
73#endif
74#endif
75
76/* data */
77jmp_buf si_start_jmpbuf;
78int siRandomStart;
79short si_restart=0;
80BOOLEAN siCntrlc = FALSE;
81
82typedef void (*si_hdl_typ)(int);
83
84/*0 implementation*/
85#ifndef MSDOS
86/* signals are not implemented in DJGCC */
87#ifndef macintosh
88/* signals are not right implemented in macintosh */
89void sigint_handler(int sig);
90#endif
91#endif
92
93#if defined(linux) && defined(__i386__)
94#if defined(HAVE_SIGCONTEXT) || defined(HAVE_ASM_SIGCONTEXT_H)
95#include <asm/sigcontext.h>
96#else
97struct sigcontext_struct {
98        unsigned short gs, __gsh;
99        unsigned short fs, __fsh;
100        unsigned short es, __esh;
101        unsigned short ds, __dsh;
102        unsigned long edi;
103        unsigned long esi;
104        unsigned long ebp;
105        unsigned long esp;
106        unsigned long ebx;
107        unsigned long edx;
108        unsigned long ecx;
109        unsigned long eax;
110        unsigned long trapno;
111        unsigned long err;
112        unsigned long eip;
113        unsigned short cs, __csh;
114        unsigned long eflags;
115        unsigned long esp_at_signal;
116        unsigned short ss, __ssh;
117        unsigned long i387;
118        unsigned long oldmask;
119        unsigned long cr2;
120};
121#endif
122typedef struct sigcontext_struct sigcontext;
123
124/*2
125* signal handler for run time errors, linux/i386 version
126*/
127void sigsegv_handler(int sig, sigcontext s)
128{
129  fprintf(stderr,"Singular : signal %d (v: %d/%u):\n",sig,SINGULAR_VERSION,feVersionId);
130  if (sig!=SIGINT)
131  {
132    fprintf(stderr,"Segment fault/Bus error occurred at %x because of %x (r:%d)\n"
133                   "please inform the authors\n",
134                   (int)s.eip,(int)s.cr2,siRandomStart);
135  }
136#ifdef __OPTIMIZE__
137  if(si_restart<3)
138  {
139    si_restart++;
140    fprintf(stderr,"trying to restart...\n");
141    init_signals();
142    longjmp(si_start_jmpbuf,1);
143  }
144#endif
145#ifdef CALL_GDB
146  if (sig!=SIGINT) debug(INTERACTIVE);
147#endif
148  exit(0);
149}
150
151#ifdef PAGE_TEST
152#ifndef PAGE_INTERRUPT_TIME
153#define PAGE_INTERRUPT_TIME 1
154#endif
155void sig11_handler(int sig, sigcontext s)
156{
157  unsigned long base =(unsigned long)(s.cr2&(~4095));
158  int i;
159  i=mmPage_tab_ind-1;
160  while (mmPage_tab[i]!=base) i--;
161  mmUse_tab[i]='1';
162  mmPage_tab_acc++;
163  mmPage_AllowAccess((void *)base);
164  signal(SIGSEGV,(si_hdl_typ)sig11_handler);
165}
166
167void sigalarm_handler(int sig, sigcontext s)
168{
169  int i=mmPage_tab_ind-1;
170  mmWriteStat();
171  for(;i>=0;i--)
172  {
173    mmPage_DenyAccess((void *)mmPage_tab[i]);
174  }
175  struct itimerval t,o;
176  memset(&t,0,sizeof(t));
177  t.it_value.tv_sec     =(unsigned)0;
178  t.it_value.tv_usec    =(unsigned) PAGE_INTERRUPT_TIME;
179  o.it_value.tv_sec     =(unsigned)0;
180  o.it_value.tv_usec    =(unsigned)PAGE_INTERRUPT_TIME;
181  setitimer(ITIMER_VIRTUAL,&t,&o);
182  signal(SIGVTALRM,(si_hdl_typ)sigalarm_handler);
183}
184#endif
185
186/*2
187* init signal handlers, linux/i386 version
188*/
189void init_signals()
190{
191/*4 signal handler: linux*/
192#ifdef PAGE_TEST
193  signal(SIGSEGV,(si_hdl_typ)sig11_handler);
194  struct itimerval t,o;
195  memset(&t,0,sizeof(t));
196  t.it_value.tv_sec     =(unsigned)0;
197  t.it_value.tv_usec    =(unsigned)PAGE_INTERRUPT_TIME;
198  o.it_value.tv_sec     =(unsigned)0;
199  o.it_value.tv_usec    =(unsigned)PAGE_INTERRUPT_TIME;
200  setitimer(ITIMER_VIRTUAL,&t,&o);
201  signal(SIGVTALRM,(si_hdl_typ)sigalarm_handler);
202#else
203  if (SIG_ERR==signal(SIGSEGV,(si_hdl_typ)sigsegv_handler))
204  {
205    PrintS("cannot set signal handler for SEGV\n");
206  }
207#endif
208  if (SIG_ERR==signal(SIGFPE, (si_hdl_typ)sigsegv_handler))
209  {
210    PrintS("cannot set signal handler for FPE\n");
211  }
212  if (SIG_ERR==signal(SIGILL, (si_hdl_typ)sigsegv_handler))
213  {
214    PrintS("cannot set signal handler for ILL\n");
215  }
216  if (SIG_ERR==signal(SIGIOT, (si_hdl_typ)sigsegv_handler))
217  {
218    PrintS("cannot set signal handler for IOT\n");
219  }
220#ifndef macintosh
221  if (SIG_ERR==signal(SIGINT ,sigint_handler))
222  {
223    PrintS("cannot set signal handler for INT\n");
224  }
225  signal(SIGCHLD, (void (*)(int))SIG_IGN);
226#endif
227}
228
229#else
230#ifdef SPARC_SUNOS_4
231/*2
232* signal handler for run time errors, sparc sunos 4 version
233*/
234void sigsegv_handler(int sig, int code, struct sigcontext *scp, char *addr)
235{
236  fprintf(stderr,"Singular : signal %d, code %d (v: %d/%u):\n",
237    sig,code,SINGULAR_VERSION,feVersionId);
238  if ((sig!=SIGINT)&&(sig!=SIGABRT))
239  {
240    fprintf(stderr,"Segment fault/Bus error occurred at %x (r:%d)\n"
241                   "please inform the authors\n",
242                   (int)addr,siRandomStart);
243  }
244#ifdef __OPTIMIZE__
245  if(si_restart<3)
246  {
247    si_restart++;
248    fprintf(stderr,"trying to restart...\n");
249    init_signals();
250    longjmp(si_start_jmpbuf,1);
251  }
252#endif
253#ifdef CALL_GDB
254  if (sig!=SIGINT) debug(STACK_TRACE);
255#endif
256  exit(0);
257}
258
259/*2
260* init signal handlers, sparc sunos 4 version
261*/
262void init_signals()
263{
264/*4 signal handler:*/
265  signal(SIGSEGV,sigsegv_handler);
266  signal(SIGBUS, sigsegv_handler);
267  signal(SIGFPE, sigsegv_handler);
268  signal(SIGILL, sigsegv_handler);
269  signal(SIGIOT, sigsegv_handler);
270  signal(SIGINT ,sigint_handler);
271  signal(SIGCHLD, (void (*)(int))SIG_IGN);
272}
273#else
274
275/*2
276* signal handler for run time errors, general version
277*/
278#ifndef macintosh
279void sigsegv_handler(int sig)
280{
281  fprintf(stderr,"Singular : signal %d (v: %d/%u):\n",
282    sig,SINGULAR_VERSION,feVersionId);
283  if (sig!=SIGINT)
284  {
285    fprintf(stderr,"Segment fault/Bus error occurred (r:%d)\n"
286                   "please inform the authors\n",
287                   siRandomStart);
288  }
289#ifdef __OPTIMIZE__
290  if(si_restart<3)
291  {
292    si_restart++;
293    fprintf(stderr,"trying to restart...\n");
294    init_signals();
295    longjmp(si_start_jmpbuf,1);
296  }
297#endif
298#ifdef unix
299#ifndef hpux
300/* debug(..) does not work under HPUX (because ptrace does not work..) */
301#ifdef CALL_GDB
302#ifndef MSDOS
303  if (sig!=SIGINT) debug(STACK_TRACE);
304#endif
305#endif
306#endif
307#endif
308  exit(0);
309}
310#endif
311
312/*2
313* init signal handlers, general version
314*/
315void init_signals()
316{
317#ifndef MSDOS
318/* signals are not implemented in DJGCC */
319#ifndef macintosh
320/* signals are temporaliy removed for macs. */
321/*4 signal handler:*/
322  signal(SIGSEGV,(void (*) (int))sigsegv_handler);
323#ifdef SIGBUS
324  signal(SIGBUS, sigsegv_handler);
325#endif
326#ifdef SIGFPE
327  signal(SIGFPE, sigsegv_handler);
328#endif
329#ifdef SIGILL
330  signal(SIGILL, sigsegv_handler);
331#endif
332#ifdef SIGIOT
333  signal(SIGIOT, sigsegv_handler);
334#endif
335#ifdef SIGXCPU
336  signal(SIGXCPU, (void (*)(int))SIG_IGN);
337#endif
338  signal(SIGINT ,sigint_handler);
339  signal(SIGCHLD, (void (*)(int))SIG_IGN);
340#endif
341#endif
342}
343#endif
344#endif
345
346#ifndef MSDOS
347#ifndef macintosh
348/*2
349* signal handler for SIGINT
350*/
351void sigint_handler(int sig)
352{
353  mflush();
354  #ifdef HAVE_FEREAD
355  if (fe_is_raw_tty) fe_temp_reset();
356  #endif
357  loop
358  {
359    int cnt=0;
360    int c;
361    fprintf(stderr,"// ** Interrupt at cmd:`%s` in line:'%s'\n",
362      Tok2Cmdname(iiOp),my_yylinebuf);
363    if (feGetOptValue(FE_OPT_EMACS) == NULL)
364    {
365      fputs("abort command(a), continue(c) or quit Singular(q) ?",stderr);fflush(stderr);
366      c = fgetc(stdin);
367    }
368    else
369    {
370      c = 'a';
371    }
372   
373    switch(c)
374    {
375#if defined(MONOM_COUNT) || defined(DIV_COUNT)
376              case 'e':
377#ifdef MONOM_COUNT
378                extern void ResetMonomCount();
379                ResetMonomCount();
380#endif
381#ifdef DIV_COUNT
382                extern void ResetDivCount();
383                ResetDivCount();
384#endif
385                break;
386              case 'o':
387#ifdef MONOM_COUNT
388                extern void OutputMonomCount();
389                OutputMonomCount();
390#endif
391#ifdef DIV_COUNT
392                extern void OutputDivCount();
393                OutputDivCount();
394#endif
395                break;
396#endif // defined(MONOM_COUNT) || defined(DIV_COUNT)
397      case 'q':
398                m2_end(2);
399      case 'r':
400                longjmp(si_start_jmpbuf,1);
401      case 'b':
402                VoiceBackTrack();
403                break;
404      case 'a':
405                siCntrlc++;
406      case 'c':
407                if (feGetOptValue(FE_OPT_EMACS) == NULL) fgetc(stdin);
408                signal(SIGINT ,(si_hdl_typ)sigint_handler);
409                return;
410                //siCntrlc ++;
411                //if (siCntrlc>2) signal(SIGINT,(si_hdl_typ) sigsegv_handler);
412                //else            signal(SIGINT,(si_hdl_typ) sigint_handler);
413    }
414    cnt++;
415    if(cnt>5) m2_end(2);
416  }
417}
418#endif
419#endif
420
421//#ifdef macintosh
422//#include <Types.h>
423//#include <Events.h>
424//#include <OSEvents.h>
425//#include <CursorCtl.h>
426//
427///*3
428//* macintosh only:
429//* side effect of ^C is to insert EOF at the end of the current
430//* input selection. We must drain input, reach this EOF, then clear it
431//*/
432//static void flush_intr(void)
433//{
434//  int c;
435//
436//  while ((c=getchar())!=EOF);
437//  clearerr(stdin);
438//}
439//
440///*3
441//* macintosh only:
442//* spin beach ball in MPW, allows MPW-tool to go to the background
443//* so you can use the finder and interrupts
444//*/
445//static void beachball(void)
446//{
447//  Show_Cursor(HIDDEN_CURSOR);
448//  SpinCursor(10);
449//}
450//#endif
451
452#ifndef MSDOS
453//void test_int()
454//{
455//#ifndef macintosh
456//  if (siCntrlc!=0)
457//  {
458//    int saveecho = si_echo;
459//    siCntrlc = FALSE;
460//    signal(SIGINT ,sigint_handler);
461////#ifdef macintosh
462////    flush_intr();
463////#endif
464//    iiDebug();
465//    si_echo = saveecho;
466//  }
467//#endif
468//}
469#endif
470
471#ifdef unix
472#ifndef hpux
473#ifndef __OPTIMIZE__
474#ifndef MSDOS
475int si_stop_stack_trace_x;
476#ifdef CALL_GDB
477static void debug (int method)
478{
479  if (feOptValue(FE_OPT_NO_TTY))
480  {
481    dReportError("Caught Signal 11");
482    return;
483  }
484  int pid;
485  char buf[16];
486  char *args[4] = { "gdb", "Singularg", NULL, NULL };
487
488  #ifdef HAVE_FEREAD
489  if (fe_is_raw_tty) fe_temp_reset();
490  #endif
491
492  sprintf (buf, "%d", getpid ());
493
494  args[2] = buf;
495
496  pid = fork ();
497  if (pid == 0)
498  {
499    switch (method)
500    {
501      case INTERACTIVE:
502        fprintf (stderr, "debug_stop\n");
503        debug_stop (args);
504        break;
505      case STACK_TRACE:
506        fprintf (stderr, "stack_trace\n");
507        stack_trace (args);
508        break;
509    }
510  }
511  else if (pid == -1)
512  {
513    perror ("could not fork");
514    return;
515  }
516
517  si_stop_stack_trace_x = 1;
518  while (si_stop_stack_trace_x) ;
519}
520
521static void debug_stop ( char **args)
522{
523  execvp (args[0], args);
524  perror ("exec failed");
525  _exit (0);
526}
527#endif
528
529static int stack_trace_done;
530
531static void stack_trace (char **args)
532{
533  int pid;
534  int in_fd[2];
535  int out_fd[2];
536  fd_set fdset;
537  fd_set readset;
538  struct timeval tv;
539  int sel, index, state;
540  char buffer[256];
541  char c;
542
543  stack_trace_done = 0;
544
545  signal (SIGCHLD, stack_trace_sigchld);
546
547  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
548  {
549    perror ("could open pipe");
550    m2_end(999);
551  }
552
553  pid = fork ();
554  if (pid == 0)
555  {
556    close (0); dup2 (in_fd[0],0);   /* set the stdin to the in pipe */
557    close (1); dup2 (out_fd[1],1);  /* set the stdout to the out pipe */
558    close (2); dup2 (out_fd[1],2);  /* set the stderr to the out pipe */
559
560    execvp (args[0], args);      /* exec gdb */
561    perror ("exec failed");
562    m2_end(999);
563  }
564  else if (pid == -1)
565  {
566    perror ("could not fork");
567    m2_end(999);
568  }
569
570  FD_ZERO (&fdset);
571  FD_SET (out_fd[0], &fdset);
572
573  write (in_fd[1], "backtrace\n", 10);
574  write (in_fd[1], "p si_stop_stack_trace_x = 0\n", 28);
575  write (in_fd[1], "quit\n", 5);
576
577  index = 0;
578  state = 0;
579
580  loop
581  {
582    readset = fdset;
583    tv.tv_sec = 1;
584    tv.tv_usec = 0;
585
586#ifdef hpux
587    sel = select (FD_SETSIZE, (int *)readset.fds_bits, NULL, NULL, &tv);
588#else
589    sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
590#endif
591    if (sel == -1)
592      break;
593
594    if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
595    {
596      if (read (out_fd[0], &c, 1))
597      {
598        switch (state)
599        {
600          case 0:
601            if (c == '#')
602            {
603              state = 1;
604              index = 0;
605              buffer[index++] = c;
606            }
607            break;
608          case 1:
609            buffer[index++] = c;
610            if ((c == '\n') || (c == '\r'))
611            {
612              buffer[index] = 0;
613              fprintf (stderr, "%s", buffer);
614              state = 0;
615              index = 0;
616            }
617            break;
618          default:
619            break;
620        }
621      }
622    }
623    else if (stack_trace_done)
624      break;
625  }
626
627  close (in_fd[0]);
628  close (in_fd[1]);
629  close (out_fd[0]);
630  close (out_fd[1]);
631  m2_end(0);
632}
633
634static void stack_trace_sigchld (int signum)
635{
636  stack_trace_done = 1;
637}
638
639#endif
640#endif
641#endif
642#endif
643
644/* Under HPUX 9, system(...) returns -1 if SIGCHLD does not equal
645   SIG_DFL. However, if it stays at SIG_DFL we get zombie processes
646   for terminated childs generated by fork. Therefors some special treatment
647   is necessary */
648#ifdef HPUX_9
649#undef system
650extern "C" {
651  int  hpux9_system(const char* call)
652  {
653    int ret;
654    signal(SIGCHLD, (void (*)(int))SIG_DFL);
655    ret = system(call);
656    signal(SIGCHLD, (void (*)(int))SIG_IGN);
657    return ret;
658  }
659}
660#endif /* HPUX_9 */
Note: See TracBrowser for help on using the repository browser.