source: git/Singular/cntrlc.cc @ 66415e1

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