My Project
Macros | Typedefs | Functions | Variables
cntrlc.cc File Reference
#include "kernel/mod2.h"
#include "reporter/si_signals.h"
#include "Singular/fevoices.h"
#include "misc/options.h"
#include "Singular/tok.h"
#include "Singular/ipshell.h"
#include "Singular/cntrlc.h"
#include "Singular/feOpt.h"
#include "Singular/misc_ip.h"
#include "Singular/links/silink.h"
#include "Singular/links/ssiLink.h"
#include <NTL/version.h>
#include <NTL/tools.h>
#include <time.h>
#include <sys/time.h>

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 
#define CALL_GDB
 
#define INTERACTIVE   0
 
#define STACK_TRACE   1
 

Typedefs

typedef void(* si_hdl_typ) (int)
 

Functions

static void debug (int)
 
static void debug_stop (char *const *args)
 
static void stack_trace (char *const *args)
 
void sig_pipe_hdl (int)
 
void sig_term_hdl (int)
 
void sigint_handler (int)
 
si_hdl_typ si_set_signal (int sig, si_hdl_typ signal_handler)
 meta function for binding a signal to an handler More...
 
void sigsegv_handler (int sig)
 
void init_signals ()
 init signal handlers and error handling for libraries: NTL, factory More...
 

Variables

VAR si_link pipeLastLink =NULL
 
VAR BOOLEAN singular_in_batchmode =FALSE
 
VAR volatile BOOLEAN do_shutdown = FALSE
 
VAR volatile int defer_shutdown = 0
 
VAR jmp_buf si_start_jmpbuf
 
VAR int siRandomStart
 
VAR short si_restart =0
 
VAR int sigint_handler_cnt =0
 
VAR volatile int si_stop_stack_trace_x
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 9 of file cntrlc.cc.

◆ CALL_GDB

#define CALL_GDB

Definition at line 36 of file cntrlc.cc.

◆ INTERACTIVE

#define INTERACTIVE   0

Definition at line 58 of file cntrlc.cc.

◆ STACK_TRACE

#define STACK_TRACE   1

Definition at line 59 of file cntrlc.cc.

Typedef Documentation

◆ si_hdl_typ

typedef void(* si_hdl_typ) (int)

Definition at line 104 of file cntrlc.cc.

Function Documentation

◆ debug()

static void debug ( int  method)
static

Definition at line 371 of file cntrlc.cc.

372 {
373  if (feOptValue(FE_OPT_NO_TTY))
374  {
375  dReportError("Caught Signal 11");
376  return;
377  }
378  /* REMARK FOR NEWER LINUX SYSTEMS:
379 Attaching to a process on Linux with GDB as a normal user may fail with "ptrace:Operation not permitted". By default Linux does not allow attaching to a process which wasn't launched by the debugger (see the Yama security documentation for more details). (https://www.kernel.org/doc/Documentation/security/Yama.txt)
380 
381 There are ways to workaround this:
382 
383  Run the following command as super user: echo 0| sudo tee /proc/sys/kernel/yama/ptrace_scope
384 
385  This will set the ptrace level to 0, after this just with user permissions you can attach to processes which are not launched by the debugger.
386 
387  On distributions without Yama (such as Raspbian) you can use libcap2-bin to assign ptrace permissions to specific executables: sudo setcap cap_sys_ptrace=eip /usr/bin/gdb
388 */
389  int pid;
390  char buf[16];
391  char * args[4] = { (char*)"gdb", (char*)"Singular", NULL, NULL };
392 
393  #ifdef HAVE_FEREAD
395  #endif /* HAVE_FEREAD */
396 
397  sprintf (buf, "%d", getpid ());
398 
399  args[2] = buf;
400 
401  pid = fork ();
402  if (pid == 0)
403  {
404  switch (method)
405  {
406  case INTERACTIVE:
407  fputs ("\n\nquit with \"p si_stop_stack_trace_x=0\"\n\n\n",stderr);
408  debug_stop (args);
409  break;
410  case STACK_TRACE:
411  fputs ("stack_trace\n",stderr);
412  stack_trace (args);
413  break;
414  default:
415  // should not be reached:
416  exit(1);
417  }
418  }
419  else if (pid == -1)
420  {
421  perror ("could not fork");
422  return;
423  }
424 
426  while (si_stop_stack_trace_x) ;
427 }
static void stack_trace(char *const *args)
Definition: cntrlc.cc:437
VAR volatile int si_stop_stack_trace_x
Definition: cntrlc.cc:369
#define INTERACTIVE
Definition: cntrlc.cc:58
#define STACK_TRACE
Definition: cntrlc.cc:59
static void debug_stop(char *const *args)
Definition: cntrlc.cc:429
static void * feOptValue(feOptIndex opt)
Definition: feOpt.h:40
VAR BOOLEAN fe_is_raw_tty
Definition: fereadl.c:71
void fe_temp_reset(void)
Definition: fereadl.c:109
int dReportError(const char *fmt,...)
Definition: dError.cc:43
#define NULL
Definition: omList.c:12
int status int void * buf
Definition: si_signals.h:59

◆ debug_stop()

static void debug_stop ( char *const args)
static

Definition at line 429 of file cntrlc.cc.

430 {
431  execvp (args[0], args);
432  perror ("exec failed");
433  _exit (0);
434 }

◆ init_signals()

void init_signals ( )

init signal handlers and error handling for libraries: NTL, factory

Definition at line 535 of file cntrlc.cc.

536 {
537 // NTL error handling (>= 9.3.0) ----------------------------------------
538 #ifdef HAVE_NTL
539 #if (((NTL_MAJOR_VERSION==9)&&(NTL_MINOR_VERSION>=3))||(NTL_MAJOR_VERSION>=10))
540  ErrorMsgCallback=WerrorS;
541  ErrorCallback=HALT;
542 #endif
543 #endif
544 
545 // signal handler -------------------------------------------------------
546  #ifdef SIGSEGV
548  #endif
549  #ifdef SIGBUS
551  #endif
552  #ifdef SIGFPE
554  #endif
555  #ifdef SIGILL
557  #endif
558  #ifdef SIGIOT
560  #endif
565 }
void sig_pipe_hdl(int)
Definition: cntrlc.cc:72
si_hdl_typ si_set_signal(int sig, si_hdl_typ signal_handler)
meta function for binding a signal to an handler
Definition: cntrlc.cc:126
void sig_term_hdl(int)
Definition: cntrlc.cc:85
void sigint_handler(int)
Definition: cntrlc.cc:274
void(* si_hdl_typ)(int)
Definition: cntrlc.cc:104
void sigsegv_handler(int sig)
Definition: cntrlc.cc:242
void WerrorS(const char *s)
Definition: feFopen.cc:24
static void HALT()
Definition: mod2.h:124

◆ si_set_signal()

si_hdl_typ si_set_signal ( int  sig,
si_hdl_typ  signal_handler 
)

meta function for binding a signal to an handler

Parameters
[in]sigSignal number
[in]signal_handlerPointer to signal handler
Returns
value of signal()

Definition at line 126 of file cntrlc.cc.

127 {
128 #if 0
129  si_hdl_typ retval=signal (sig, (si_hdl_typ)signal_handler);
130  if (retval == SIG_ERR)
131  {
132  fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig);
133  }
134  si_siginterrupt(sig, 0);
135  /*system calls will be restarted if interrupted by the specified
136  * signal sig. This is the default behavior in Linux.
137  */
138 #else
139  struct sigaction new_action,old_action;
140  memset(&new_action, 0, sizeof(struct sigaction));
141 
142  /* Set up the structure to specify the new action. */
143  new_action.sa_handler = signal_handler;
144  if (sig==SIGINT)
145  sigemptyset (&new_action.sa_mask);
146  else
147  new_action.sa_flags = SA_RESTART;
148 
149  int r=si_sigaction (sig, &new_action, &old_action);
150  si_hdl_typ retval=(si_hdl_typ)old_action.sa_handler;
151  if (r == -1)
152  {
153  fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig);
154  retval=SIG_ERR;
155  }
156 #endif
157  return retval;
158 } /* si_set_signal */
if(yy_init)
Definition: libparse.cc:1420
#define si_siginterrupt(arg1, arg2)

◆ sig_pipe_hdl()

void sig_pipe_hdl ( int  )

Definition at line 72 of file cntrlc.cc.

73 {
74  if (pipeLastLink!=NULL)
75  {
78  WerrorS("pipe failed");
79  }
80 }
VAR si_link pipeLastLink
Definition: cntrlc.cc:69

◆ sig_term_hdl()

void sig_term_hdl ( int  )

Definition at line 85 of file cntrlc.cc.

86 {
87  do_shutdown = TRUE;
88  if (!defer_shutdown)
89  {
90  m2_end(1);
91  }
92 }
#define TRUE
Definition: auxiliary.h:100
VAR volatile BOOLEAN do_shutdown
Definition: cntrlc.cc:82
VAR volatile int defer_shutdown
Definition: cntrlc.cc:83
void m2_end(int i)
Definition: misc_ip.cc:1096

◆ sigint_handler()

void sigint_handler ( int  )

Definition at line 274 of file cntrlc.cc.

275 {
276  mflush();
277  #ifdef HAVE_FEREAD
279  #endif /* HAVE_FEREAD */
280  char default_opt=' ';
281  if ((feOptSpec[FE_OPT_CNTRLC].value!=NULL)
282  && ((char*)(feOptSpec[FE_OPT_CNTRLC].value))[0])
283  { default_opt=((char*)(feOptSpec[FE_OPT_CNTRLC].value))[0]; }
284  loop
285  {
286  int cnt=0;
287  int c;
288 
290  {
291  c = 'q';
292  }
293  else if (default_opt!=' ')
294  {
295  c = default_opt;
296  }
297  else
298  {
299  fprintf(stderr,"// ** Interrupt at cmd:`%s` in line:'%s'\n",
301  if (feOptValue(FE_OPT_EMACS) == NULL)
302  {
303  fputs("abort after this command(a), abort immediately(r), print backtrace(b), continue(c) or quit Singular(q) ?",stderr);
304  fflush(stderr);fflush(stdin);
305  c = fgetc(stdin);
306  }
307  else
308  {
309  c = 'a';
310  }
311  }
312 
313  switch(c)
314  {
315  case 'q': case EOF:
316  m2_end(2);
317  case 'r':
318  if (sigint_handler_cnt<3)
319  {
321  fputs("** Warning: Singular should be restarted as soon as possible **\n",stderr);
322  fflush(stderr);
323  extern void my_yy_flush();
324  my_yy_flush();
326  longjmp(si_start_jmpbuf,1);
327  }
328  else
329  {
330  fputs("** tried too often, try another possibility **\n",stderr);
331  fflush(stderr);
332  }
333  break;
334  case 'b':
335  VoiceBackTrack();
336  break;
337  case 'a':
338  siCntrlc++;
339  case 'c':
340  if ((feOptValue(FE_OPT_EMACS) == NULL) && (default_opt!=' '))
341  {
342  /* Read until a newline or EOF */
343  while (c != EOF && c != '\n') c = fgetc(stdin);
344  }
346  return;
347  //siCntrlc ++;
348  //if (siCntrlc>2) si_set_signal(SIGINT,(si_hdl_typ) sigsegv_handler);
349  //else si_set_signal(SIGINT,(si_hdl_typ) sigint_handler);
350  }
351  cnt++;
352  if(cnt>5) m2_end(2);
353  }
354 }
VAR jmp_buf si_start_jmpbuf
Definition: cntrlc.cc:100
VAR BOOLEAN singular_in_batchmode
Definition: cntrlc.cc:70
VAR int sigint_handler_cnt
Definition: cntrlc.cc:273
EXTERN_VAR struct fe_option feOptSpec[]
Definition: feOpt.h:17
VAR char my_yylinebuf[80]
Definition: febase.cc:44
VAR Voice * currentVoice
Definition: fevoices.cc:47
void VoiceBackTrack()
Definition: fevoices.cc:75
Voice * feInitStdin(Voice *pp)
Definition: fevoices.cc:669
const char * Tok2Cmdname(int tok)
Definition: gentable.cc:140
VAR int iiOp
Definition: iparith.cc:219
VAR BOOLEAN siCntrlc
Definition: options.c:14
#define mflush()
Definition: reporter.h:58
void my_yy_flush()
Definition: scanner.cc:2338
#define loop
Definition: structs.h:80

◆ sigsegv_handler()

void sigsegv_handler ( int  sig)

Definition at line 242 of file cntrlc.cc.

243 {
244  fprintf(stderr,"Singular : signal %d (v: %d):\n",
245  sig,SINGULAR_VERSION);
246  if (sig!=SIGINT)
247  {
248  fprintf(stderr,"current line:>>%s<<\n",my_yylinebuf);
249  fprintf(stderr,"Segment fault/Bus error occurred (r:%d)\n"
250  "please inform the authors\n",
251  siRandomStart);
252  }
253  #ifdef __OPTIMIZE__
254  if(si_restart<3)
255  {
256  si_restart++;
257  fputs("trying to restart...\n",stderr);
258  init_signals();
259  longjmp(si_start_jmpbuf,1);
260  }
261  #endif /* __OPTIMIZE__ */
262  #ifdef CALL_GDB
263  if (sig!=SIGINT) debug(STACK_TRACE);
264  #endif /* CALL_GDB */
265  exit(0);
266 }
static void debug(int)
Definition: cntrlc.cc:371
VAR short si_restart
Definition: cntrlc.cc:102
VAR int siRandomStart
Definition: cntrlc.cc:101
void init_signals()
init signal handlers and error handling for libraries: NTL, factory
Definition: cntrlc.cc:535
#define SINGULAR_VERSION
Definition: mod2.h:85

◆ stack_trace()

static void stack_trace ( char *const args)
static

Definition at line 437 of file cntrlc.cc.

438 {
439  int pid;
440  int in_fd[2];
441  int out_fd[2];
442  fd_set fdset;
443  fd_set readset;
444  struct timeval tv;
445  int sel, index, state;
446  char buffer[256];
447  char c;
448 
449  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
450  {
451  perror ("could open pipe");
452  m2_end(999);
453  }
454 
455  pid = fork ();
456  if (pid == 0)
457  {
458  si_close (0); si_dup2 (in_fd[0],0); /* set the stdin to the in pipe */
459  si_close (1); si_dup2 (out_fd[1],1); /* set the stdout to the out pipe */
460  si_close (2); si_dup2 (out_fd[1],2); /* set the stderr to the out pipe */
461 
462  execvp (args[0], args); /* exec gdb */
463  perror ("exec failed");
464  m2_end(999);
465  }
466  else if (pid == -1)
467  {
468  perror ("could not fork");
469  m2_end(999);
470  }
471 
472  FD_ZERO (&fdset);
473  FD_SET (out_fd[0], &fdset);
474 
475  si_write (in_fd[1], "backtrace\n", 10);
476  si_write (in_fd[1], "p si_stop_stack_trace_x = 0\n", 28);
477  si_write (in_fd[1], "quit\n", 5);
478 
479  index = 0;
480  state = 0;
481 
482  loop
483  {
484  readset = fdset;
485  tv.tv_sec = 1;
486  tv.tv_usec = 0;
487 
488  sel = si_select (FD_SETSIZE, &readset, NULL, NULL, &tv);
489  if (sel == -1)
490  break;
491 
492  if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
493  {
494  if (si_read (out_fd[0], &c, 1))
495  {
496  switch (state)
497  {
498  case 0:
499  if (c == '#')
500  {
501  state = 1;
502  index = 0;
503  buffer[index++] = c;
504  }
505  break;
506  case 1:
507  buffer[index++] = c;
508  if ((c == '\n') || (c == '\r'))
509  {
510  buffer[index] = 0;
511  fputs (buffer,stderr);
512  state = 0;
513  index = 0;
514  }
515  break;
516  default:
517  break;
518  }
519  }
520  }
521  else if (si_stop_stack_trace_x==0)
522  break;
523  }
524 
525  si_close (in_fd[0]);
526  si_close (in_fd[1]);
527  si_close (out_fd[0]);
528  si_close (out_fd[1]);
529  m2_end(0);
530 }
static int index(p_Length length, p_Ord ord)
Definition: p_Procs_Impl.h:592

Variable Documentation

◆ defer_shutdown

VAR volatile int defer_shutdown = 0

Definition at line 83 of file cntrlc.cc.

◆ do_shutdown

VAR volatile BOOLEAN do_shutdown = FALSE

Definition at line 82 of file cntrlc.cc.

◆ pipeLastLink

VAR si_link pipeLastLink =NULL

Definition at line 69 of file cntrlc.cc.

◆ si_restart

VAR short si_restart =0

Definition at line 102 of file cntrlc.cc.

◆ si_start_jmpbuf

VAR jmp_buf si_start_jmpbuf

Definition at line 100 of file cntrlc.cc.

◆ si_stop_stack_trace_x

VAR volatile int si_stop_stack_trace_x

Definition at line 369 of file cntrlc.cc.

◆ sigint_handler_cnt

VAR int sigint_handler_cnt =0

Definition at line 273 of file cntrlc.cc.

◆ singular_in_batchmode

VAR BOOLEAN singular_in_batchmode =FALSE

Definition at line 70 of file cntrlc.cc.

◆ siRandomStart

VAR int siRandomStart

Definition at line 101 of file cntrlc.cc.