2010-04-28 20 views
2

Je suis presque désespérée .. Je développe une application de service de terrain pour Windows Mobile 6.1 en utilisant C# et un peu p/Invoquant. (Je pense que je référence environ 50 fonctions natives)Unceschable AccesViolationException

Dans des circonstances normales, cela ne pose aucun problème, mais quand je commence à mettre l'accent sur le GC, je reçois une erreur désagréable 0xC0000005 qui semble inaccessible. Dans mon test je ferme rapidement et ouvre un formulaire de dialogue (le formulaire a fait usage de fonctions natives, mais pour les tests je les ai commentés) et après un moment, le journaliste d'erreur Windows Mobile vient me dire qu'il y avait un fatal erreur dans mon application.

Mon code utilise un try-catch autour du Application.Run(masterForm); et se connecte à l'événement CurrentDomain.UnhandledException, mais l'application se bloque toujours. Même lorsque j'attache le débogueur, Visual Studio me dit juste "La connexion à distance à l'appareil a été perdue" quand l'exception se produit.

Puisque je n'ai pas réussi à attraper l'exception dans l'environnement géré, j'ai essayé pour donner un sens au fichier journal d'Error Reporter. Mais cela n'a aucun sens, la seule chose cohérente à propos de l'erreur est l'application où elle se trouve.

Le thread où l'application se produit est inconnu pour moi, le module où l'erreur se produit diffère de temps à temps (j'ai vu mon application.exe, WS2.dll, netcfagl3_5.dll et mscoree3_5.dll), même le code d'erreur n'est pas toujours le même. (La plupart du temps, il est 0XC0000005, mais je l'ai aussi vu une erreur 0x80000002, qui est un avertissement comptable le premier octet?)

J'ai essayé le débogage par bugtrap, mais étrangement cette plante avec le même code d'erreur (0xC0000005). J'ai essayé d'ouvrir le fichier kdmp avec Visual Studio, mais je ne peux pas donner de sens car il ne montre que le code du désassembleur quand j'entre dans l'erreur (sauf si j'ai les bons fichiers .pbb, ce que je fais 't). Idem pour WinDbg. Pour faire une histoire courte: Je n'ai franchement aucune idée de l'endroit où chercher cette erreur, et j'espère que l'âme brillante de stackoverflow le fera. Je suis heureux de fournir du code mais en ce moment je ne sais pas quelle pièce à fournir ..

Toute aide est grandement appréciée!

[EDIT 3 mai 2010]

Comme vous pouvez le voir dans mon commentaire à Hans Je retesté tout le programme après que je décommenté tous les P/Invoque, mais cela n'a pas résolu mon problème. J'ai essayé de reproduire l'erreur avec le moins de code possible et finalement, il semble que l'accès multi-thread est celui qui me pose tous les problèmes.

Dans mon application, j'ai un contrôle utilisateur qui fonctionne comme une liste de défilement de doigt/flick. Dans ce contrôle, j'utilise un bitmap pour chaque élément de la liste en tant que canevas. Le dessin sur cette toile est géré par un thread séparé et quand je désactive ce thread, l'erreur semble disparaître .. Je vais faire d'autres tests à ce sujet et afficherai les résultats ici.

+0

Jetez un oeil à cette question, on dirait qu'il peut être lié: http://stackoverflow.com/questions/724644/ –

+0

Non, mon bloc de capture ne se appelle pas du tout .. – Roy

Répondre

0

Il s'avère être une exception causée par Interlocked.

Dans mon code, il y a un entier _drawThreadIsRunning qui est mis à 1 lorsque le thread de dessin est en cours d'exécution, et mis à 0 sinon. Je mis cette valeur à l'aide Contrefil:

if (Interlocked.Exchange(ref _drawThreadIsRunning, 1) == 0) { /* run thread */ }

Quand je change cette ligne tout cela fonctionne, il semble qu'il y ait un problème avec threadsafety quelque part, mais je ne peux pas comprendre. (c'est-à-dire je ne veux pas perdre plus de temps à le comprendre)

Merci pour l'aide les gars!

4

La capture de cette exception n'est pas une option. C'est le pire type de crise cardiaque qu'un thread peut subir, le processeur a détecté un problème sérieux et ne peut pas continuer à exécuter du code. Ceci est invariablement causé par un code mal géré, il semble que vous en ayez beaucoup dans votre programme. Vous devez vous concentrer sur le débogage de ce code non géré pour obtenir quelque part.

Les deux causes les plus fréquentes d'un AV sont

  • corruption Heap. Le code non géré a incorrectement écrit des données dans le tas, détruisant ainsi l'intégrité structurelle du tas. Généralement causé par le débordement de la limite d'un bloc de mémoire alloué. Ou en utilisant un bloc de tas après qu'il a été libéré. Très difficile à diagnostiquer, l'exception sera levée longtemps après que le dommage ait été fait.

  • Corruption de pile. Le plus souvent causé par débordement des limites d'un tableau qui a été alloué sur la pile. Cela peut remplacer les valeurs des autres variables de la pile ou détruire l'adresse de retour de la fonction. Un peu plus facile à diagnostiquer, il a tendance à bien se répéter et a un effet immédiat. Un effet secondaire est que le débogueur perd sa capacité à afficher la pile d'appels juste après que le dommage ait été fait.

La corruption de tas est la plus probable et la plus difficile. Cela est généralement abordé en déboguant le code dans la construction de débogage avec un allocateur de débogage qui surveille l'intégrité du tas. L'en-tête <crtdbg.h> en fournit un. Ce n'est pas une approche garantie, vous pouvez avoir des Heisenbugs vraiment méchants qui ne font que monter la tête dans la version Release. Très peu d'options disponibles alors, à part un examen soigné du code. Bonne chance, vous en aurez besoin.

+0

J'ai commenté tout p/Invoque de mon code, a donné une réinitialisation matérielle à l'appareil, et a commencé à tester à nouveau, mais le bugger existe toujours. .. hein? – Roy