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

Typedef Documentation

◆ si_hdl_typ

typedef void(* si_hdl_typ) (int)

Definition at line 96 of file cntrlc.cc.

Function Documentation

◆ debug()

static void debug ( int  method)
static

Definition at line 363 of file cntrlc.cc.

364{
365 if (feOptValue(FE_OPT_NO_TTY))
366 {
367 dReportError("Caught Signal 11");
368 return;
369 }
370 /* REMARK FOR NEWER LINUX SYSTEMS:
371Attaching 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)
372
373There are ways to workaround this:
374
375 Run the following command as super user: echo 0| sudo tee /proc/sys/kernel/yama/ptrace_scope
376
377 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.
378
379 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
380*/
381 int pid;
382 char buf[16];
383 char * args[4] = { (char*)"gdb", (char*)"Singular", NULL, NULL };
384
385 #ifdef HAVE_FEREAD
387 #endif /* HAVE_FEREAD */
388
389 sprintf (buf, "%d", getpid ());
390
391 args[2] = buf;
392
393 pid = fork ();
394 if (pid == 0)
395 {
396 switch (method)
397 {
398 case INTERACTIVE:
399 fputs ("\n\nquit with \"p si_stop_stack_trace_x=0\"\n\n\n",stderr);
400 debug_stop (args);
401 break;
402 case STACK_TRACE:
403 fputs ("stack_trace\n",stderr);
404 stack_trace (args);
405 break;
406 default:
407 // should not be reached:
408 exit(1);
409 }
410 }
411 else if (pid == -1)
412 {
413 perror ("could not fork");
414 return;
415 }
416
418 while (si_stop_stack_trace_x) ;
419}
static void stack_trace(char *const *args)
Definition: cntrlc.cc:429
VAR volatile int si_stop_stack_trace_x
Definition: cntrlc.cc:361
#define INTERACTIVE
Definition: cntrlc.cc:50
#define STACK_TRACE
Definition: cntrlc.cc:51
static void debug_stop(char *const *args)
Definition: cntrlc.cc:421
static void * feOptValue(feOptIndex opt)
Definition: feOpt.h:40
VAR BOOLEAN fe_is_raw_tty
Definition: fereadl.c:72
void fe_temp_reset(void)
Definition: fereadl.c:110
int dReportError(const char *fmt,...)
Definition: dError.cc:44
#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 421 of file cntrlc.cc.

422{
423 execvp (args[0], args);
424 perror ("exec failed");
425 _exit (0);
426}

◆ init_signals()

void init_signals ( void  )

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

Definition at line 527 of file cntrlc.cc.

528{
529// signal handler -------------------------------------------------------
530 #ifdef SIGSEGV
532 #endif
533 #ifdef SIGBUS
535 #endif
536 #ifdef SIGFPE
538 #endif
539 #ifdef SIGILL
541 #endif
542 #ifdef SIGIOT
544 #endif
549}
void sig_pipe_hdl(int)
Definition: cntrlc.cc:64
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:118
void sig_term_hdl(int)
Definition: cntrlc.cc:77
void sigint_handler(int)
Definition: cntrlc.cc:266
void(* si_hdl_typ)(int)
Definition: cntrlc.cc:96
void sigsegv_handler(int sig)
Definition: cntrlc.cc:234

◆ 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 118 of file cntrlc.cc.

119{
120#if 0
121 si_hdl_typ retval=signal (sig, (si_hdl_typ)signal_handler);
122 if (retval == SIG_ERR)
123 {
124 fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig);
125 }
126 si_siginterrupt(sig, 0);
127 /*system calls will be restarted if interrupted by the specified
128 * signal sig. This is the default behavior in Linux.
129 */
130#else
131 struct sigaction new_action,old_action;
132 memset(&new_action, 0, sizeof(struct sigaction));
133
134 /* Set up the structure to specify the new action. */
135 new_action.sa_handler = signal_handler;
136 if (sig==SIGINT)
137 sigemptyset (&new_action.sa_mask);
138 else
139 new_action.sa_flags = SA_RESTART;
140
141 int r=si_sigaction (sig, &new_action, &old_action);
142 si_hdl_typ retval=(si_hdl_typ)old_action.sa_handler;
143 if (r == -1)
144 {
145 fprintf(stderr, "Unable to init signal %d ... exiting...\n", sig);
146 retval=SIG_ERR;
147 }
148#endif
149 return retval;
150} /* si_set_signal */
if(!FE_OPT_NO_SHELL_FLAG)(void) system(sys)
#define si_siginterrupt(arg1, arg2)

◆ sig_pipe_hdl()

void sig_pipe_hdl ( int  )

Definition at line 64 of file cntrlc.cc.

65{
66 if (pipeLastLink!=NULL)
67 {
70 WerrorS("pipe failed");
71 }
72}
VAR si_link pipeLastLink
Definition: cntrlc.cc:61
void WerrorS(const char *s)
Definition: feFopen.cc:24

◆ sig_term_hdl()

void sig_term_hdl ( int  )

Definition at line 77 of file cntrlc.cc.

78{
80 if (!defer_shutdown)
81 {
82 m2_end(1);
83 }
84}
#define TRUE
Definition: auxiliary.h:100
VAR volatile BOOLEAN do_shutdown
Definition: cntrlc.cc:74
VAR volatile int defer_shutdown
Definition: cntrlc.cc:75
void m2_end(int i)
Definition: misc_ip.cc:1097

◆ sigint_handler()

void sigint_handler ( int  )

Definition at line 266 of file cntrlc.cc.

267{
268 mflush();
269 #ifdef HAVE_FEREAD
271 #endif /* HAVE_FEREAD */
272 char default_opt=' ';
273 if ((feOptSpec[FE_OPT_CNTRLC].value!=NULL)
274 && ((char*)(feOptSpec[FE_OPT_CNTRLC].value))[0])
275 { default_opt=((char*)(feOptSpec[FE_OPT_CNTRLC].value))[0]; }
276 loop
277 {
278 int cnt=0;
279 int c;
280
282 {
283 c = 'q';
284 }
285 else if (default_opt!=' ')
286 {
287 c = default_opt;
288 }
289 else
290 {
291 fprintf(stderr,"// ** Interrupt at cmd:`%s` in line:'%s'\n",
293 if (feOptValue(FE_OPT_EMACS) == NULL)
294 {
295 fputs("abort after this command(a), abort immediately(r), print backtrace(b), continue(c) or quit Singular(q) ?",stderr);
296 fflush(stderr);fflush(stdin);
297 c = fgetc(stdin);
298 }
299 else
300 {
301 c = 'a';
302 }
303 }
304
305 switch(c)
306 {
307 case 'q': case EOF:
308 m2_end(2);
309 case 'r':
310 if (sigint_handler_cnt<3)
311 {
313 fputs("** Warning: Singular should be restarted as soon as possible **\n",stderr);
314 fflush(stderr);
315 extern void my_yy_flush();
316 my_yy_flush();
318 longjmp(si_start_jmpbuf,1);
319 }
320 else
321 {
322 fputs("** tried too often, try another possibility **\n",stderr);
323 fflush(stderr);
324 }
325 break;
326 case 'b':
328 break;
329 case 'a':
330 siCntrlc++;
331 case 'c':
332 if ((feOptValue(FE_OPT_EMACS) == NULL) && (default_opt!=' '))
333 {
334 /* Read until a newline or EOF */
335 while (c != EOF && c != '\n') c = fgetc(stdin);
336 }
338 return;
339 //siCntrlc ++;
340 //if (siCntrlc>2) si_set_signal(SIGINT,(si_hdl_typ) sigsegv_handler);
341 //else si_set_signal(SIGINT,(si_hdl_typ) sigint_handler);
342 }
343 cnt++;
344 if(cnt>5) m2_end(2);
345 }
346}
VAR jmp_buf si_start_jmpbuf
Definition: cntrlc.cc:92
VAR BOOLEAN singular_in_batchmode
Definition: cntrlc.cc:62
VAR int sigint_handler_cnt
Definition: cntrlc.cc:265
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:49
void VoiceBackTrack()
Definition: fevoices.cc:77
Voice * feInitStdin(Voice *pp)
Definition: fevoices.cc:677
const char * Tok2Cmdname(int tok)
Definition: gentable.cc:140
VAR int iiOp
Definition: iparith.cc:222
VAR BOOLEAN siCntrlc
Definition: options.c:14
#define mflush()
Definition: reporter.h:58
void my_yy_flush()
Definition: scanner.cc:2318
#define loop
Definition: structs.h:75

◆ sigsegv_handler()

void sigsegv_handler ( int  sig)

Definition at line 234 of file cntrlc.cc.

235{
236 fprintf(stderr,"Singular : signal %d (v: %d):\n",
237 sig,SINGULAR_VERSION);
238 if (sig!=SIGINT)
239 {
240 fprintf(stderr,"current line:>>%s<<\n",my_yylinebuf);
241 fprintf(stderr,"Segment fault/Bus error occurred (r:%d)\n"
242 "please inform the authors\n",
244 }
245 #ifdef __OPTIMIZE__
246 if(si_restart<3)
247 {
248 si_restart++;
249 fputs("trying to restart...\n",stderr);
250 init_signals();
251 longjmp(si_start_jmpbuf,1);
252 }
253 #endif /* __OPTIMIZE__ */
254 #ifdef CALL_GDB
255 if (sig!=SIGINT) debug(STACK_TRACE);
256 #endif /* CALL_GDB */
257 exit(0);
258}
static void debug(int)
Definition: cntrlc.cc:363
VAR short si_restart
Definition: cntrlc.cc:94
VAR int siRandomStart
Definition: cntrlc.cc:93
void init_signals()
init signal handlers and error handling for libraries: NTL, factory
Definition: cntrlc.cc:527
#define SINGULAR_VERSION
Definition: mod2.h:87

◆ stack_trace()

static void stack_trace ( char *const args)
static

Definition at line 429 of file cntrlc.cc.

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

◆ pipeLastLink

VAR si_link pipeLastLink =NULL

Definition at line 61 of file cntrlc.cc.

◆ si_restart

VAR short si_restart =0

Definition at line 94 of file cntrlc.cc.

◆ si_start_jmpbuf

VAR jmp_buf si_start_jmpbuf

Definition at line 92 of file cntrlc.cc.

◆ si_stop_stack_trace_x

VAR volatile int si_stop_stack_trace_x

Definition at line 361 of file cntrlc.cc.

◆ sigint_handler_cnt

VAR int sigint_handler_cnt =0

Definition at line 265 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 93 of file cntrlc.cc.