source: git/Singular/cntrlc.cc @ 18dd47

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