--- rpl/src/rpl.c 2011/09/20 19:28:39 1.93 +++ rpl/src/rpl.c 2011/09/21 09:09:01 1.94 @@ -36,6 +36,8 @@ rplinit(int argc, char *argv[], unsigned # include "copyright-conv.h" # include "licence-conv.h" + char pile_signaux[SIGSTKSZ]; + file *f_source; int erreur_historique; @@ -100,6 +102,7 @@ rplinit(int argc, char *argv[], unsigned errno = 0; s_queue_signaux = NULL; + routine_recursive = 0; pid_processus_pere = getpid(); # ifdef DEBUG_MEMOIRE @@ -176,7 +179,6 @@ rplinit(int argc, char *argv[], unsigned (*s_etat_processus).exception = d_ep; (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex; - (*s_etat_processus).compteur_violation_d_acces = 0; (*s_etat_processus).rpl_home = rpl_home; @@ -314,50 +316,40 @@ rplinit(int argc, char *argv[], unsigned home = ""; } - // Initialisation d'une pile de signal pour récupérer les - // débordement de pile - -# if !defined(Cygwin) && !defined(OpenBSD) - if (((*s_etat_processus).pile_signal.ss_sp = - malloc((*s_etat_processus).pile_signal.ss_size = - SIGSTKSZ)) == NULL) - { - erreur = d_es_allocation_memoire; - - if ((*s_etat_processus).langue == 'F') +# ifdef HAVE_STACK_OVERFLOW_RECOVERY + if (stackoverflow_install_handler(interruption_depassement_pile, + pile_signaux, sizeof(pile_signaux)) != 0) { - printf("+++Système : Mémoire insuffisante\n"); - } - else - { - printf("+++System : Not enough memory\n"); - } - - return(EXIT_FAILURE); - } - - (*s_etat_processus).pile_signal.ss_flags = 0; + erreur = d_es_signal; - if (sigaltstack(&((*s_etat_processus).pile_signal), NULL) != 0) - { - erreur = d_es_signal; + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation de la pile alternative " + "impossible\n"); + } + else + { + printf("+++System : Initialization of alternate " + "stack failed\n"); + } + return(EXIT_FAILURE); + } +# else if ((*s_etat_processus).langue == 'F') { - printf("+++Système : Initialisation de la pile spécifique de signal" - " impossible\n"); + printf("+++Attention : Le système ne supporte pas de pile " + "alternative\n"); } else { - printf("+++System : Initialization of signal stack failed\n"); + printf("+++Warning : Operating system does not support alternate " + "stack\n"); } - - return(EXIT_FAILURE); - } # endif action.sa_handler = interruption1; - action.sa_flags = SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGINT, &action, NULL) != 0) { @@ -434,7 +426,7 @@ rplinit(int argc, char *argv[], unsigned } action.sa_handler = interruption2; - action.sa_flags = SA_NODEFER | SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGTSTP, &action, NULL) != 0) { @@ -472,7 +464,7 @@ rplinit(int argc, char *argv[], unsigned } action.sa_handler = interruption5; - action.sa_flags = SA_NODEFER | SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGPIPE, &action, NULL) != 0) { @@ -512,9 +504,9 @@ rplinit(int argc, char *argv[], unsigned } action.sa_handler = interruption1; - action.sa_flags = SA_NODEFER | SA_ONSTACK; + action.sa_flags = 0; - if (sigaction(SIGALRM, &action, NULL) != 0) + if (sigaction(SIGUSR1, &action, NULL) != 0) { erreur = d_es_signal; @@ -532,9 +524,9 @@ rplinit(int argc, char *argv[], unsigned } signal_test = SIGTEST; - kill(getpid(), SIGALRM); + kill(getpid(), SIGUSR1); - if (signal_test != SIGALRM) + if (signal_test != SIGUSR1) { erreur = d_es_signal; @@ -1453,10 +1445,36 @@ rplinit(int argc, char *argv[], unsigned } } + /* + * Dans le cas où le programme est appelé avec l'option -d, + * on ne récupère par les signaux de violation d'accès. On + * tente simplement la récupération des dépassements de pile. + */ + if (debug == d_faux) { + +# ifdef HAVE_SIGSEGV_RECOVERY + if (sigsegv_install_handler(interruption_violation_access) != 0) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation de la pile alternative " + "impossible\n"); + } + else + { + printf("+++System : Initialization of alternate " + "stack failed\n"); + } + + return(EXIT_FAILURE); + } +# else action.sa_handler = interruption3; - action.sa_flags = SA_NODEFER | SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGSEGV, &action, NULL) != 0) { @@ -1474,6 +1492,28 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + signal_test = SIGTEST; + kill(getpid(), SIGSEGV); + + if (signal_test != SIGSEGV) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals " + "failed\n"); + } + + return(EXIT_FAILURE); + } +# endif + if (sigaction(SIGBUS, &action, NULL) != 0) { if ((*s_etat_processus).langue == 'F') @@ -1489,12 +1529,34 @@ rplinit(int argc, char *argv[], unsigned return(EXIT_FAILURE); } + + signal_test = SIGTEST; + kill(getpid(), SIGBUS); + + if (signal_test != SIGBUS) + { + erreur = d_es_signal; + + if ((*s_etat_processus).langue == 'F') + { + printf("+++Système : Initialisation des signaux POSIX " + "impossible\n"); + } + else + { + printf("+++System : Initialization of POSIX signals " + "failed\n"); + } + + return(EXIT_FAILURE); + } + } if (option_n == d_vrai) { action.sa_handler = interruption4; - action.sa_flags = SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGHUP, &action, NULL) != 0) { @@ -2914,7 +2976,7 @@ rplinit(int argc, char *argv[], unsigned .thread).nombre_objets_dans_pipe--; action.sa_handler = SIG_IGN; - action.sa_flags = SA_ONSTACK; + action.sa_flags = 0; if (sigaction(SIGPIPE, &action, ®istre) != 0) @@ -3519,6 +3581,17 @@ rplinit(int argc, char *argv[], unsigned analyse_post_mortem(); # endif +# ifdef HAVE_STACK_OVERFLOW_RECOVERY + stackoverflow_deinstall_handler(); +# endif + +# ifdef HAVE_SIGSEGV_RECOVERY + if (debug == d_faux) + { + sigsegv_deinstall_handler(); + } +# endif + return((erreur == d_absence_erreur) ? EXIT_SUCCESS : EXIT_FAILURE); }