source: git/Singular/cntrlc.cc @ b60fb4

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