--- rpl/src/interruptions.c 2011/09/01 12:14:56 1.62 +++ rpl/src/interruptions.c 2011/09/03 10:31:50 1.63 @@ -1991,9 +1991,9 @@ interruption2(SIGHANDLER_ARGS) void interruption3(SIGHANDLER_ARGS) { - struct_processus *s_etat_processus; + pthread_t thread; - static int compteur = 0; + struct_processus *s_etat_processus; verrouillage_gestionnaire_signaux(); @@ -2021,24 +2021,76 @@ 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\n"); + } + else + { + printf("+++System : Access violation\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); }