--- rpl/src/interruptions.c 2011/06/10 11:35:13 1.49 +++ rpl/src/interruptions.c 2011/09/09 12:23:25 1.65 @@ -1,6 +1,6 @@ /* ================================================================================ - RPL/2 (R) version 4.1.0.prerelease.0 + RPL/2 (R) version 4.1.3 Copyright (C) 1989-2011 Dr. BERTRAND Joël This file is part of RPL/2. @@ -803,27 +803,8 @@ liberation_threads(struct_processus *s_e } } -#if 0 - for(i = 0; i < (*s_etat_processus).nombre_variables; i++) - { - pthread_mutex_trylock(&((*(*s_etat_processus) - .s_liste_variables[i].objet).mutex)); - pthread_mutex_unlock(&((*(*s_etat_processus) - .s_liste_variables[i].objet).mutex)); - - // Les variables de niveau 0 sont des définitions qui - // ne sont pas copiées entre threads. - if ((*s_etat_processus).s_liste_variables[i].niveau > 0) - { - liberation(s_etat_processus, - (*s_etat_processus).s_liste_variables[i].objet); - } - - free((*s_etat_processus).s_liste_variables[i].nom); - } - - free((*s_etat_processus).s_liste_variables); -#endif + liberation_arbre_variables(s_etat_processus, + (*s_etat_processus).s_arbre_variables, d_faux); for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++) { @@ -1337,6 +1318,7 @@ liberation_threads(struct_processus *s_e sem_destroy2((*s_etat_processus).semaphore_fork, sem_fork); # endif + liberation_contexte_cas(s_etat_processus); free(s_etat_processus); s_etat_processus = candidat; @@ -1736,6 +1718,9 @@ deverrouillage_gestionnaire_signaux() return; } +#define test_signal(signal) \ + if (signal_test == SIGTEST) { signal_test = signal; return; } + void interruption1(SIGHANDLER_ARGS) { @@ -1747,6 +1732,7 @@ interruption1(SIGHANDLER_ARGS) volatile sig_atomic_t exclusion = 0; + test_signal(signal); verrouillage_gestionnaire_signaux(); # ifdef _BROKEN_SIGINFO @@ -1924,6 +1910,7 @@ interruption2(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + test_signal(signal); verrouillage_gestionnaire_signaux(); # ifdef _BROKEN_SIGINFO @@ -2009,20 +1996,13 @@ interruption2(SIGHANDLER_ARGS) void interruption3(SIGHANDLER_ARGS) { - pid_t pid; + pthread_t thread; struct_processus *s_etat_processus; - static int compteur = 0; - + test_signal(signal); verrouillage_gestionnaire_signaux(); -# ifdef _BROKEN_SIGINFO - pid = origine_signal(signal); -# else - pid = (*siginfo).si_pid; -# endif - if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -2047,24 +2027,79 @@ interruption3(SIGHANDLER_ARGS) // Segfault dans une routine interne if (strncmp(getenv("LANG"), "fr", 2) == 0) { - printf("+++Système : Violation d'accès (dépassement de pile)\n"); + printf("+++Système : Violation d'accès\n"); } else { - printf("+++System : Access violation (stack overflow)\n"); + printf("+++System : Access violation\n"); } fflush(stdout); - compteur++; + (*s_etat_processus).compteur_violation_d_acces++; - if (compteur > 1) + if ((*s_etat_processus).compteur_violation_d_acces > 1) { + // On vient de récupérer plus d'une erreur de segmentation + // dans le même processus ou le même thread. L'erreur n'est pas + // récupérable et on sort autoritairement du programme. Il peut + // rester des processus orphelins en attente ! + + if (strncmp(getenv("LANG"), "fr", 2) == 0) + { + printf("+++Système : Violation d'accès, tentative de " + "terminaison de la tâche\n"); + printf(" (defauts multiples)\n"); + } + else + { + printf("+++System : Access violation, trying to kill task " + "(multiple defaults)\n"); + } + + fflush(stdout); + deverrouillage_gestionnaire_signaux(); exit(EXIT_FAILURE); } else { + // Première erreur de segmentation. On essaie de terminer + // proprement le thread ou le processus. Le signal ne peut être + // envoyé que depuis le même processus. + + if (recherche_thread_principal(getpid(), &thread) == d_vrai) + { + if (pthread_equal(thread, pthread_self()) != 0) + { + deverrouillage_gestionnaire_signaux(); + + if ((*s_etat_processus).pid_processus_pere != getpid()) + { + // On est dans le thread principal d'un processus. + + longjmp(contexte_processus, -1); + } + else + { + // On est dans le thread principal du processus + // père. + + longjmp(contexte_initial, -1); + } + } + else + { + // On est dans un thread fils d'un thread principal. + + deverrouillage_gestionnaire_signaux(); + longjmp(contexte_thread, -1); + } + } + + // Là, on ramasse les miettes puisque le thread n'existe plus + // dans la base (corruption de la mémoire). + deverrouillage_gestionnaire_signaux(); longjmp(contexte_initial, -1); } @@ -2077,18 +2112,11 @@ interruption3(SIGHANDLER_ARGS) void interruption4(SIGHANDLER_ARGS) { - pid_t pid; - struct_processus *s_etat_processus; + test_signal(signal); verrouillage_gestionnaire_signaux(); -# ifdef _BROKEN_SIGINFO - pid = origine_signal(signal); -# else - pid = (*siginfo).si_pid; -# endif - if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -2119,6 +2147,7 @@ interruption5(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + test_signal(signal); verrouillage_gestionnaire_signaux(); # ifdef _BROKEN_SIGINFO @@ -2185,18 +2214,11 @@ interruption5(SIGHANDLER_ARGS) void interruption6(SIGHANDLER_ARGS) { - pid_t pid; - struct_processus *s_etat_processus; + test_signal(signal); verrouillage_gestionnaire_signaux(); -# ifdef _BROKEN_SIGINFO - pid = origine_signal(signal); -# else - pid = (*siginfo).si_pid; -# endif - if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -2217,18 +2239,11 @@ interruption6(SIGHANDLER_ARGS) void interruption7(SIGHANDLER_ARGS) { - pid_t pid; - struct_processus *s_etat_processus; + test_signal(signal); verrouillage_gestionnaire_signaux(); -# ifdef _BROKEN_SIGINFO - pid = origine_signal(signal); -# else - pid = (*siginfo).si_pid; -# endif - if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -2258,6 +2273,7 @@ interruption8(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + test_signal(signal); verrouillage_gestionnaire_signaux(); # ifdef _BROKEN_SIGINFO @@ -2304,18 +2320,11 @@ interruption8(SIGHANDLER_ARGS) void interruption9(SIGHANDLER_ARGS) { - pid_t pid; - struct_processus *s_etat_processus; + test_signal(signal); verrouillage_gestionnaire_signaux(); -# ifdef _BROKEN_SIGINFO - pid = origine_signal(signal); -# else - pid = (*siginfo).si_pid; -# endif - if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -2349,20 +2358,13 @@ interruption10(SIGHANDLER_ARGS) { file *fichier; - pid_t pid; - struct_processus *s_etat_processus; unsigned char nom[8 + 64 + 1]; + test_signal(signal); verrouillage_gestionnaire_signaux(); -# ifdef _BROKEN_SIGINFO - pid = origine_signal(signal); -# else - pid = (*siginfo).si_pid; -# endif - if ((s_etat_processus = recherche_thread(getpid(), pthread_self())) == NULL) { deverrouillage_gestionnaire_signaux(); @@ -2402,6 +2404,7 @@ interruption11(SIGHANDLER_ARGS) struct_processus *s_etat_processus; + test_signal(signal); verrouillage_gestionnaire_signaux(); # ifdef _BROKEN_SIGINFO