Loading...
Searching...
No Matches
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 <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

## 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 | sig_term_hdl_child (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
void | sigsegv_handler (int sig)
void | init_signals ()
| init signal handlers and error handling for libraries: NTL, factory
void | si_set_signals ()
void | si_reset_signals ()

## 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
VAR si_hdl_typ | si_sig_chld_hdl
VAR si_hdl_typ | old_sig_chld_hdl
VAR si_hdl_typ | si_sig_term_hdl

## Macro Definition Documentation

## _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 9 of file cntrlc.cc.

## CALL_GDB

#define CALL_GDB

Definition at line 28 of file cntrlc.cc.

## INTERACTIVE

#define INTERACTIVE 0

Definition at line 50 of file cntrlc.cc.

## STACK_TRACE

#define STACK_TRACE 1

Definition at line 51 of file cntrlc.cc.

## Function Documentation

## debug()

void debug | ( | int | method | ) |

static

Definition at line 366 of file cntrlc.cc.

{
if (feOptValue(FE_OPT_NO_TTY))
{
dReportError("Caught Signal 11");
return;
}
/* REMARK FOR NEWER LINUX SYSTEMS:
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)
There are ways to workaround this:
Run the following command as super user: echo 0| sudo tee /proc/sys/kernel/yama/ptrace_scope
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.
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
*/
int pid;
char buf[16];
char * args[4] = { (char*)"gdb", (char*)"Singular", NULL, NULL };
#ifdef HAVE_FEREAD
if (fe_is_raw_tty) fe_temp_reset();
#endif /* HAVE_FEREAD */
snprintf (buf, 16, "%d", getpid ());
args[2] = buf;
pid = fork ();
if (pid == 0)
{
switch (method)
{
case INTERACTIVE:
fputs ("\n\nquit with \"p si_stop_stack_trace_x=0\"\n\n\n",stderr);
debug_stop (args);
break;
case STACK_TRACE:
fputs ("stack_trace\n",stderr);
stack_trace (args);
break;
default:
// should not be reached:
exit(1);
}
}
else if (pid == -1)
{
perror ("could not fork");
return;
}
si_stop_stack_trace_x = 1;
while (si_stop_stack_trace_x) ;
}
stack_trace
static void stack_trace(char *const *args)
Definition cntrlc.cc:432
si_stop_stack_trace_x
VAR volatile int si_stop_stack_trace_x
Definition cntrlc.cc:364
INTERACTIVE
#define INTERACTIVE
Definition cntrlc.cc:50
STACK_TRACE
#define STACK_TRACE
Definition cntrlc.cc:51
debug_stop
static void debug_stop(char *const *args)
Definition cntrlc.cc:424
feOptValue
static void * feOptValue(feOptIndex opt)
Definition feOpt.h:40
fe_is_raw_tty
VAR BOOLEAN fe_is_raw_tty
Definition fereadl.c:72
fe_temp_reset
void fe_temp_reset(void)
Definition fereadl.c:110
dReportError
int dReportError(const char *fmt,...)
Definition dError.cc:44
NULL
#define NULL
Definition omList.c:12
buf
int status int void * buf
Definition si_signals.h:69

## debug_stop()

void debug_stop | ( | char *const * | args | ) |

static

Definition at line 424 of file cntrlc.cc.

{
execvp (args[0], args);
perror ("exec failed");
_exit (0);
}

## init_signals()

void init_signals | ( | void |  | ) |

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

Definition at line 530 of file cntrlc.cc.

{
// signal handler -------------------------------------------------------
#ifdef SIGSEGV
si_set_signal(SIGSEGV,(si_hdl_typ)sigsegv_handler);
#endif
#ifdef SIGBUS
si_set_signal(SIGBUS, (si_hdl_typ)sigsegv_handler);
#endif
#ifdef SIGFPE
si_set_signal(SIGFPE, (si_hdl_typ)sigsegv_handler);
#endif
#ifdef SIGILL
si_set_signal(SIGILL, (si_hdl_typ)sigsegv_handler);
#endif
#ifdef SIGIOT
si_set_signal(SIGIOT, (si_hdl_typ)sigsegv_handler);
#endif
si_set_signal(SIGINT ,(si_hdl_typ)sigint_handler);
si_set_signal(SIGCHLD, (si_hdl_typ)sig_chld_hdl);
si_set_signal(SIGPIPE, (si_hdl_typ)sig_pipe_hdl);
si_set_signal(SIGTERM, (si_hdl_typ)sig_term_hdl);
}
sig_pipe_hdl
void sig_pipe_hdl(int)
Definition cntrlc.cc:64
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
Definition cntrlc.cc:121
sig_term_hdl
void sig_term_hdl(int)
Definition cntrlc.cc:77
sigint_handler
void sigint_handler(int)
Definition cntrlc.cc:269
sigsegv_handler
void sigsegv_handler(int sig)
Definition cntrlc.cc:237
si_hdl_typ
void(* si_hdl_typ)(int)
Definition cntrlc.h:30
sig_chld_hdl
void sig_chld_hdl(int)
additional default signal handler
Definition ssiLink.cc:3265

## si_reset_signals()

void si_reset_signals | ( |  | ) |

Definition at line 568 of file cntrlc.cc.

{
// signal handler -------------------------------------------------------
//si_set_signal(SIGINT ,si_sigint_handler);
si_set_signal(SIGCHLD, old_sig_chld_hdl);
//si_set_signal(SIGPIPE, si_sig_pipe_hdl);
si_set_signal(SIGTERM, si_sig_term_hdl);
}
si_sig_term_hdl
VAR si_hdl_typ si_sig_term_hdl
Definition cntrlc.cc:558
old_sig_chld_hdl
VAR si_hdl_typ old_sig_chld_hdl
Definition cntrlc.cc:556

## 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] | sig | Signal number
  [in] | signal_handler | Pointer to signal handler

Returns
  value of signal()

Definition at line 121 of file cntrlc.cc.

{
#if 0
si_hdl_typ retval=signal (sig, (si_hdl_typ)signal_handler);
if (retval == SIG_ERR)
{
fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig);
}
si_siginterrupt(sig, 0);
/*system calls will be restarted if interrupted by the specified
* signal sig. This is the default behavior in Linux.
*/
#else
struct sigaction new_action,old_action;
memset(&new_action, 0, sizeof(struct sigaction));
/* Set up the structure to specify the new action. */
new_action.sa_handler = signal_handler;
if (sig==SIGINT)
sigemptyset (&new_action.sa_mask);
else
new_action.sa_flags = SA_RESTART /*| SA_NOCLDWAIT*/;
int r=si_sigaction (sig, &new_action, &old_action);
si_hdl_typ retval=(si_hdl_typ)old_action.sa_handler;
if (r == -1)
{
fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig);
retval=SIG_ERR;
}
#endif
return retval;
} /* si_set_signal */
si_siginterrupt
#define si_siginterrupt(arg1, arg2)

## si_set_signals()

void si_set_signals | ( |  | ) |

Definition at line 560 of file cntrlc.cc.

{
//si_sigint_handler=si_set_signal(SIGINT ,(si_hdl_typ)sigint_handler);
old_sig_chld_hdl=si_sig_chld_hdl=si_set_signal(SIGCHLD, (si_hdl_typ)sig_chld_hdl);
//si_sig_pipe_hdl=si_set_signal(SIGPIPE, (si_hdl_typ)sig_pipe_hdl);
si_sig_term_hdl=si_set_signal(SIGTERM, (si_hdl_typ)sig_term_hdl);
}
si_sig_chld_hdl
VAR si_hdl_typ si_sig_chld_hdl
Definition cntrlc.cc:555

## sig_pipe_hdl()

void sig_pipe_hdl | ( | int |  | ) |

Definition at line 64 of file cntrlc.cc.

{
if (pipeLastLink!=NULL)
{
slClose(pipeLastLink);
pipeLastLink=NULL;
WerrorS("pipe failed");
}
}
pipeLastLink
VAR si_link pipeLastLink
Definition cntrlc.cc:61
WerrorS
void WerrorS(const char *s)
Definition feFopen.cc:24
slClose
BOOLEAN slClose(si_link l)
Definition silink.cc:240

## sig_term_hdl()

void sig_term_hdl | ( | int |  | ) |

Definition at line 77 of file cntrlc.cc.

{
do_shutdown = TRUE;
if (!defer_shutdown)
{
m2_end(-1);
}
}
TRUE
#define TRUE
Definition auxiliary.h:101
do_shutdown
VAR volatile BOOLEAN do_shutdown
Definition cntrlc.cc:74
defer_shutdown
VAR volatile int defer_shutdown
Definition cntrlc.cc:75
m2_end
void m2_end(int i)
Definition misc_ip.cc:1104

## sig_term_hdl_child()

void sig_term_hdl_child | ( | int |  | ) |

Definition at line 86 of file cntrlc.cc.

{
_exit(0);
}

## sigint_handler()

void sigint_handler | ( | int |  | ) |

Definition at line 269 of file cntrlc.cc.

{
mflush();
#ifdef HAVE_FEREAD
if (fe_is_raw_tty) fe_temp_reset();
#endif /* HAVE_FEREAD */
char default_opt=' ';
if ((feOptSpec[FE_OPT_CNTRLC].value!=NULL)
&& ((char*)(feOptSpec[FE_OPT_CNTRLC].value))[0])
{ default_opt=((char*)(feOptSpec[FE_OPT_CNTRLC].value))[0]; }
loop
{
int cnt=0;
int c;
if (singular_in_batchmode)
{
c = 'q';
}
else if (default_opt!=' ')
{
c = default_opt;
}
else
{
fprintf(stderr,"// ** Interrupt at cmd:`%s` in line:'%s'\n",
Tok2Cmdname(iiOp),my_yylinebuf);
if (feOptValue(FE_OPT_EMACS) == NULL)
{
fputs("abort after this command(a), abort immediately(r), print backtrace(b), continue(c) or quit Singular(q) ?",stderr);
fflush(stderr);fflush(stdin);
c = fgetc(stdin);
}
else
{
c = 'a';
}
}
switch(c)
{
case 'q': case EOF:
m2_end(2);
case 'r':
if (sigint_handler_cnt<3)
{
sigint_handler_cnt++;
fputs("** Warning: Singular should be restarted as soon as possible **\n",stderr);
fflush(stderr);
extern void my_yy_flush();
my_yy_flush();
currentVoice=feInitStdin(NULL);
longjmp(si_start_jmpbuf,1);
}
else
{
fputs("** tried too often, try another possibility **\n",stderr);
fflush(stderr);
}
break;
case 'b':
VoiceBackTrack();
break;
case 'a':
siCntrlc++;
case 'c':
if ((feOptValue(FE_OPT_EMACS) == NULL) && (default_opt!=' '))
{
/* Read until a newline or EOF */
while (c != EOF && c != '\n') c = fgetc(stdin);
}
si_set_signal(SIGINT ,(si_hdl_typ)sigint_handler);
return;
//siCntrlc ++;
//if (siCntrlc>2) si_set_signal(SIGINT,(si_hdl_typ) sigsegv_handler);
//else si_set_signal(SIGINT,(si_hdl_typ) sigint_handler);
}
cnt++;
if(cnt>5) m2_end(2);
}
}
si_start_jmpbuf
VAR jmp_buf si_start_jmpbuf
Definition cntrlc.cc:98
singular_in_batchmode
VAR BOOLEAN singular_in_batchmode
Definition cntrlc.cc:62
sigint_handler_cnt
VAR int sigint_handler_cnt
Definition cntrlc.cc:268
feOptSpec
EXTERN_VAR struct fe_option feOptSpec[]
Definition feOpt.h:17
my_yylinebuf
VAR char my_yylinebuf[80]
Definition febase.cc:44
currentVoice
VAR Voice * currentVoice
Definition fevoices.cc:49
VoiceBackTrack
void VoiceBackTrack()
Definition fevoices.cc:77
feInitStdin
Voice * feInitStdin(Voice *pp)
Definition fevoices.cc:677
Tok2Cmdname
const char * Tok2Cmdname(int tok)
Definition gentable.cc:137
iiOp
VAR int iiOp
Definition iparith.cc:219
siCntrlc
VAR BOOLEAN siCntrlc
Definition options.c:14
mflush
#define mflush()
Definition reporter.h:58
my_yy_flush
void my_yy_flush()
Definition scanner.cc:2318
loop
#define loop
Definition structs.h:71

## sigsegv_handler()

void sigsegv_handler | ( | int | sig | ) |

Definition at line 237 of file cntrlc.cc.

{
fprintf(stderr,"Singular : signal %d (v: %d):\n",
sig,SINGULAR_VERSION);
if (sig!=SIGINT)
{
fprintf(stderr,"current line:>>%s<<\n",my_yylinebuf);
fprintf(stderr,"Segment fault/Bus error occurred (r:%d)\n"
"please inform the authors\n",
siRandomStart);
}
#ifdef __OPTIMIZE__
if(si_restart<3)
{
si_restart++;
fputs("trying to restart...\n",stderr);
init_signals();
longjmp(si_start_jmpbuf,1);
}
#endif /* __OPTIMIZE__ */
#ifdef CALL_GDB
if (sig!=SIGINT) debug(STACK_TRACE);
#endif /* CALL_GDB */
exit(0);
}
debug
static void debug(int)
Definition cntrlc.cc:366
si_restart
VAR short si_restart
Definition cntrlc.cc:100
siRandomStart
VAR int siRandomStart
Definition cntrlc.cc:99
init_signals
void init_signals()
init signal handlers and error handling for libraries: NTL, factory
Definition cntrlc.cc:530
SINGULAR_VERSION
#define SINGULAR_VERSION
Definition mod2.h:87

## stack_trace()

void stack_trace | ( | char *const * | args | ) |

static

Definition at line 432 of file cntrlc.cc.

{
int pid;
int in_fd[2];
int out_fd[2];
fd_set fdset;
fd_set readset;
struct timeval tv;
int sel, index, state;
char buffer[256];
char c;
if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
{
perror ("could open pipe");
m2_end(999);
}
pid = fork ();
if (pid == 0)
{
si_close (0); si_dup2 (in_fd[0],0); /* set the stdin to the in pipe */
si_close (1); si_dup2 (out_fd[1],1); /* set the stdout to the out pipe */
si_close (2); si_dup2 (out_fd[1],2); /* set the stderr to the out pipe */
execvp (args[0], args); /* exec gdb */
perror ("exec failed");
m2_end(999);
}
else if (pid == -1)
{
perror ("could not fork");
m2_end(999);
}
FD_ZERO (&fdset);
FD_SET (out_fd[0], &fdset);
si_write (in_fd[1], "backtrace\n", 10);
si_write (in_fd[1], "p si_stop_stack_trace_x = 0\n", 28);
si_write (in_fd[1], "quit\n", 5);
index = 0;
state = 0;
loop
{
readset = fdset;
tv.tv_sec = 1;
tv.tv_usec = 0;
sel = si_select (FD_SETSIZE, &readset, NULL, NULL, &tv);
if (sel == -1)
break;
if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
{
if (si_read (out_fd[0], &c, 1))
{
switch (state)
{
case 0:
if (c == '#')
{
state = 1;
index = 0;
buffer[index++] = c;
}
break;
case 1:
buffer[index++] = c;
if ((c == '\n') || (c == '\r'))
{
buffer[index] = 0;
fputs (buffer,stderr);
state = 0;
index = 0;
}
break;
default:
break;
}
}
}
else if (si_stop_stack_trace_x==0)
break;
}
si_close (in_fd[0]);
si_close (in_fd[1]);
si_close (out_fd[0]);
si_close (out_fd[1]);
m2_end(1);
}
index
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 75 of file cntrlc.cc.

## do_shutdown

VAR volatile BOOLEAN do_shutdown = FALSE

Definition at line 74 of file cntrlc.cc.

## old_sig_chld_hdl

VAR si_hdl_typ old_sig_chld_hdl

Definition at line 556 of file cntrlc.cc.

## pipeLastLink

VAR si_link pipeLastLink =NULL

Definition at line 61 of file cntrlc.cc.

## si_restart

VAR short si_restart =0

Definition at line 100 of file cntrlc.cc.

## si_sig_chld_hdl

VAR si_hdl_typ si_sig_chld_hdl

Definition at line 555 of file cntrlc.cc.

## si_sig_term_hdl

VAR si_hdl_typ si_sig_term_hdl

Definition at line 558 of file cntrlc.cc.

## si_start_jmpbuf

VAR jmp_buf si_start_jmpbuf

Definition at line 98 of file cntrlc.cc.

## si_stop_stack_trace_x

VAR volatile int si_stop_stack_trace_x

Definition at line 364 of file cntrlc.cc.

## sigint_handler_cnt

VAR int sigint_handler_cnt =0

Definition at line 268 of file cntrlc.cc.

## singular_in_batchmode

VAR BOOLEAN singular_in_batchmode =FALSE

Definition at line 62 of file cntrlc.cc.

## siRandomStart

VAR int siRandomStart

Definition at line 99 of file cntrlc.cc.