I. Construction du gestionnaire de mémoire SYSALLOC▲
I-A. Construire un environnement de développement pour la bibliothèque CLIB▲
.../clib/ed/inc
.../clib/ed/src
.../clib/ed/lib
I-B. Récupérer les fichiers▲
Dans …/inc :
- bits.h
- cnt.h
- cnt_err.itm
- mem.h
- pc_dbg.h
- sys.h
- sysalloc.h
- types.h
Dans …/src :
- assert.c
- cnt.c
- sys.c
- sysalloc.c
Les quatre fichiers source servent éventuellement à générer la bibliothèque.
Bien sûr, on n’est pas obligé de générer la bibliothèque, on peut aussi ajouter ces fichiers au projet.
I-C. Créer la bibliothèque▲
Le chemin des fichiers inclus est :
.../clib
Le chemin des fichiers source (.c) est :
.../clib/ed/src
Le chemin de la sortie est :
.../clib/ed/lib
La macro DBG_SYSALLOC doit être définie globalement. Typiquement (Borland C, gcc) :
... -DDBG_SYSALLOC
Générer la bibliothèque (les détails dépendent de l'implémentation).
I-D. Créer une application de test▲
#include "ed/inc/sysalloc.h"
int
main_ (
void
)
{
char
*
p =
malloc (
sizeof
*
p);
return
0
;
}
int
main (
void
)
{
int
ret;
static
char
Trace[1
<<
8
];
SYS_INIT (
Trace, OFF);
ret =
main_ (
);
sys_mem_trace (
);
return
ret;
}
La macro DBG_SYSALLOC doit être définie globalement.
Une fois liée avec la bibliothèque, ce code produit (Borland C 3.1)
SYSALLOC BC++ Ver 4.10 SMALL 60176 MS-DOS
SYSALLOC Overload (21 rec)
SYSALLOC Successful initialization: 21 records available
SYSALLOC min=60128 max=60176 delta=48
SYSALLOC Err: Not-matched list:
SYSALLOC Bloc 12AC (1 byte) malloc'ed at line 5 of 'main.c' not freed
SYSALLOC Released Memory
La fuite mémoire a bien été détectée et identifiée.
II. Utilisation du gestionnaire de mémoire SYSALLOC▲
II-A. Fonctionnement▲
SYSALLOC est un traceur de mouvements. Il repose sur un principe simple qui consiste à détourner les fonctions standard malloc(), calloc(), realloc() et free() au profit de fonctions 'maisons' qui enregistrent les appels et les paramètres avant d'appeler la fonction réelle de la bibliothèque standard. Lors d'une libération, l'enregistrement correspondant est effacé (si possible). Lorsqu'on demande la 'trace', un bilan des opérations est fourni.
II-B. Restrictions▲
SYSALLOC ne remplace pas les fonctions de la bibliothèque standard. Si celles-ci sont appelées directement sans que « ed/inc/sysalloc.h » soit en vu (autres bibliothèques, par exemple), ces appels n'entreront pas dans le bilan et le résultat sera évidement faussé.
II-C. Programme principal▲
On peut s'inspirer du programme de test.
II-C-1. Initialisation, résultats▲
La bibliothèque SYSALLOC ne gère qu'un pointeur statique interne. La mémoire utilisée pour son fonctionnement (journalisation des événements d'allocation) n'est pas définie par défaut. L'utilisateur doit définir un tableau statique d'une taille 'raisonnable et suffisante'.
static
char
Trace[1
<<
8
];
(ici un tableau de 2^8 char, soit 256 bytes). SYS_INIT() 'formatte' la mémoire reçue et affiche le nombre d'enregistrements possible :
<...>
SYSALLOC Successful initialization: 10 records available
<...>
Il n'y a pas de grands calculs à faire. Si la taille est insuffisante, un message d'alerte (surcharge) apparaîtra à l'exécution (stdout), invitant l'utilisateur à agrandir la taille du bloc mémoire (2^9, 2^10, etc.). Il suffit ensuite de recompiler et de relancer.
SYSALLOC Overload (4 rec)
SYS_INIT() se charge d'initialiser correctement SYSALLOC à partir de la mémoire de trace définie par l'utilisateur.
SYS_INIT (Trace, OFF);
Le premier paramètre est le nom du tableau (ne fonctionne pas avec un pointeur, évidemment).
Le deuxième paramètre peut être défini à OFF ou à ON. Par défaut, il est sur OFF. On peut cependant le modifier à ON, recompiler et relancer. Dans ce cas, une trace en temps réel est émise vers stdout à chaque appel de malloc()…free().
II-C-2. Fichier d'entête▲
Il suffit d'inclure :
#include "ed/inc/sysalloc.h"
II-C-3. Diagnostic▲
Pour connaître l'état du gestionnaire de mémoire, il suffit d'appeler la fonction :
sys_mem_trace (
);
En principe, on appelle cette fonction une fois en fin d'exécution.
S’il devait y avoir des sorties directes par exit(), il est plus sûr de modifier le programme principal ainsi :
#include "ed/inc/sysalloc.h"
static
void
on_exit
(
void
)
{
sys_mem_trace (
);
}
int
main (
void
)
{
int
ret;
static
char
Trace[1
<<
8
];
atexit
(
on_exit);
SYS_INIT (
Trace, OFF);
/* application */
ret =
...
return
ret;
}
S’il y a des anomalies, des informations apparaissent sur stdout. (Adresse, taille, emplacement, message d'erreur…)
Bloc non libéré
<...>
SYSALLOC Err: Not-matched list:
SYSALLOC Bloc 12AC (1 byte) malloc'ed at line 5 of 'main.c' not freed
Bloc déjà libéré
<...>
SYSALLOC Err: Not-matched list:
SYSALLOC Bloc 003D2460 freed at line 7 of 'main.c' not allocated
<...>
Si tout se passe bien, un message de 'bonne conduite' apparaît.
<...>
SYSALLOC All-matched
<...>
II-D. Autres programmes▲
Afin de bénéficier des effets de surveillance de SYSALLOC, il faut ajouter :
#include "ed/inc/sysalloc.h"
dans tous les fichiers C du projet utilisant malloc(), calloc(), realloc(), free().