source: git/Singular/cntrlc.cc @ dc0025

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