Quelles sont les techniques de dépannage des violations d'accès très intermittentes sur un périphérique Windows Mobile?

StackOverflow https://stackoverflow.com/questions/402957

Question

J'ai une grande application Compact Frameworks V2.0 qui, dans la plupart des cas, fonctionne très bien. Une fois par jour environ, sur certains appareils, un utilisateur reçoit une erreur native 0xC0000005 qui n'est pas interceptée avec le bloc Try / Catch géré standard.

Mon application se synchronise avec le serveur via des appels ASMX à intervalles fixes. Le problème semble se produire lors de la synchronisation. En plus de l'appel ASMX qui se passe au moment de la synchronisation, la logique métier est considérable, mais 98% de cela est du code managé. J'ai passé en revue toutes mes bibliothèques P / Invokes et les applications C ++ natives des applications. À ce stade, je suis à peu près certain à 95% que le problème ne se situe pas là.

Comme cela ne se produit que sur certains appareils et très rarement (moins d'une fois par jour), il est très difficile de l'isoler. J'ai instruit mon code et il semble que cela se produise de manière aléatoire dans l'application. Je suppose donc que quelque chose altère la mémoire.

Toutes vos réflexions sur la façon de résoudre ce problème seraient les bienvenues.

Était-ce utile?

La solution 2

La gestion de mes exceptions C ++ natives n'incluait pas d'exception async et ne capturait donc pas les exceptions de violation d'accès.

Cela peut / peut ne pas être utile pour mon problème, mais peut être utile pour les autres.

L'utilisation du commutateur / EHa, comme indiqué dans ce lien, permettra d'attraper ces types d'exceptions:

http://msdn.microsoft.com/en-us/library /1deeycx5.aspx

Autres conseils

Un 0xC0000005 est une violation d'accès. Quelque chose tente de lire ou d'écrire à une adresse à laquelle il n'a pas le droit d'accéder. Celles-ci ont tendance à être très difficiles à trouver et l’expérience est l’un des meilleurs outils (le débogueur de Platform Builder est également très utile, mais c’est une voie de débogage tout à fait distincte et nécessite une expérience que vous n’avez probablement pas ou que vous auriez déjà Essayé). Je trouve que la journalisation a tendance à être moins utile que le codage soustractif - en supprimant les appels P / invoke avec des appels simulés, autant que possible.

Les violations d'accès dans les applications gérées se produisent généralement pour l'une des raisons suivantes:

  • Vous P / invoquez une API native qui transmet un descripteur à un objet géré et l’API native utilise ce descripteur. Si vous obtenez une collection et un compactage pendant l'exécution de l'API native, l'objet géré peut être déplacé et le pointeur devient non valide.
  • Vous P / invoquez quelque chose avec un tampon trop petit ou plus petit que la taille que vous transmettez et l'API dépasse une lecture ou une écriture
  • Un pointeur (IntPtr, etc.) que vous passez à un appel P / Invoke n'est pas valide (-1 ou 0) et le natif ne le vérifie pas avant de l'utiliser
  • Vous appelez / invoquez un appel natif. Le code natif manque de mémoire (généralement virtuelle). Il ne vérifie pas les allocations ayant échoué et lit / écrit sur une adresse non valide
  • Vous utilisez un GCHandle qui n'est pas initialisé ou qui pointe d'une manière ou d'une autre sur un objet déjà finalisé et collecté (il ne pointe donc pas sur un objet, il pointe sur une adresse à laquelle un objet était)
  • Votre application utilise un handle pour quelque chose qui a été invalidé par un sommeil / réveil. C'est plus ésotérique, mais cela arrive certainement. Par exemple, si vous exécutez une application sur une carte de stockage, la totalité de l'application n'est pas chargée dans la RAM. Les pièces en cours d'utilisation sont recherchées pour l'exécution. Tout cela est bien et bon. Maintenant, si vous mettez le périphérique hors tension, tous les pilotes s’éteignent. Lorsque vous redémarrez, de nombreux périphériques remontent simplement les périphériques de stockage. Lorsque votre application doit demander la page dans plus de programme, ce n'est plus où elle était et elle meurt. Un comportement similaire peut se produire avec des bases de données sur des magasins montés. Si vous avez un descripteur ouvert dans la base de données, il se peut que le descripteur de connexion ne soit plus valide après un cycle veille / réveil.

Vous constaterez ici que presque tous sont des invocations P / Invokes et ce n’est pas un hasard. Il est assez difficile d'obtenir du code managé pour le faire lui-même.

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