Thursday, December 21, 2017

Refactored, but freezing

ok donc, j'ai eu du code qui compilait en un rien de temps, malgré un refactoring plutôt osé. Par contre, plus moyen d'atteindre la fin du premier niveau: le jeu freeze, à peu près tout le temps au même endroit, juste avant de m'afficher les premiers "inkjet" mobiles.

Good joke! How useful is it to get refactored code compiling if you cannot reach the exit of level 1 anymore? The game now freezes every time roughly at the same spot, just before the first moving inkjets. I will need my mercurial time machine...

Je prends donc ma machine à remonter le temps (comprenez mercurial) ... le bug semble aussi se produire avant la refactorisation ... j'évite donc de passer pour un clown qui fait des effets d'annonce sur son flux twitter, mais je n'ai quand même pas du code qui marche. J'ai noté que A. avait réussi à rejouer aux premiers niveaux après avoir fini le niveau vertical, donc il existe un point pas trop éloigné dans l'espace-temps où j'ai du code qui n'a pas ce problème.

"Good" news is that the bug wasn't introduced by the refactory -- at least, my twitter-honor is safe. But honor does not make code run. I know that A/S-team could beat levels 1 and 2 during the last playtesting session, so the bug must have been introduced fairly recently. If I could find the last working commit, that would help understanding what went wrong and how to fix it.

Reste à le trouver pour comprendre ce qui cloche. Pour ça, j'ai maintenant mon programme automatique de "unit-testing" qui simule un va-et-vient dans les niveaux.
Et le programme de test en question crashe, lui. Un beau gros "segmentation fault", dû à un débordement de pile. Et la fonction "backtrace" capable de m'indiquer où s'est planté le programme et comment on en est arrivé là prend un plombe à s'exécuter (en fait, j'ai intérêt à l'interrompre):
  • CompoundGob::collide(#288)
  • BlockArea::collision(#1934)
  • InfiniMap::getflags(#350)
  • GameObject::cando(#1786)
  • CompoundGob::loadAnim(#178)
  • CompoundGob::setstate(#52)
  • CompoundGob::collide(#288)
  • BlockArea::collision(#1934)

Hopefully, I now have an automated test that moves back and forth through the levels. And that test program crashes (big segmentation fault) when running one failing build. The backtrace function of my debugger takes ages to point out where the crash occurs (and how the program reached that state). When I interrupt it, I see no memory reference on the "call" instruction. All registers have valid values, no invalid opcode to be spotted around. The only suspicious thing is the fact that there seems to be a repetitive pattern in the function calls.
Then I checked the value of the stack pointer and Captain Obvious knocked on my head.


Oui, vous avez bien vu: on tourne en rond. Et le code fautif serait apparu pendant que j'essayais de corriger le problème des personnages qui jouent à Philadelphia Expérimental avec le plafond.

Mais comme j'ai une release à assurer demain au boulot, je vais pas la faire trop longue. On sait où chercher. On cherchera pendant les congés entre les paquets de Noël et les cotillons ;-)

This is a stack Overflow, caused by something in the new code that enforces alignments when resizing bounding boxes. It is obvious because the stack pointer has the lowest allowed value, given the area allocated as stack according to /proc/self/maps. It is too late to start searching what and why, but at least I know what to look for and roughly where.

edit: trouvé en 20 minutes de "cybook" pendant que *deline travaillait sa danse. Corrigé en à peine davantage. On va pouvoir reprendre le travail sur les plans de scrolling ;-)

got it located while *deline was having her dancing lessons, fixed in about half an hour. I thought it would take me at least a week-end. Good. I'll be able to go on with the rest (todo: figure out what still has to be done)

No comments: