
Finalement, j'ai opté pour une approche toute neuve (pour moi) pour ce problème de malloc. C'est toujours via gdb que j'attaque le problème, mais je laisse tomber la sur-couche graphique (ddd) au profit d'un petit script perl. Celui-ci va placer les breakpoints à l'entrée et à la sortie des fonctions "malloc" et "free" (ainsi qu'à des emplacements stratégiques dans les opérateurs
new et
delete du C++) et enregistrer consciencieusement la pile d'appels, le contenu des registres du processeur ARM9 et le contenu du tableau __malloc_av_ dont j'ai parlé précédemment, et qui représente la "partie visible" de l'état maintenu par malloc.
Ce côté "totalement automatique" permet d'obtenir une trace exhaustive (64Mo) de ce qui s'est passé au niveau gestion de la mémoire pendant l'exécution du programme, que je peux ensuite traiter avec d'autres scripts. Par exemple pour vérifier qu'il y a bien eu un appel a
free avant chaque
delete operator, et surtout qu'il y a un
malloc()=X pour chaque
free(X), et l'emplacement dans la trace de la dernière opération sur l'adresse X dans le cas contraire.
Avec un peu d'ajustement, je devrais même être capable de trouver les malloc() pour lesquels il n'y a aucun
free .. et donc potentiellement d'identifier les
fuites de mémoire dans mon code. Bien sûr, il existe d'autres programmes pour faire ça, et ce de manière plus automatique (valgrind, si ma mémoire est bonne). Il y a aussi des implémentations qui intègrent ce genre de tests (cf. la variable d'environnement MALLOC_CHECK_ sous Linux) ... je profite du côté "hobby" de ce projet pour découvrir et tester des hypothèses, me construire de petits outils et tout ça ...
Et j'ai finalement mis le doigt sur le problème ... une bête initialisation manquante dans la classe GobState. C++ n'aide vraiment pas le programmeur, de ce point de vue-là. Je devrais m'habituer à compiler avec -Weffc++, s'il ne contenait pas une quantité ridicule de warnings qui me sont inutiles.