Bonsoir,
J'ai un drôle de truc qui m'arrive dans mon projet ... Lorsque j'utilise un débuger pour voir ce qui se passe, lorsque l'instruction return NULL; est exécutée à la fin d'une fonction, j'ai un NULL qui vient se mettre quelque part dans ma structure de donnée. Je n'y comprend rien.
J'ai bien vérifié, du coté où on appelle la fonction, le résultat arrive dans une variable toute neuve, je n'y comprend rien.
je me demande si ce ne serait pas un bug de GCC ... mais cela ne semble pas être le cas car que ce soit avec GCC-4.0 ou GCC-3.4 la même chose se produit.
-----
Mon projet (que j'appelle moon pour le moment, pas très original, je sais) consiste à créer un langage de programmation dans le style lisp/scheme mais pas exactement pareil (sinon, je prendrait ce qui existe). Pour cela, j'utilise le garbage collector Hans Boehm [2] mais je ne pense pas que le problème vienne de là.
Ce qui se passe, c'est que lors de l'exécution, j'ai une pile d'objets qui permet notament à un objet enfant de parcourir tous ses parents à la recherche de la définition d'une variable. Ainsi, certains objets sont dotés d'un environnement, c'est à dire globalement un pointeur void* et un pointeur sur une fonction qui doit permettre de dire si la variable recherchée est définie dans cet environement.
Je ne sais vraiment pas quoi faire, je ne vois pas bien quelle pourrait être la cause de tout ça. Et surtout je ne vous pas comment l'instruction return pour modifier des données dans le tas, de plus, logiquement, la valeur de retour ne passe que dans des registres [3] (du moins sur une architecture x86).
Si quelqu'un veut voir ma source, c'est par là [1] ou par là [4] (bazaar-ng). Pour compiler, il faut cmake [5] et le bon garbage collector [2]. Ensuite il suffit de lancer la commande cmake . pour configurer la sources puis make pour construire l'exécutable.
Il suffit de lancer la commande ./moon test.moon pour que l'erreur se produise. Le fichier .kdbgrc.moon contient ce qu'il faut pour lancer kdbg.
Pour bien la voir, il faut lancer un débuger et metre un point d'arrêt dans la fonction moon_environment_resolve dans moonlib/environment.c [6]. les deux premières fois que le programme est arrêté, relancer l'exécution, c'est à la 3e fois qu'on peut continuer en pas à pas et voir que l'instruction return NULL met NULL dans parents->stack.
Pour info, la fonction appelante, est moon_resolve dans le fichier moonlib/core-inline.h [7]
je ne vous demande pas de réparer complètement mon code, mais juste de m'aider à voir où il pourrait y avoir un truc qui cloche ... car je ne vois pas du tout :(
Merci de toute aide
Mildred
--
[1] http://bzr.mildred632.free.fr/viewsource/Projects/moon-c-gc
[2] http://www.hpl.hp.com/personal/Hans_Boehm/gc/
[3] http://en.wikipedia.org/wiki/Calling_convention
[4] http://bzr.mildred632.free.fr/Projects/moon-c-gc/moon-src.ta(...)
[5] http://cmake.org
[6] http://bzr.mildred632.free.fr/viewsource/Projects/moon-c-gc/(...)
[7] http://bzr.mildred632.free.fr/viewsource/Projects/moon-c-gc/(...)
# bizarre
Posté par left . Évalué à 5.
moon-c-gc/common/strbuf.c:buffer_to_string_delete
(...)
Free(B);
Free(B->data);
(...)
c'est normal ou pas?
parce que ton pb, je trouve que ça sent fort la corruption de heap, quand même.
[^] # Re: bizarre
Posté par Mildred (site web personnel) . Évalué à 2.
Je pense bien que l'erreur doit se trouver ailleurs, invisible, mais comment savoir où ? J'ai essayé la compilation avec Electric Fence alors normalement, tout débordement devrait être détecté ...
[^] # Re: bizarre
Posté par B. franck . Évalué à 3.
Comme le post précédent le dit, c'est une corruption de mémoire.
http://valgrind.org/
[^] # Re: bizarre
Posté par jlh . Évalué à 3.
et son adresse est retournée comme résultat en fin de fonction, mais cet espace mémoire doit être réutilisé après par d'autre fonctions.
Tu peux enlever la variable stack et remplacer le memcpy par un moonS_copy.
Mais ....
... dans moon_resolve, la variable parents est un pointeur vers une
zone mémoire allouée par un malloc et un peu plus loin, cette adresse est écrasée par : parents = moon_find_envS(parents);
donc tu ne peux plus libérer cette zone.
[^] # Re: bizarre
Posté par Mildred (site web personnel) . Évalué à 2.
Merci beaucoup pour cette aide
Ce n'est pas gênant, c'est le garbage collector qui s'en charge :)
En cherchant sur google "heap corruption", j'ai trouvé mpatrol ... et lorsque je l'ai utilisé, il m'a dit
De plus, maintenant, electric fence me fait un joli segfault, je vais pouvoir débuger comme avant.
merci beaucoup
[^] # Re: bizarre
Posté par Jllc . Évalué à 2.
Depuis un an, je développe beaucoup en C sur un projet, et pour beaucoup d'erreur, le code fautif était très loin de l'endroit où se manifestait le plantage. Tout simplement parce que l'erreur, par exemple un dépassement de tampon, écrasait des données qui n'étaient utilisée que plus loin.
Maintenant, comment savoir où ... Utiliser Electric Fence était une bonne idée, mais ne résoud pas tout. Valgrind, mentionné par quelqu'un d'autre peut aider.
Sinon, reste à étudier le code, ajouter des informations de débugage, en affichant par exemple le contenu d'un tas de structures. Pour mes développements, sur lequels je suis plus ou moins une logique objet, j'ai pour chacune de mes structures de données une fonction qui en affiche le contenu, avec les adresses des pointeurs. Afficher ces infos avant et après des appels de fonctions peut permettre de contrôler quels pointeurs/contenus ont été modifiés.
[^] # Re: bizarre
Posté par Krunch (site web personnel) . Évalué à 4.
Programmer proprement quoi. Une fois qu'on fait ça, retrouver un bug devient généralement bien plus facile pour la simple raison qu'on le trouve plus tôt dans le développement.
Voir aussi le guide superflu de programmation en langage C :
http://docs.happycoders.org/orgadoc/dev/C/c-superflu.pdf
Pour ce qui est de l'affiche des structures des données, c'est plutôt du ressort du debugger (ddd marche bien pour ça) même s'il est vrai que dans certains cas ça reste plus pratique d'avoir une fonction d'affichage à côté.
À ce sujet j'ai commencé un vague argumentaire à l'encontre du "printf()-debugging". Faudra que je pense à en faire un vrai texte un jour.
http://www.krunch.be/vrac/txt/printf-debugging-harmful
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
[^] # Re: bizarre
Posté par Mildred (site web personnel) . Évalué à 2.
Pour le printf debugging, je ne vois pas trop ce qu'il y a de mal à ça, si on s'y prend bien. Ce n'est pas la solution ultime mais ca peut aider à voir où est le problème.
Et c'est comme ça que je fesait au début (avant de découvrir kdbg puis ddd), et c'est comme ça que je fais toujours avec des langages comme php.
Tu pourrais peut être en faire un journal pour expliquer ton point de vue à fond ... ça m'intéresserait.
Mildred
[^] # Re: bizarre
Posté par Krunch (site web personnel) . Évalué à 2.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
# Merci à tous
Posté par Mildred (site web personnel) . Évalué à 2.
Je pense que le problème venait de la fonction moon_find_envS() qui retournait un objet alloué sur la pile ... forcément, ca ne peux pas marcher.
Encore merci.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.