--- rpl/src/gestion_objets.c 2010/02/26 19:22:05 1.5 +++ rpl/src/gestion_objets.c 2010/02/28 14:47:14 1.6 @@ -25,7 +25,7 @@ /* ================================================================================ - Routine de gestion du nombre d'occurrences comme grandeur atomique + Routines de gestion du nombre d'occurrences comme grandeur atomique ================================================================================ entrées : structure sur l'état du processus et objet à afficher -------------------------------------------------------------------------------- @@ -3497,4 +3497,277 @@ copie_etat_processus(struct_processus *s #undef return } + +/* +================================================================================ + Routines de debug +================================================================================ + entrées : +-------------------------------------------------------------------------------- + sorties : +-------------------------------------------------------------------------------- + effets de bord : néant +================================================================================ +*/ + +#ifdef DEBUG_MEMOIRE + +#undef malloc +#undef realloc +#undef free + +#ifdef return +# undef return +#endif + +#undef fprintf + +#define return(a) { if (a == NULL) \ + { BACKTRACE(20); fprintf(stderr, ">>> MEDITATION %d\n", __LINE__); } \ + return(a); } while(0) + +typedef struct memoire +{ + void *pointeur; + unsigned char *fonction; + unsigned char *argument; + unsigned long ligne; + size_t taille; + unsigned long long ordre; + struct memoire *suivant; +} struct_memoire; + +static struct_memoire *debug = NULL; +static unsigned long long ordre = 0; +static pthread_mutex_t mutex_allocation = PTHREAD_MUTEX_INITIALIZER; + +#define check(a, b) ((strcmp(#a, fonction) == 0) && (ligne == b)) + +void * +debug_memoire_ajout(size_t taille, const unsigned char *fonction, + unsigned long ligne, const unsigned char *argument) +{ + struct_memoire *ancienne_base; + + pthread_mutex_lock(&mutex_allocation); + + ancienne_base = debug; + + if ((debug = malloc(sizeof(struct_memoire))) == NULL) + { + pthread_mutex_unlock(&mutex_allocation); + return(NULL); + } + + if (((*debug).pointeur = malloc(taille)) == NULL) + { + pthread_mutex_unlock(&mutex_allocation); + return(NULL); + } + + (*debug).suivant = ancienne_base; + (*debug).ligne = ligne; + (*debug).taille = taille; + (*debug).ordre = ordre; + + pthread_mutex_unlock(&mutex_allocation); + + if (((*debug).fonction = malloc((strlen(fonction) + 1) * + sizeof(unsigned char))) == NULL) + { + return(NULL); + } + + if (((*debug).argument = malloc((strlen(argument) + 1) * + sizeof(unsigned char))) == NULL) + { + return(NULL); + } + + strcpy((*debug).fonction, fonction); + strcpy((*debug).argument, argument); + + ordre++; + + return((*debug).pointeur); +} + +void * +debug_memoire_modification(void *pointeur, size_t taille, + const unsigned char *fonction, unsigned long ligne, + const unsigned char *argument) +{ + struct_memoire *element_courant; + + if (pointeur != NULL) + { + if (taille == 0) + { + // Revient à free() + debug_memoire_retrait(pointeur); + return(NULL); + } + else + { + // Réallocation réelle + + pthread_mutex_lock(&mutex_allocation); + + element_courant = debug; + + while(element_courant != NULL) + { + if ((*element_courant).pointeur == pointeur) + { + break; + } + + element_courant = (*element_courant).suivant; + } + + if (element_courant == NULL) + { + pthread_mutex_unlock(&mutex_allocation); + return(NULL); + } + + pthread_mutex_unlock(&mutex_allocation); + + if (((*element_courant).pointeur = realloc(pointeur, taille)) + == NULL) + { + return(NULL); + } + + (*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).argument = malloc((strlen(argument) + 1) * + sizeof(unsigned char))) == NULL) + { + return(NULL); + } + + strcpy((*element_courant).fonction, fonction); + strcpy((*element_courant).argument, argument); + + return((*element_courant).pointeur); + } + } + else + { + // Revient à malloc() + pointeur = debug_memoire_ajout(taille, fonction, ligne, argument); + return(pointeur); + } +} + +void +debug_memoire_retrait(void *pointeur) +{ + struct_memoire *element_courant; + struct_memoire *element_precedent; + + pthread_mutex_lock(&mutex_allocation); + + element_courant = debug; + element_precedent = NULL; + + while(element_courant != NULL) + { + if ((*element_courant).pointeur == pointeur) + { + if (element_precedent == NULL) + { + debug = (*debug).suivant; + } + else + { + (*element_precedent).suivant = (*element_courant).suivant; + } + + free((*element_courant).fonction); + free((*element_courant).argument); + free(element_courant); + + break; + } + + element_precedent = element_courant; + element_courant = (*element_courant).suivant; + } + + pthread_mutex_unlock(&mutex_allocation); + + free(pointeur); + + return; +} + +void +debug_memoire_verification(struct_processus *s_etat_processus) +{ + integer8 i; + + struct_memoire *element_courant; + struct_memoire *element_suivant; + + fprintf(stderr, "[%d-%llu] MEMORY LEAK\n", + getpid(), (unsigned long long) pthread_self()); + + pthread_mutex_lock(&mutex_allocation); + + element_courant = debug; + i = 1; + + while(element_courant != NULL) + { + fprintf(stderr, "[%d-%llu] MEDITATION %lld (%llu)\n", getpid(), + (unsigned long long) pthread_self(), i, + (*element_courant).ordre); + fprintf(stderr, "[%d-%llu] P: %p, F: %s(), L: %lu, S: %d\n", + getpid(), (unsigned long long) pthread_self(), + (*element_courant).pointeur, + (*element_courant).fonction, (*element_courant).ligne, + (int) (*element_courant).taille); + fprintf(stderr, "[%d-%llu] A: %s\n", getpid(), + (unsigned long long) pthread_self(), + (*element_courant).argument); + + switch(i) + { + // Affichage des méditations + case 1: + { + break; + } + } + + i++; + + element_suivant = (*element_courant).suivant; + free((*element_courant).fonction); + free((*element_courant).argument); + free(element_courant); + element_courant = element_suivant; + } + + pthread_mutex_unlock(&mutex_allocation); + + fprintf(stderr, "[%d-%llu] END OF LIST\n", getpid(), + (unsigned long long) pthread_self()); + + return; +} + +#endif + // vim: ts=4