Détecter une erreur dans un processus (en l'occurence svchost.exe)
gerbito
Messages postés39Date d'inscriptionmardi 14 décembre 2004StatutMembreDernière intervention20 octobre 2015
-
23 mai 2008 à 15:34
gerbito
Messages postés39Date d'inscriptionmardi 14 décembre 2004StatutMembreDernière intervention20 octobre 2015
-
30 mai 2008 à 18:37
Bonjour,
Voilà, je développe en C# une appli qui reçoit des données d'un serveur auquel elle est reliée par un modem GPRS. Or cette appli me claque sans grier gare une belle boîte grise intitulée "svchost.exe Application Erreur" commentée comme ceci :
L'instruction à l'adresse 0x77c43dbd référence la mémoire 0x90909090, la mémoire ne peut pas être écrite.
Ca me rappelle un bel incident de segmentation, j'avais le même genre de choses quand j'utilisais des pointeurs en C++ en ayant oublié de les intialiser, sauf je voyais le nom de mon appli C++ à la place de svchost.exe. Mais que si ce genre d'erreur passe au travers du catch(...) en C++, ca s'attrape très bien en C#, NullReferenceException, et j'ai blindé mon code de gestionnaires d'erreurs.
Ca proviendrait donc d'un traitement interne des DLL système que j'utilise dans mon appli (RasApi32.dll pour la connexion et Kernel32.dll). J'ai pourtant bien fait vérifier qu'aucun appel des fonctions des dll système n'est fait avec des pointeurs nuls.
Pourtant mon appli continue de fonctionner, mais elle ne reçoit plus de données du serveur, et la présence de cette boîte grise est horripilante.
Ce qu'il me faudrait, ce serait donc espionner toutes les instances processus svchost, que j'ai réussi à regrouper dans un tableau de la sorte :
Mais, malheureusement je ne peux pas faire pour chaque process de ma liste :
processus.StartInfo.ShellExecute = false;
processus.StartInfo.RedirectStandardError = true;
processus.ErrorDataReceived += new DataReceivedEventHandler(Surveille);
Car évidemment les processus sont déjà lancés quand je veux les surveiller, et cela provoque une erreur à l'éxécution.
Si j'arrive à intercerpter la mise en erreur de svchost au moment ou elle survient, c'est gagné, je pourrais flinguer ce sale svchost pas beau et mon appli pourra continuer sans cette boîte grise affreuse (après bien entendu, avoir relancé la communication avec mon serveur...)
L'un entre vous aurait-il une idée de la marche à suivre ? Cela me serait d'un grand secours.
leprov
Messages postés1160Date d'inscriptionvendredi 23 juillet 2004StatutMembreDernière intervention21 octobre 201017 23 mai 2008 à 16:18
cette erreur me fait plutot penser a une erreur d'overflow d'un buffer. par exemple un pointeur qui tes retourné, tu écrit en dehors des limites et tu écrase le pointeur de retour de la fonction. avant de chercher a faire un workaround, vérifie que tu peux pas fixer ca en commencant par les points suivants :
-assure toi que ton code C# ne détruit pas une zone mémoire qu'il a initilisé. il est fréquent que le GC te supprime une zone mémoire que tu n'as pas initilalisée au bon endroit. par exemple, tu initialize une variable que tu passe par référence a une fonction de l'API, mais cette variable etait locale a la fonction. tu sors de la fonction, le GC passe immédiatement, et le process natif n'a pas eu le temps de copier la zone mémoire (ou travaille dessus directement sans copier) : tu as effacé la mémoire du process natif.
-assure toi que tous tes paramètres correspondent aux requirements msdn. pas de struct mal alignées ou mal formattées (trop grosses, etc). le marshalling passe une zone mémoire trop grosse et le code natif protège pas suffisement l'overflow (suffit qu'il prenne un void* et ca risque de péter plus loin).
souvent ce genre d'erreurs viennent d'une mauvaise gestion mémoire coté C# (faut dire que l'interop est pas tjs ce qu'il y a de plus simple a gérer)
gerbito
Messages postés39Date d'inscriptionmardi 14 décembre 2004StatutMembreDernière intervention20 octobre 2015 23 mai 2008 à 18:26
Merci de ta réponse.
C'est vrai qu'avec le ramasse-miettes on ne pense plus que derrière les variables que l'on déclare se cachent ces bons vieux pointeurs du C.
J'ai mis mes variables de classe représentant les handles et les évènements échangés avec l'API en statique, et je vais laisser le test se faire pendant le week-end.
Il faudrait que je puisse tracer l'utilisation de ces pointeurs dans l'API si ca foire
gerbito
Messages postés39Date d'inscriptionmardi 14 décembre 2004StatutMembreDernière intervention20 octobre 2015 30 mai 2008 à 18:37
Bonjour !
Voilà, comme leprov me l'a indiqué, j'ai passé en revue tous les handles passés à l'API RAS, les ai mis en statique en prenant bien garde qu'ils ne soient pas réinitialisés par la suite.
Après un premier résultat qui semblait presque concluant (mon appli a tourné pendant 22 heures de suite avant que l'erreur du svchost ne se manifeste à nouveau, mais l'adresse avait changé), c'est de nouveau la catastrophe...
L'appli tient à peine 20 minutes depuis que j'ai activé le double tampon d'affichage sur un contrôle (pour éviter d'avoir un rafraîchissement horrible), et c'est de nouveau l'adresse 0x77c43dbd qui pose souci dans svchost. J'ai pourtant suivi les instructions citées sur ce site :
http://www.codeproject.com/KB/graphics/DoubleBuffering.aspx pour le double tampon.
Franchement, je ne sais plus trop quoi faire... Quand cette erreur survient, les connexions se coupent sur la cible ou est éxécutée mon appli.