Question

S'il vous plaît aider! Je suis vraiment à bout de forces. Mon programme est un petit gestionnaire de notes personnelles (google pour "cintanotes"). Sur certains ordinateurs (et bien sûr, je n'en possède aucun), il se bloque avec une exception non gérée juste après le démarrage. Rien de spécial à propos de ces ordinateurs ne peut être dit, sauf qu'ils ont tendance à avoir des processeurs AMD.

Environnement: Windows XP, Visual C ++ 2005/2008, WinApi brut.

Voici ce qui est certain à propos de ce "Heisenbug":

1) Le crash ne survient que dans la version Release.

2) Le crash disparaît dès que je supprime tout ce qui concerne GDI.

3) BoundChecker n'a pas à se plaindre.

4) L'écriture d'un journal montre que le crash se produit lors de la déclaration d'une variable int locale! Comment cela pourrait-il être? Corruption de mémoire?

Toutes les idées seraient grandement appréciées!

UPDATE: j'ai réussi à faire déboguer l'application sur un "quotient défectueux". PC. Les résultats:

"Exception non gérée à 0x0044a26a dans CintaNotes.exe: 0xC000001D: Instruction illégale."

et le code se casse sur

0044A26A cvtsi2sd xmm1, dword ptr [esp + 14h]

Il semble donc que le problème réside dans le "Jeu d'instructions amélioré / Génération de code / Activer" " option du compilateur. Il a été défini sur "/ arch: SSE2". et se plantait sur les machines qui ne supportaient pas SSE2. J'ai défini cette option sur "Non défini". et le bug est parti. Ouf!

Merci beaucoup à tous pour votre aide !!

Était-ce utile?

La solution

Donc, il ne se bloque pas lorsque la configuration est Configuration DEBUG? Il y a beaucoup de choses différentes d'une configruation RELEASE: 1.) Initialisation des globals 2.) Code machine généré, etc.

La première étape consiste donc à rechercher les réglages exacts pour chaque paramètre en mode RELEASE par rapport au mode DEBUG.

-AD

Autres conseils

  

4) L'écriture d'un journal montre que le crash se produit lors de la déclaration d'une variable locale int! comment cela pourrait-il être? Corruption de mémoire?

Quel est le code sous-jacent dans l'exécutable / l'assembly? La déclaration de int n'est pas du tout un code et ne peut donc pas planter. Est-ce que vous initialisez int d'une manière ou d'une autre?

Pour voir le code à l'origine du crash, vous devez effectuer ce qu'on appelle une analyse post-mortem.

Rapport d'erreurs Windows

Si vous souhaitez analyser le crash, vous devez obtenir un vidage sur incident. Une option pour cela est de vous enregistrer pour le rapport d'erreurs Windows - nécessite de l'argent (vous avez besoin d'un ID de signature de code numérique) et du remplissage de formulaires. Pour plus d'informations, visitez le site https://winqual.microsoft.com/ .

Obtenez le vidage sur incident destiné au WER directement auprès du client

Une autre option consiste à entrer en contact avec un utilisateur confronté au crash et à obtenir directement de lui un vidage sur le crash destiné à WER. L’utilisateur peut le faire s’il clique sur les détails techniques avant d’envoyer le blocage à Microsoft. L’emplacement du fichier de vidage sur incident peut être vérifié à cet endroit.

Votre propre minidump

Une autre option consiste à enregistrer votre propre gestionnaire d'exceptions, à gérer l'exception et à écrire un minidump où vous le souhaitez. Vous trouverez une description détaillée à l'adresse Débogage post-mortem de votre projet de code avec votre application, Visual Studio et Minidumps. Article NET .

  

1) Le crash ne survient que dans la version Release.

C’est généralement le signe que vous utilisez un comportement qui n’est pas garanti, mais qui est vrai dans la version de débogage. Par exemple, si vous oubliez d'initialiser vos variables ou d'accéder à un tableau hors limites. Assurez-vous que vous avez activé toutes les vérifications du compilateur (/ RTCsuc). Vérifiez également des éléments tels que l’ordre d’évaluation des paramètres de la fonction (ce qui n’est pas garanti).

  

2) Le crash disparaît dès que je supprime tout ce qui concerne GDI.

Peut-être que c'est un indice que vous faites quelque chose de mal avec les choses liées à GDI? Utilisez-vous HANDLE après avoir été libérés, par exemple?

Téléchargez le package Outils de débogage pour Windows . Définissez les chemins de symbole correctement, puis exécutez votre application sous WinDbg. À un moment donné, il y aura rupture avec une violation d'accès. Ensuite, vous devriez lancer la commande "! Analyse -v", qui est très intelligente et devrait vous donner un indice sur ce qui ne va pas.

La plupart des bogues heisenbugs / release-only sont dus à un flux de contrôle qui dépend de lectures de mémoire non initialisée / d'indicateurs obsolètes / de mémoire tampon passée, ou de conditions de concurrence, ou des deux.

Essayez de remplacer vos allocateurs afin qu’ils mettent à zéro la mémoire lors de l’allocation. Le problème disparaît-il (ou devient-il plus reproductible?)

  

L'écriture d'un journal montre que le crash se produit lors de la déclaration d'une variable int locale! Comment cela pourrait-il être? Corruption de mémoire?

Débordement de pile! ;)

  

4) L'écriture d'un journal montre que le crash se produit lors de la déclaration d'une variable locale int! comment cela pourrait-il être? Corruption de mémoire

J'ai trouvé la cause de nombreux "accidents étranges". déréférencer un this brisé à l'intérieur d'une fonction membre dudit objet.

Que dit l'accident? Violation d'accès ? Une exception? Ce serait un indice supplémentaire pour résoudre ce problème avec

Assurez-vous de ne pas avoir subi de corruption de mémoire à l'aide de PageHeap.exe

Assurez-vous que la pile ne déborde pas (tableau CBig [1000000]]

Assurez-vous de ne pas avoir de mémoire non initialisée.

De plus, vous pouvez exécuter la version finale également à l'intérieur du débogueur, une fois que vous avez généré les symboles de débogage (ce qui ne revient pas à créer une version de débogage) pour le processus. Parcourez et voyez si vous recevez des avertissements dans la fenêtre de trace du débogueur.

& 4; L’écriture d’un journal montre que le crash se produit lors de la déclaration d’une variable locale int! Comment cela pourrait-il être? Corruption de mémoire? & Quot;

Cela pourrait indiquer que le matériel est en fait défectueux ou poussé trop fort. Découvrez s'ils ont overclocké leur ordinateur.

Quand j’obtiens ce genre de chose, j’essaie d’exécuter le code via gimpels PC-Lint (analyse de code statique) car il vérifie différentes classes d’erreurs dans BoundsChecker. Si vous utilisez Boundschecker, activez les options d’empoisonnement de la mémoire.

Vous mentionnez les processeurs AMD. Avez-vous déjà vérifié s'il existait une version et / ou une configuration similaire de la carte graphique / pilote sur les ordinateurs en panne? Cela plante-t-il toujours ou juste de temps en temps? Peut-être exécuter l'outil Informations système sur ces machines et voir ce qu'elles ont en commun,

Cela ressemble à une corruption de pile pour moi. Mon outil préféré pour retrouver ces informations est IDA Pro . Bien sûr, vous n'avez pas accès à la machine de l'utilisateur.

Certains contrôleurs de mémoire ont du mal à détecter la corruption de la pile (s’il en est ainsi). Le moyen le plus sûr d’obtenir ceux que je pense est l’analyse d’exécution.

Cela peut également être dû à une corruption dans un chemin d’exception, même si l’exception a été gérée. Est-ce que vous déboguez avec "Exceptions à la première chance" activées? Vous devriez aussi longtemps que vous le pouvez. Dans de nombreux cas, cela devient agaçant après un certain temps.

Pouvez-vous envoyer à ces utilisateurs une version contrôlée de votre application? Consultez Minidump pour gérer cette exception et l'écrire. une décharge. Ensuite, utilisez WinDbg pour déboguer de votre côté.

Une autre méthode consiste à écrire des journaux très détaillés. Créer un " Consigner chaque action " " et demandez à l’utilisateur de l’activer et de vous l’envoyer aussi. Videz la mémoire dans les journaux. Découvrez '_CrtDbgReport ()' sur MSDN.

Bonne chance!

EDIT:

En réponse à votre commentaire: Une erreur sur une déclaration de variable locale ne me surprend pas. J'ai souvent vu ça. Cela est généralement dû à une pile corrompue.

Certaines variables de la pile peuvent être exécutées sur ses limites, par exemple. Tout l'enfer se déchaîne après ça. Ensuite, les déclarations de variables de pile génèrent des erreurs de mémoire aléatoires, les tables virtuelles sont corrompues, etc.

Chaque fois que je les vois depuis longtemps, je dois aller chez IDA Pro. Le débogage détaillé du désassemblage d'exécution est la seule chose que je sache qui obtient ces informations de manière fiable.

De nombreux développeurs utilisent WinDbg pour ce type d’analyse. C'est pourquoi j'ai également suggéré Minidump.

Essayez Rational (IBM) PurifyPlus. BoundsChecker ne détecte pas beaucoup d'erreurs.

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