--- rpl/src/gestion_objets.c 2010/05/16 19:36:20 1.17 +++ rpl/src/gestion_objets.c 2013/02/26 19:56:13 1.94 @@ -1,7 +1,7 @@ /* ================================================================================ - RPL/2 (R) version 4.0.15 - Copyright (C) 1989-2010 Dr. BERTRAND Joël + RPL/2 (R) version 4.1.12 + Copyright (C) 1989-2013 Dr. BERTRAND Joël This file is part of RPL/2. @@ -20,7 +20,7 @@ */ -#include "rpl.conv.h" +#include "rpl-conv.h" /* @@ -57,7 +57,7 @@ decrementation_atomique(struct_objet *s_ return((*s_objet).nombre_occurrences); } -inline void +void initialisation_objet(struct_objet *s_objet) { pthread_mutexattr_t attributs_mutex; @@ -111,6 +111,13 @@ initialisation_allocateur(struct_process (*s_etat_processus).pointeur_vec = 0; (*s_etat_processus).pointeur_maillons = 0; + (*s_etat_processus).pointeur_variables_noeud = 0; + (*s_etat_processus).pointeur_variables_partagees_noeud = 0; + (*s_etat_processus).pointeur_variables_feuille = 0; + (*s_etat_processus).pointeur_variables_variable = 0; + (*s_etat_processus).pointeur_variables_tableau_noeuds = 0; + (*s_etat_processus).pointeur_variables_tableau_noeuds_partages = 0; + return; } @@ -143,6 +150,20 @@ liberation_allocateur(struct_processus * for(i = 0; i < (*s_etat_processus).pointeur_maillons; free((*s_etat_processus).maillons[i++])); + for(i = 0; i < (*s_etat_processus).pointeur_variables_noeud; + free((*s_etat_processus).variables_noeud[i++])); + for(i = 0; i < (*s_etat_processus).pointeur_variables_partagees_noeud; + free((*s_etat_processus).variables_partagees_noeud[i++])); + for(i = 0; i < (*s_etat_processus).pointeur_variables_feuille; + free((*s_etat_processus).variables_feuille[i++])); + for(i = 0; i < (*s_etat_processus).pointeur_variables_variable; + free((*s_etat_processus).variables_variable[i++])); + for(i = 0; i < (*s_etat_processus).pointeur_variables_tableau_noeuds; + free((*s_etat_processus).variables_tableau_noeuds[i++])); + for(i = 0; i < (*s_etat_processus) + .pointeur_variables_tableau_noeuds_partages; + free((*s_etat_processus).variables_tableau_noeuds_partages[i++])); + { struct_liste_chainee *l_element_courant; struct_liste_chainee *l_element_suivant; @@ -234,7 +255,7 @@ allocation_maillon(struct_processus *s_e /* ================================================================================ - Routine d'allocation d'un maillon d'un objet (liste, expression...) + Routine de libération d'un maillon d'un objet (liste, expression...) ================================================================================ Entrées : structure sur l'état du processus et objet à afficher -------------------------------------------------------------------------------- @@ -266,7 +287,7 @@ liberation_maillon(struct_processus *s_e ================================================================================ Routine d'allocation d'une structure *s_objet ================================================================================ - Entrées : structure sur l'état du processus et objet à afficher + Entrées : structure sur l'état du processus et objet à allouer -------------------------------------------------------------------------------- Sorties : chaine de caractères -------------------------------------------------------------------------------- @@ -274,13 +295,25 @@ liberation_maillon(struct_processus *s_e ================================================================================ */ -void * +struct_objet * allocation(struct_processus *s_etat_processus, enum t_type type) { struct_objet *s_objet; + if (pthread_mutex_lock(&((*s_etat_processus).mutex_allocation)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return(NULL); + } + if ((*s_etat_processus).pile_objets == NULL) { + if (pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return(NULL); + } + // Il n'existe aucune structure struct_objet disponible dans le cache. if ((s_objet = malloc(sizeof(struct_objet))) == NULL) @@ -299,6 +332,12 @@ allocation(struct_processus *s_etat_proc (*s_etat_processus).taille_pile_objets--; (*s_objet).nombre_occurrences = 1; + + if (pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return(NULL); + } } (*s_objet).type = type; @@ -512,6 +551,7 @@ allocation(struct_processus *s_etat_proc return(NULL); } + (*((struct_mutex *) (*s_objet).objet)).tid = pthread_self(); break; } @@ -877,14 +917,21 @@ liberation(struct_processus *s_etat_proc { if (decrementation_atomique(s_objet) > 0) { - liberation(s_etat_processus, (*((struct_fichier *) - (*s_objet).objet)).format); + BUG((*(*((struct_fichier *) (*s_objet).objet)).format) + .nombre_occurrences <= 1, + pthread_mutex_unlock(&((*s_objet).mutex)), + printf("(*(*((struct_fichier *) (*s_objet).objet))" + ".format).nombre_occurrences=%ld\n", + (*(*((struct_fichier *) (*s_objet).objet)).format) + .nombre_occurrences)); + + liberation(s_etat_processus, + (*((struct_fichier *) (*s_objet).objet)).format); return; } liberation(s_etat_processus, (*((struct_fichier *) (*s_objet).objet)).format); - free((unsigned char *) (*((struct_fichier *) (*s_objet).objet)).nom); free((struct_fichier *) ((*s_objet).objet)); @@ -1064,6 +1111,28 @@ liberation(struct_processus *s_etat_proc return; } + if (pthread_mutex_trylock(&((*((struct_mutex *) + (*s_objet).objet)).mutex)) == 0) + { + // On a pu verrouiller le mutex. Il faut donc spécifier le tid. + (*((struct_mutex *) (*s_objet).objet)).tid = pthread_self(); + } + + if (pthread_equal(pthread_self(), + (*((struct_mutex *) (*s_objet).objet)).tid) != 0) + { + pthread_mutex_unlock(&((*((struct_mutex *) + (*s_objet).objet)).mutex)); + } + else + { + (*s_etat_processus).erreur_systeme = + d_es_mutex_acquis_autre_thread; + return; + } + + pthread_mutex_destroy(&((*((struct_mutex *) + (*s_objet).objet)).mutex)); free((struct_mutex *) (*s_objet).objet); break; } @@ -1097,14 +1166,13 @@ liberation(struct_processus *s_etat_proc return; } - free(s_objet); break; } case PRC : { if (pthread_mutex_lock(&((*(*((struct_processus_fils *) - (*s_objet).objet)).thread).mutex)) != 0) + (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; @@ -1114,7 +1182,8 @@ liberation(struct_processus *s_etat_proc .nombre_references--; BUG((*(*((struct_processus_fils *) (*s_objet).objet)).thread) - .nombre_references < 0, printf("(*(*((struct_processus_fils" + .nombre_references < 0, uprintf( + "(*(*((struct_processus_fils" " *) (*s_objet).objet)).thread).nombre_references = %d\n", (int) (*(*((struct_processus_fils *) (*s_objet).objet)) .thread).nombre_references)); @@ -1130,7 +1199,7 @@ liberation(struct_processus *s_etat_proc } if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) - (*s_objet).objet)).thread).mutex)) != 0) + (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; @@ -1140,11 +1209,16 @@ liberation(struct_processus *s_etat_proc { pthread_mutex_destroy(&((*(*((struct_processus_fils *) (*s_objet).objet)).thread).mutex)); + pthread_mutex_destroy(&((*(*((struct_processus_fils *) + (*s_objet).objet)).thread).mutex_nombre_references)); free((*((struct_processus_fils *) (*s_objet).objet)).thread); } if (decrementation_atomique(s_objet) > 0) { + BUG(drapeau == d_vrai, uprintf("(*(*((struct_processus_fils" + " *) (*s_objet).objet)).thread).nombre_references " + "= 0 with nombre_occurrences > 0\n")); return; } @@ -1210,6 +1284,14 @@ liberation(struct_processus *s_etat_proc { if (decrementation_atomique(s_objet) > 0) { + BUG((*(*((struct_socket *) (*s_objet).objet)).format) + .nombre_occurrences <= 1, + pthread_mutex_unlock(&((*s_objet).mutex)), + printf("(*(*((struct_socket *) (*s_objet).objet))" + ".format).nombre_occurrences=%ld\n", + (*(*((struct_socket *) (*s_objet).objet)).format) + .nombre_occurrences)); + liberation(s_etat_processus, (*((struct_socket *) (*s_objet).objet)).format); return; @@ -1217,6 +1299,7 @@ liberation(struct_processus *s_etat_proc liberation(s_etat_processus, (*((struct_socket *) (*s_objet).objet)).format); + free((unsigned char *) (*((struct_socket *) (*s_objet).objet)) .adresse); free((unsigned char *) (*((struct_socket *) (*s_objet).objet)) @@ -1400,30 +1483,36 @@ liberation(struct_processus *s_etat_proc return; } - if (s_etat_processus != NULL) + if (pthread_mutex_lock(&((*s_etat_processus).mutex_allocation)) != 0) { - if ((*s_etat_processus).taille_pile_objets < TAILLE_CACHE) - { - (*s_objet).objet = (*s_etat_processus).pile_objets; - (*s_etat_processus).pile_objets = s_objet; - (*s_etat_processus).taille_pile_objets++; - } - else - { - if (pthread_mutex_destroy(&((*s_objet).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return; - } + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } - free(s_objet); - } + if ((*s_etat_processus).taille_pile_objets < TAILLE_CACHE) + { + (*s_objet).objet = (*s_etat_processus).pile_objets; + (*s_etat_processus).pile_objets = s_objet; + (*s_etat_processus).taille_pile_objets++; } else { + if (pthread_mutex_destroy(&((*s_objet).mutex)) != 0) + { + pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)); + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + free(s_objet); } + if (pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)) != 0) + { + (*s_etat_processus).erreur_systeme = d_es_processus; + return; + } + return; } @@ -2157,20 +2246,9 @@ copie_objet(struct_processus *s_etat_pro case MTX : { - if (type != 'O') - { - incrementation_atomique(s_objet); - return(s_objet); - } - - if ((s_nouvel_objet = allocation(s_etat_processus, MTX)) == NULL) - { - return(NULL); - } - - (*((struct_mutex *) ((*s_nouvel_objet).objet))).mutex = - (*((struct_mutex *) ((*s_objet).objet))).mutex; - break; + // La duplication d'un mutex renvoie le même objet. + incrementation_atomique(s_objet); + return(s_objet); } case NOM : @@ -2212,19 +2290,24 @@ copie_objet(struct_processus *s_etat_pro return(s_objet); } + // Un objet de type NON est un objet encapsulé dans une + // structure de type struct_objet. Elle peut très bien contenir + // une donnée, mais c'est à l'utilisateur de la libérer + // explicitement avec un free(). + if ((s_nouvel_objet = allocation(s_etat_processus, NON)) == NULL) { return(NULL); } - (*s_nouvel_objet).objet = NULL; + (*s_nouvel_objet).objet = (*s_objet).objet; break; } case PRC : { if (pthread_mutex_lock(&((*(*((struct_processus_fils *) - (*s_objet).objet)).thread).mutex)) != 0) + (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { return(NULL); } @@ -2233,7 +2316,7 @@ copie_objet(struct_processus *s_etat_pro .nombre_references++; if (pthread_mutex_unlock(&((*(*((struct_processus_fils *) - (*s_objet).objet)).thread).mutex)) != 0) + (*s_objet).objet)).thread).mutex_nombre_references)) != 0) { return(NULL); } @@ -2278,9 +2361,10 @@ copie_objet(struct_processus *s_etat_pro { incrementation_atomique(s_objet); - if (((*((struct_socket *) ((*s_nouvel_objet).objet))).format = - copie_objet(s_etat_processus, (*((struct_socket *) - ((*s_objet).objet))).format, 'P')) == NULL) + if (((*((struct_socket *) ((*s_objet).objet))) + .format = copie_objet(s_etat_processus, + (*((struct_socket *) ((*s_objet).objet))).format, 'P')) + == NULL) { return(NULL); } @@ -2424,6 +2508,8 @@ copie_objet(struct_processus *s_etat_pro return(NULL); } + (*((struct_semaphore *) (*s_nouvel_objet).objet)).semaphore = + (*((struct_semaphore *) (*s_objet).objet)).semaphore; strcpy((*((struct_semaphore *) (*s_nouvel_objet).objet)).nom, (*((struct_semaphore *) (*s_objet).objet)).nom); break; @@ -2741,18 +2827,18 @@ copie_etat_processus(struct_processus *s * n'ont aucune raison de changer. */ -# ifndef SEMAPHORES_NOMMES - sem_init(&((*s_nouvel_etat_processus).semaphore_fork), 0, 0); -# else - if (((*s_nouvel_etat_processus).semaphore_fork = sem_init2(0, sem_fork)) - == SEM_FAILED) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(NULL); - } -# endif + pthread_mutexattr_init(&attributs_mutex); + pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL); + (*s_nouvel_etat_processus).sections_critiques = 0; + + // Les sémaphores sont initialisés dans le nouveau thread. Il + // s'agit d'une limitation de l'implantation de l'émulation + // de sem_init(). + + initialisation_contexte_cas(s_etat_processus); (*s_nouvel_etat_processus).var_volatile_processus_pere = 0; + (*s_nouvel_etat_processus).var_volatile_processus_racine = 0; (*s_nouvel_etat_processus).fichiers_graphiques = NULL; (*s_nouvel_etat_processus).entree_standard = NULL; (*s_nouvel_etat_processus).s_marques = NULL; @@ -2783,6 +2869,8 @@ copie_etat_processus(struct_processus *s (*s_nouvel_etat_processus).nombre_interruptions_non_affectees = 0; (*s_nouvel_etat_processus).at_exit = NULL; + (*s_nouvel_etat_processus).at_poke = NULL; + (*s_nouvel_etat_processus).traitement_at_poke = 'N'; for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++) { @@ -2794,10 +2882,17 @@ copie_etat_processus(struct_processus *s if ((*s_nouvel_etat_processus).generateur_aleatoire != NULL) { - (*s_nouvel_etat_processus).generateur_aleatoire = NULL; - } + if (((*s_nouvel_etat_processus).generateur_aleatoire = + gsl_rng_clone((*s_etat_processus).generateur_aleatoire)) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(NULL); + } - (*s_nouvel_etat_processus).type_generateur_aleatoire = NULL; + gsl_rng_set((*s_nouvel_etat_processus).generateur_aleatoire, + gsl_rng_get((*s_etat_processus).generateur_aleatoire)); + } // Copie de la localisation @@ -3024,135 +3119,18 @@ copie_etat_processus(struct_processus *s * Copie de la table des variables */ - if (((*s_nouvel_etat_processus).s_liste_variables = - malloc((*s_etat_processus).nombre_variables_allouees * - sizeof(struct_variable))) == NULL) - { - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return(NULL); - } - - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(NULL); - } - - for(i = 0; i < (*s_etat_processus).nombre_variables; i++) - { - if (((*s_nouvel_etat_processus).s_liste_variables[i].nom = - malloc((strlen((*s_etat_processus).s_liste_variables[i].nom) - + 1) * sizeof(unsigned char))) == NULL) - { - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return(NULL); - } - - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(NULL); - } - - strcpy((*s_nouvel_etat_processus).s_liste_variables[i].nom, - (*s_etat_processus).s_liste_variables[i].nom); - - (*s_nouvel_etat_processus).s_liste_variables[i].origine = - (*s_etat_processus).s_liste_variables[i].origine; - (*s_nouvel_etat_processus).s_liste_variables[i].niveau = - (*s_etat_processus).s_liste_variables[i].niveau; - (*s_nouvel_etat_processus).s_liste_variables[i].variable_statique = - (*s_etat_processus).s_liste_variables[i].variable_statique; - (*s_nouvel_etat_processus).s_liste_variables[i].variable_partagee = - (*s_etat_processus).s_liste_variables[i].variable_partagee; - (*s_nouvel_etat_processus).s_liste_variables[i].variable_verrouillee = - (*s_etat_processus).s_liste_variables[i].variable_verrouillee; - - // Les définitions sont partagées entre tous les threads. - - if ((*s_etat_processus).s_liste_variables[i].niveau == 0) - { - (*s_nouvel_etat_processus).s_liste_variables[i].objet = - (*s_etat_processus).s_liste_variables[i].objet; - } - else - { - if (((*s_nouvel_etat_processus).s_liste_variables[i].objet = - copie_objet(s_etat_processus, - (*s_etat_processus).s_liste_variables[i] - .objet, 'P')) == NULL) - { - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return(NULL); - } + (*s_nouvel_etat_processus).l_liste_variables_statiques = NULL; + copie_arbre_variables(s_etat_processus, s_nouvel_etat_processus); - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(NULL); - } - } - } - - /* - * Copie de la table des variables statiques - */ - - if (((*s_nouvel_etat_processus).s_liste_variables_statiques = - malloc((*s_etat_processus).nombre_variables_statiques_allouees * - sizeof(struct_variable_statique))) == NULL) + if ((*s_nouvel_etat_processus).erreur_systeme != d_es) { - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return(NULL); - } - - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(NULL); } - for(i = 0; i < (*s_etat_processus).nombre_variables_statiques; i++) - { - if (((*s_nouvel_etat_processus).s_liste_variables_statiques[i].nom = - malloc((strlen((*s_etat_processus).s_liste_variables_statiques - [i].nom) + 1) * sizeof(unsigned char))) == NULL) - { - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return(NULL); - } - - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(NULL); - } - - strcpy((*s_nouvel_etat_processus).s_liste_variables_statiques[i].nom, - (*s_etat_processus).s_liste_variables_statiques[i].nom); - - (*s_nouvel_etat_processus).s_liste_variables_statiques[i].origine = - (*s_etat_processus).s_liste_variables_statiques[i].origine; - (*s_nouvel_etat_processus).s_liste_variables_statiques[i].niveau = - (*s_etat_processus).s_liste_variables_statiques[i].niveau; - (*s_nouvel_etat_processus).s_liste_variables_statiques[i] - .variable_statique = (*s_etat_processus) - .s_liste_variables_statiques[i].variable_statique; - - if (((*s_nouvel_etat_processus).s_liste_variables_statiques[i].objet = - copie_objet(s_etat_processus, (*s_etat_processus) - .s_liste_variables_statiques[i].objet, 'P')) == NULL) - { - if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) - { - (*s_etat_processus).erreur_systeme = d_es_processus; - return(NULL); - } - - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(NULL); - } - } + (*(*s_nouvel_etat_processus).l_liste_variables_partagees) = + (*(*s_etat_processus).l_liste_variables_partagees); + (*(*s_nouvel_etat_processus).s_arbre_variables_partagees) = + (*(*s_etat_processus).s_arbre_variables_partagees); /* * Copie de la pile opérationnelle @@ -3261,6 +3239,9 @@ copie_etat_processus(struct_processus *s * Copie des différents contextes */ + (*s_nouvel_etat_processus).pointeur_signal_lecture = d_faux; + (*s_nouvel_etat_processus).pointeur_signal_ecriture = d_faux; + (*s_nouvel_etat_processus).l_base_pile_contextes = NULL; l_element_lecture = (*s_etat_processus).l_base_pile_contextes; @@ -3519,6 +3500,12 @@ copie_etat_processus(struct_processus *s pthread_mutex_init(&((*s_nouvel_etat_processus).mutex), &attributs_mutex); pthread_mutexattr_destroy(&attributs_mutex); + pthread_mutexattr_init(&attributs_mutex); + pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL); + pthread_mutex_init(&((*s_nouvel_etat_processus).mutex_allocation), + &attributs_mutex); + pthread_mutexattr_destroy(&attributs_mutex); + if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0) { (*s_etat_processus).erreur_systeme = d_es_processus; @@ -3548,20 +3535,24 @@ copie_etat_processus(struct_processus *s #undef malloc #undef realloc #undef free +#undef fork #ifdef return # undef return #endif -#undef fprintf - #ifdef __BACKTRACE +#define PROFONDEUR_PILE 64 #define return(a) { if (a == NULL) \ - { BACKTRACE(20); fprintf(stderr, ">>> MEDITATION %d\n", __LINE__); } \ + { BACKTRACE(PROFONDEUR_PILE); \ + fprintf(stderr, ">>> MEDITATION %d\n", __LINE__); } \ return(a); } while(0) -#define PROFONDEUR_PILE 64 #endif +#undef fprintf +#define check(a, b) ((strcmp(#a, fonction) == 0) && (ligne == b)) +#undef CORE_DUMP + typedef struct memoire { void *pointeur; @@ -3579,10 +3570,20 @@ typedef struct memoire static struct_memoire *debug = NULL; static unsigned long long ordre = 0; -static pthread_mutex_t mutex_allocation = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t mutex_allocation; -#define check(a, b) ((strcmp(#a, fonction) == 0) && (ligne == b)) -#define CORE_DUMP +void +debug_memoire_initialisation() +{ + pthread_mutexattr_t attributs_mutex; + + pthread_mutexattr_init(&attributs_mutex); + pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mutex_allocation, &attributs_mutex); + pthread_mutexattr_destroy(&attributs_mutex); + + return; +} void * debug_memoire_ajout(size_t taille, const unsigned char *fonction, @@ -3590,6 +3591,8 @@ debug_memoire_ajout(size_t taille, const { struct_memoire *ancienne_base; + void *pointeur; + pthread_mutex_lock(&mutex_allocation); ancienne_base = debug; @@ -3611,30 +3614,35 @@ debug_memoire_ajout(size_t taille, const (*debug).taille = taille; (*debug).ordre = ordre; + pointeur = (*debug).pointeur; + # ifdef __BACKTRACE (*debug).profondeur = backtrace((*debug).pile, PROFONDEUR_PILE); # endif - pthread_mutex_unlock(&mutex_allocation); - if (((*debug).fonction = malloc((strlen(fonction) + 1) * sizeof(unsigned char))) == NULL) { + pthread_mutex_unlock(&mutex_allocation); return(NULL); } if (((*debug).argument = malloc((strlen(argument) + 1) * sizeof(unsigned char))) == NULL) { + pthread_mutex_unlock(&mutex_allocation); return(NULL); } strcpy((*debug).fonction, fonction); strcpy((*debug).argument, argument); + memset((*debug).pointeur, 0, (*debug).taille); + + pthread_mutex_unlock(&mutex_allocation); ordre++; - return((*debug).pointeur); + return(pointeur); } void * @@ -3648,9 +3656,11 @@ debug_memoire_modification(void *pointeu { if (taille == 0) { - // Revient à free() + // Revient à free(). Il n'y a pas de parenthèses car on ne veut + // pas utiliser la macro return(). + debug_memoire_retrait(pointeur); - return(NULL); + return NULL ; } else { @@ -3673,38 +3683,50 @@ debug_memoire_modification(void *pointeu if (element_courant == NULL) { pthread_mutex_unlock(&mutex_allocation); - return(NULL); - } - pthread_mutex_unlock(&mutex_allocation); + uprintf("[%d-%llu] ILLEGAL POINTER (realloc)\n", + getpid(), (unsigned long long) pthread_self()); +# ifdef __BACKTRACE + BACKTRACE(PROFONDEUR_PILE); +# endif - if (((*element_courant).pointeur = realloc(pointeur, taille)) - == NULL) - { - return(NULL); + return(realloc(pointeur, taille)); } + else + { + if (((*element_courant).pointeur = realloc(pointeur, taille)) + == NULL) + { + pthread_mutex_unlock(&mutex_allocation); + return(NULL); + } - (*element_courant).ligne = ligne; - (*element_courant).taille = taille; - free((*element_courant).fonction); - free((*element_courant).argument); + (*element_courant).ligne = ligne; + (*element_courant).taille = taille; + free((*element_courant).fonction); + free((*element_courant).argument); - if (((*element_courant).fonction = malloc((strlen(fonction) + 1) * - sizeof(unsigned char))) == NULL) - { - return(NULL); - } + if (((*element_courant).fonction = malloc((strlen(fonction) + + 1) * sizeof(unsigned char))) == NULL) + { + pthread_mutex_unlock(&mutex_allocation); + return(NULL); + } - if (((*element_courant).argument = malloc((strlen(argument) + 1) * - sizeof(unsigned char))) == NULL) - { - return(NULL); - } + if (((*element_courant).argument = malloc((strlen(argument) + + 1) * sizeof(unsigned char))) == NULL) + { + pthread_mutex_unlock(&mutex_allocation); + return(NULL); + } - strcpy((*element_courant).fonction, fonction); - strcpy((*element_courant).argument, argument); + strcpy((*element_courant).fonction, fonction); + strcpy((*element_courant).argument, argument); + + pthread_mutex_unlock(&mutex_allocation); - return((*element_courant).pointeur); + return((*element_courant).pointeur); + } } } else @@ -3739,6 +3761,11 @@ debug_memoire_retrait(void *pointeur) (*element_precedent).suivant = (*element_courant).suivant; } + if (pointeur != NULL) + { + memset(pointeur, 0, (*element_courant).taille); + } + free((*element_courant).fonction); free((*element_courant).argument); free(element_courant); @@ -3752,8 +3779,16 @@ debug_memoire_retrait(void *pointeur) pthread_mutex_unlock(&mutex_allocation); - free(pointeur); + if (element_courant == NULL) + { + uprintf("[%d-%llu] ILLEGAL POINTER (free)\n", + getpid(), (unsigned long long) pthread_self()); +# ifdef __BACKTRACE + BACKTRACE(PROFONDEUR_PILE); +# endif + } + free(pointeur); return; } @@ -3793,6 +3828,33 @@ debug_memoire_verification() (unsigned long long) pthread_self(), (*element_courant).argument); + if (strstr((*element_courant).argument, "sizeof(unsigned char)") + != NULL) + { + fprintf(stderr, "[%d-%llu] ", getpid(), + (unsigned long long) pthread_self()); + fprintf(stderr, "O: %s\n", (unsigned char *) + (*element_courant).pointeur); + } + else if (strcmp((*element_courant).argument, "sizeof(struct_objet)") + == 0) + { + fprintf(stderr, "[%d-%llu] ", getpid(), + (unsigned long long) pthread_self()); + fprintf(stderr, "O: %d\n", (*((struct_objet *) + (*element_courant).pointeur)).type); + } + else if (strcmp((*element_courant).argument, + "sizeof(struct_liste_chainee)") == 0) + { + fprintf(stderr, "[%d-%llu] ", getpid(), + (unsigned long long) pthread_self()); + fprintf(stderr, "O: data=%p next=%p\n", (*((struct_liste_chainee *) + (*element_courant).pointeur)).donnee, + (*((struct_liste_chainee *) (*element_courant).pointeur)) + .suivant); + } + # ifdef __BACKTRACE appels = backtrace_symbols((*element_courant).pile, (*element_courant).profondeur); @@ -3828,6 +3890,7 @@ debug_memoire_verification() } pthread_mutex_unlock(&mutex_allocation); + pthread_mutex_destroy(&mutex_allocation); fprintf(stderr, "[%d-%llu] END OF LIST\n", getpid(), (unsigned long long) pthread_self()); @@ -3835,6 +3898,31 @@ debug_memoire_verification() return; } +pid_t +debug_fork() +{ + pid_t pid; + + pthread_mutex_lock(&mutex_allocation); + pid = fork(); + + if (pid == 0) + { + liberation_queue_signaux(s_etat_processus); + creation_queue_signaux(s_etat_processus); + + pthread_mutex_destroy(&mutex_allocation); + debug_memoire_initialisation(); + } + else + { + pthread_mutex_unlock(&mutex_allocation); + } + + // Pas de parenthèses pour ne pas remplacer return par sa macro. + return pid; +} + void analyse_post_mortem() {