Bonjour,
Je suis en train de reprendre un vieux projet de jeu en C (conçu sous Dos avec gcc/allegro). Tout se passe à peu près bien, sauf que j'arrive à un moment à un "segmentation fault" dont je ne parviens pas à retrouver l'origine (même en plaçant des points d'arrêt sous kdevelop).
Il existe un moyen de savoir exactement quelle ligne des sources provoque le plantage ? Un "coredump" n'est-il pas sensé être créé à ce moment ? J'ai cherché un fichier ressemblant à "core" mais sans succès.
Merci
# générer le core dump
Posté par Cyberdivad . Évalué à 1.
On peut vérifier que le coredump sera bien généré avec la commande
$ ulimit -c
Si le nombre donné vaut 0, aucun coredump ne sera généré. D'après ce que j'ai trouvé, une taille de 1000 devrait suffire :
$ ulimit -c 1000
Maintenant, je lance mon programme et l'exécute jusqu'à atteindre le plantage, et j'ouvre le coredump avec gdb :
% gdb ./testwin core.wxyz
GNU gdb 6.3-debian
[...]
Failed to read a valid object file image from memory.
Core was generated by `./testwin'.
Program terminated with signal 6, Aborted.
Cannot access memory at address 0x40016e28
#0 0x402567ab in ?? ()
(gdb) quit
Bon ben je ne suis pas tellement plus avancé :-) D'après la doc que j'ai trouvé, j'aurais du avoir la liste d'appel des fonctions juste avant le plantage.
Y a-t-il quelque chose (d'évident sûrement) que j'ai raté ?
Merci
[^] # Re: générer le core dump
Posté par Sebastien . Évalué à 3.
ulimit -c unlimited
(ma vie: l'appli sur laquelle je travaille peut me pondre des fois des cores de 50Mo voire plus, donc bon... Ton ulimit me semble un peu limite ;)
[^] # Re: générer le core dump
Posté par Cyberdivad . Évalué à 1.
Dans mon cas, j'ai vu qu'il existait un "liballegro4.1-dbg" (compilés avec les symboles de débuggage). Après l'avoir installé et compilé mon programme avec, gbd me sort enfin une liste conséquente d'appels. Bon, il ne remonte toujours pas jusqu'à mon programme, la dernière ligne faisant référence à libc6 ..
Finalement, j'ai découvert un des trucs qui n'allait pas. Suite à un changement de taille d'une des images du jeu (je ne peux pas trop expliquer le détail ici), je provoquais un dépassement de tableau. Rien à voir avec allegro donc.
Ce n'est pas typiquement le genre de trucs qu'on devrait pouvoir retrouver avec gdb ?
[^] # Re: générer le core dump
Posté par Florent C. . Évalué à 1.
Avec gdb je ne sais pas, mais avec valgrind, oui :)
[^] # Re: générer le core dump
Posté par Ph Husson (site web personnel) . Évalué à 4.
2.Tu peux faire directement gdb ./testwin, la tu lance run et t'attend le segfault
3.C'est pas un segmentation fault, mais un abort, donc volontaire par le programme.
Un grep "abort()" -r lesources pourait aider
4.Dans gdb tu peux faire bt pour voir quelles fonctions ont appellé la fonction planteuses
[^] # Re: générer le core dump
Posté par Cyberdivad . Évalué à 1.
2. Voilà un bon truc, merci :-) Il faut vraiment que je me penche sur la doc des outils comme gdb. C'est le genre de truc que j'aurais aimé apprendre à l'école :-)
3. Ben en fait, il me sortais "abort" si je lançais le programme directement et "segmentation fault" à travers kdevelop. Comme c'est mon propre projet que je reprends, je sais qu'il n'y a aucun abort dans mon code, j'ignorais cet appel jusqu'à maintenant :-) Quoique cet appel se trouve peut-être dans une des fonctions d'allegro, bonne idée à creuser, merci -:)
4. C'est la seule commande que je connaissais déjà dans gdb, avec quit :-)
Merci pour ces pistes.
[^] # Et la pile ?
Posté par Obsidian . Évalué à 2.
Comme dit plus haut, on inclue les symboles de debuggage en compilant avec "-g", on lance gdb ./testwin, on fait run et on attend le segfault.
crashme.c
int main (void)
{
char * ptr =0;
* ptr = '-';
return 0;
}
$ gcc -g crashme.c -o crashme
$ gdb crashme
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0x08048346 in main () at crashme.c:5
5 * ptr = '-';
Et quand on veut savoir d'où on vient, on explore la pile avec un backtrace :
(gdb) bt
#0 0x08048346 in main () at crashme.c:5
#1 0x40043c57 in __libc_start_main () from /lib/i686/libc.so.6
Après il existe "b" pour placer un breakpoint, "s" (step) pour avancer d'une instruction, "n" (next) pour sortir de la fonction en cours, etc. et surtout "help".
Enfin un conseil : Lâche KDevelop un moment ou l'on va croire que tu es perdu sans Visual Studios. Habitues-toi un moment à la ligne de commande, et reviens-y - si tu y tiens encore - quand tu seras devenu un guru ! :-)
[^] # Re: Et la pile ?
Posté par Cyberdivad . Évalué à 2.
Sinon, je ne suis pas un fana de kdevelop à la base. J'ai passé le projet sous cet IDE il y a peu pour une histoire de confort, mais je reprends le C (et ce projet) après l'avoir lâché pour d'autres langages pendant longtemps, et je n'avais jamais eu l'occasion d'aborder ces programmes (gdb, valgrind...) voilà tout :-) Je manque cruellement de connaissances pour ce genre de choses qui sortent du langage et l'algorithmie, mais je sais encore écrire un makefile (je vérifie .. oui ! ouf !). Je dois être récupérable :-)
Au boulot, je travaille sous 4D 6 et je peux te dire que je regrette l'absence d'outils en ligne de commande. On ne peut rien scripter, les sources sont enfermés dans un format binaire qui empêche tout accès par des outils extérieurs (impossible de faire un simple rechercher/remplacer global !). Pas moyen non plus d'automatiser des trucs (stats, compilation, maintenance de la base ..) un cauchemard, mais je m'égare.
# Gdb et printf ...
Posté par Florent C. . Évalué à 3.
Il y a aussi la solution de poser des printf de partout dans ton code pour "tracer" le déroulement de ton code, et quand ça s'arrête, tu sais où ...
Voilà, c'est le système D ...
Sinon pense à utiliser un outil du genre de Valgrind pour débusquer tous tes problèmes d'allocation/déallocation/écriture/lecture en mémoire, car les segfault sont souvent dûs à des défauts de programmation à ces niveaux-là ...
[^] # Re: Gdb et printf ...
Posté par Cyberdivad . Évalué à 2.
Le problème ici était que je ne voyais absolument pas d'où pouvait venir le plantage et ne savais où poser les points d'arrêts (ou les printf).
Sinon, merci pour valgrind, je vais regarder de ce côté et voir comment il fonctionne.
# Efence
Posté par Pinaraf . Évalué à 4.
Grossièrement : quand tu l'actives, sa librairie "remplace" les malloc et realloc standards : ils allouent de la mémoire à la fin des blocs mémoire. Comme ça, quand t'as une erreur d'écriture dans un endroit non autorisé, le segfault est déclenché tout de suite, et donc tu seras bien plus proche du malloc que sans ElectricFence, où le segfault peut avoir lieu 15 minutes après le malloc "défectueux"...
# DDD
Posté par vrm (site web personnel) . Évalué à 2.
http://www.gnu.org/software/ddd/(...)
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.