web-dev-qa-db-fra.com

Visual Studio - Comment trouver la source des erreurs de corruption de segment de mémoire

Je me demande s’il existe un moyen efficace de rechercher le code source à l’origine d’une erreur de corruption de segment de mémoire, étant donné l’adresse mémoire des données écrites «en dehors» du bloc de segment alloué dans Visual Studio;

La liste d'éléments libres 26F7F670 (0008) est de mauvaise taille (morte)

(Essayer d'écrire quelques notes sur la façon de trouver des erreurs de mémoire)

Merci d'avance!

25
Danne

Commencez par installer windbg:

http://www.Microsoft.com/whdc/Devtools/Debugging/default.mspx

Ensuite, activez le saut de page comme ceci:

gflags.exe –p /enable yourexecutable.exe /full

Cela insérera une page non accessible en écriture après chaque allocation de tas.

Après ce lancement de l'exécutable à l'intérieur de windbg, toutes les écritures en dehors du tas seront désormais capturées par ce débogueur. Pour tourner le saut de page ensuite, utilisez ceci:

gflags.exe -p /disable yourexecutable.exe

Plus d'informations sur l'utilisation du pageheap ici .

46
Andreas Brinck

Pour Windows 10, vous pouvez activer l’option PageHeap dans l’outil GFlags , cet outil faisant partie des outils de débogage pour Windows

Les options de tas de page dans GFlags vous permettent de sélectionner la vérification de tas standard ou la vérification de tas de page entière. Attention, la vérification du tas complet utilise une page complète de mémoire pour chaque allocation, ce qui peut entraîner une insuffisance de mémoire système.

Pour activer le segment de page dans GFlags: 

• Pour activer la vérification de tas de page standard, la version standard écrit un modèle à la fin de chaque allocation de segment, puis examine le modèle lorsque les allocations sont libérées. 

Pour vérifier tous les processus, utilisez:

gflags/r + hpa

gflags/k + hpa

pour un usage unique:

gflags/p/enable ImageFileName

• Pour activer la vérification de tas page complète pour un processus, cette option place une page inaccessible à la fin de chaque affectation de sorte que le programme s'arrête immédiatement s'il tente d'accéder à la mémoire au-delà de l'allocation. processus unique en raison de la consommation importante de mémoire.

gflags/i ImageFileName + hpa

gflags/p/enable ImageFileName/full

Les deux commandes ci-dessus sont interchangeables. 

Remarque: tous les paramètres de segment de page mentionnés ci-dessus sont des paramètres système stockés dans le registre (sauf/k) et restent effectifs jusqu'à ce que vous les changiez. Le paramètre/k est un paramètre d'indicateur de noyau défini pour cette session et sera perdu à la fermeture de Windows.

Un autre outil utile est le Application Verifier , mais il ne fait pas partie des outils de débogage pour Windows. Il est plutôt inclus dans le Kit de développement logiciel Windows

4
Merav Kochavi

Peut-être que vous pouvez essayer le vérificateur d'applications de Microsoft. Il a résolu un problème similaire une fois pour moi, en activant des vérifications supplémentaires sur les opérations de tas. montrer jusqu'à ce que quelque chose de gros arrive au tas (comme l'allocation massive/libre).

3
Smithy

Vous pouvez définir un point d'arrêt lors d'une écriture sur l'adresse de la mémoire. Le débogueur vous montrera ensuite le code qui écrit dans l'emplacement, mais vous devez toujours déterminer laquelle des écritures est à l'origine du problème.

2
Timo Geusch

C'est probablement trop tard, mais s'il compile avec gcc et peut fonctionner sur linux, vous pouvez utiliser valgrind pour trouver la source du problème (je ne me souviens pas des drapeaux, je ne l'ai utilisé qu'une fois avec beaucoup de succès).

2
user34537

plus d'infos sur Gflags et PageHeap (qui ont beaucoup aidé): http://msdn.Microsoft.com/en-us/library/windows/hardware/ff549561%28v=vs.85%29.aspx

2
NoAngel

Je suppose que C++ est le langage.

Si l'erreur est reproductible et que l'adresse corrompue est toujours la même, vous pouvez définir un point d'arrêt des données pour arrêter le programme lors de l'écriture à cette adresse.

1
Timores

Assurez-vous que toutes les bibliothèques auxquelles vous vous connectez sont compilées dans la même version CLR que l'application que vous exécutez - toutes dans Release ou toutes dans Debug.  

Lorsque vous compilez dans Debug et Release, vous ciblez en fait deux versions différentes de la bibliothèque d'exécution C. Ces versions sont très différentes et utilisent des stratégies différentes pour allouer de la mémoire et utilisent différents tas. Mais la chose la plus importante à savoir est qu’ils ne sont PAS compatibles les uns avec les autres.

La bibliothèque d'exécution de la Release C a alloué de la mémoire comme prévu, alors que le débogage ajoutera des informations supplémentaires, telles que des blocs de garde pour suivre le dépassement de mémoire tampon et l'emplacement qui a appelé la fonction d'allocation, et alloue à son tour plus de mémoire que la Release. 

Si vous liez votre application à un mélange de DLL construites dans Release et Debug, vous finirez probablement par essayer de supprimer un objet dans un CLR créé dans un autre. Cela signifie que vous allez essayer de libérer plus ou moins de mémoire que celle allouée à l'objet, ce qui peut corrompre le tas. 

Vous devez créer votre application, ainsi que l’attacher à des bibliothèques construites sous la même configuration, soit Release, soit Debug. 

Ce problème peut se produire en particulier dans les modules compilés avec différents compilateurs.

Il existe un moyen de contourner le problème, que je vais mentionner mais que je ne recommande pas. Si, pour une raison quelconque, vous devez encore créer différents modes, cette solution permet d'affecter et de libérer toute la mémoire du même segment de mémoire partagé. L'API GetProcessHeap vous permettra d'accéder au segment de mémoire partagé à travers les différents modules. En utilisant HeapAlloc & HeapFree, vous pouvez allouer et libérer de la mémoire dans le segment de mémoire partagé. Remarque: HeapAlloc et HeapFree doivent remplacer tous les appels à malloc et free dans votre application.

0
Merav Kochavi