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:
379Attaching 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
381There 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}
#define NULL
Definition: auxiliary.h:104
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
fq_nmod_t buf
Definition: facHensel.cc:101
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

◆ 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(both_non_zero==0)
Definition: cfEzgcd.cc:91
#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{
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':
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",
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.