Question

J'ai essayé de localiser un bogue de plantage intermittent dans mon code (qui utilise setjmp), et je l'ai réduit à: apparaît lors de la compilation avec / O2, disparaît avec / O2 / Oy-, c'est-à-dire ne montre que vers le haut avec le pointeur d'omission de cadre.

http://msdn.microsoft.com /en-us/library/2kxx5t2c(v=vs.80).aspx suggère que setjmp nécessite un pointeur de cadre. Ainsi:

  1. Il semble que lorsqu'un programme qui utilise setjmp est compilé avec / O2, Visual C ++ génère silencieusement du code qui provoque une corruption intermittente de la pile. Est-ce vrai ou est-ce que je manque quelque chose?

  2. Il me semble que seule la fonction qui invoque setjmp devrait avoir besoin d'être compilée avec frame pointer, le reste du programme - même les fonctions qui appellent longjmp - devraient pouvoir omettre frame pointer. Est-ce vrai?

Modifier: je l'ai affiné un peu plus.

L'activation du pointeur de cadre sur la fonction qui appelait setjmp ne faisait aucune différence, mais c'est parce que le compilateur le faisait déjà, comme il se doit, remarquant évidemment que cela devait être fait, et le faisait automatiquement.

Ce qui a fait la différence, c'est l'activation du pointeur d'image sur main. Ce n'est pas aussi bizarre que cela puisse paraître, car le crash se manifestait en retour de main. Maintenant que j'y pense, tous les exemples que je peux trouver dans une recherche rapide sur google d'utilisation de setjmp, faites-le en main. Il est peut-être arrivé que l'équipe de compilation Microsoft ne l'ait testé que de cette façon.

Cela étant la manière idiomatique de l'utiliser, peut-être que la meilleure solution serait pour moi de simplement intégrer la fonction utilisant setjmp dans main.

Était-ce utile?

La solution

D'accord, j'ai publié un rapport de bogue avec un cas de test autonome, donc j'espère qu'un correctif est en préparation: http://connect.microsoft.com/VisualStudio/feedback/details/666704/visual-c-génère-un-code-incorrect-avec-omettre-pointeur-cadre-et-setjmp

En attendant, la solution de contournement est de ne pas utiliser le pointeur d'omission de cadre, ou de mettre le code qui appelle setjmp dans main, ou de placer la fonction qui appelle longjmp dans le même fichier source que l'appel à setjmp.

Autres conseils

Pouvez-vous préciser plus d'informations sur le crash lui-même?Je veux dire, quel code le compilateur a généré pour le longjmp, le crash se produit-il immédiatement après le longjmp, ou lorsque vous essayez d'accéder à des variables automatiques, ou lorsque vous essayez de quitter la fonction?

Je suppose que la fonction target doit être compilée avec un cadre de pile standard, il ne semble y avoir aucune limitation raisonnable à la fonction qui utilise longjmp.

setjmp est implémenté de différentes manières, mais cela a probablement quelque chose à voir avec l'implémentation de l'assembly pour votre système d'exploitation particulier.

Lorsqu'une fonction est compilée en utilisant __stdcall, les arguments sont stockés par rapport au pointeur de cadre.Votre implémentation peut accéder aux arguments de setjmp par rapport audit pointeur afin de ne pas avoir à effacer plusieurs registres en leur sauvegardant le contexte (car cela ruinerait une grande partie du point de setjmp);Il me semble me souvenir que setjmp est implémenté de cette manière dans le noyau Linux.

Bien sûr, si msvc ne génère pas d'instructions pour définir ebp, cela ne fonctionnera pas et provoquera sûrement un plantage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top