J'ai un programme qui me demande l'erreur dans VS2010, dans le débogage:
Error: Stack around the variable 'x' was corrupted
Cela me donne la fonction où un débordement de pile est susceptible de se produire, mais je ne peux pas voir visuellement où est le problème.
Existe-t-il un moyen général de déboguer cette erreur avec VS2010? Serait-il possible d'indiquer quelle opération d'écriture écrase la mémoire de pile incorrecte?
Existe-t-il un moyen général de déboguer cette erreur avec VS2010?
Non, il n'y en a pas. Ce que vous avez fait est en quelque sorte d'invoquer un comportement indéfini. La raison pour laquelle ces comportements ne sont pas définis est que le cas général est très difficile à détecter/diagnostiquer. Parfois, il est impossible de le faire.
Cependant, il existe un nombre assez restreint de problèmes qui causent généralement votre problème:
free
pour quelque chose alloué avec new
, etc.),Cela peut être causé par plusieurs problèmes, généralement difficiles à voir:
delete
une variable affectée avec new[]
ou delete[]
une variable affectée à new
delete
quelque chose alloué avec malloc
delete
une variable de stockage automatiqueSi ce n'est pas immédiatement clair, je mettrais la main sur un débogueur de mémoire (je peux penser à Rational Purify pour Windows).
En fait, ce que vous voyez est assez informatif, vous devriez vous enregistrer près de x emplacement de variable pour toute activité pouvant causer cette erreur.
Voici comment vous pouvez reproduire une telle exception:
int main() {
char buffer1[10];
char buffer2[20];
memset(buffer1, 0, sizeof(buffer1) + 1);
return 0;
}
va générer (VS2010):
Échec de la vérification au moment de l'exécution n ° 2 - La pile autour de la variable 'buffer1' était corrompue.
manifestement, memset a écrit 1 caractère plus qu'il ne le devrait. VS avec option\GS permet de détecter de tels débordements de mémoire tampon (que vous avez activés). Pour plus d’informations, lisez ceci: http://msdn.Microsoft.com/en-us/library/Aa290051 .
Vous pouvez par exemple utiliser le débogueur et le code pas à pas, chaque fois que vous regardez le contenu de votre variable, son évolution. Vous pouvez également tenter votre chance avec des points d'arrêt de données, vous définissez un point d'arrêt lorsque certains emplacements de mémoire changent et le débogueur s'arrête à ce moment-là, ce qui peut éventuellement vous indiquer où se trouve le problème. Mais cela pourrait ne pas fonctionner avec le drapeau\GS.
Pour détecter les débordements de tas, vous pouvez utiliser l'outil gflags.
Ce message peut également être dû à une violation des limites du tableau. Assurez-vous que votre fonction (et chaque fonction appelée, en particulier les fonctions membres pour les objets basés sur une pile) obéit aux limites des tableaux pouvant être utilisés.
Cette erreur m'a laissé perplexe pendant des heures. Je connais les causes possibles. Celles-ci sont déjà mentionnées dans les réponses précédentes, mais je n'alloue pas de mémoire, n'accède pas aux éléments d'un tableau, ne renvoie pas les pointeurs sur des variables locales. .
Puis finalement trouvé la source du problème:
*x++;
L'intention était d'incrémenter la valeur indiquée. Mais en raison de la priorité précédée de ++
, déplacer le pointeur x
vers l'avant puis *
ne fait rien, puis écrire dans *x
endommagera le canari de la pile si le paramètre provient de la pile, ce qui fait grief à VS.
Le changer en (*x)++
résout le problème.
J'espère que cela t'aides.
Voici ce que je fais dans cette situation:
Définissez un point d'arrêt à un emplacement où vous pouvez voir la valeur (correcte) de la variable en question, mais avant que l'erreur se produise. Vous aurez besoin de l'adresse mémoire de la variable dont la pile est corrompue. Parfois, je dois ajouter une ligne de code pour que le débogueur me donne l'adresse facilement (int * x = & y)
À ce stade, vous pouvez définir un point d'arrêt de la mémoire (Débogage-> Nouveau point d'arrêt-> Nouveau point d'arrêt des données)
Hit Play et le débogueur devraient s'arrêter lorsque la mémoire est écrite. Recherchez la pile (le mien insère généralement un code d'assemblage) pour voir comment on appelle.
Je suis généralement la variable avant la variable qui se plaint qui m'aide généralement à résoudre le problème. Mais cela peut parfois être très complexe sans aucun indice comme vous l'avez vu. Vous pouvez activer le menu Débogage >> Exceptions et cocher la case "Exceptions Win32" pour intercepter toutes les exceptions. Cela ne détectera toujours pas ces exceptions, mais cela pourrait intercepter autre chose qui pourrait indirectement indiquer le problème.
Dans mon cas, cela était dû à la bibliothèque que j'utilisais. Le fichier d’en-tête que j’ai inclus dans mon projet ne correspond pas tout à fait au fichier d’en-tête de cette bibliothèque (sur une ligne).
Il y a une erreur différente qui est aussi liée:
0xC015000F: le contexte d'activation en cours de désactivation n'est pas le plus récemment activé un.
Lorsque j'en ai eu marre de recevoir le message mystérieux sur la pile corrompue sur mon ordinateur sans informations de débogage, j'ai essayé mon projet sur un autre ordinateur et il me donnait plutôt le message ci-dessus. Avec la nouvelle exception, j'ai été en mesure de trouver la solution.
J'ai rencontré ce problème lorsque j'ai créé un tableau de 13 éléments avec le pointeur, puis j'ai essayé de définir le 14ème élément. Changer le tableau en 14 éléments a résolu le problème. J'espère que cela aide certaines personnes ^ _ ^