2010-03-17 6 views
1

Il y a longtemps, j'ai découvert que je recevais des violations d'accès dans mon code en raison de l'utilisation des boîtes de dialogue Ouvrir fichier Delphi et/ou Enregistrer fichier qui encapsulent les boîtes de dialogue Windows . J'ai posé quelques questions sur quelques forums et on m'a dit que cela pouvait être dû à la façon dont certains programmes ajoutent des hooks au système shell qui entraînent l'injection de DLL dans tous les processus, dont certains peuvent causer des ravages avec un programme. Pour mémoire, l'environnement de programmation que j'utilise est Delphi 6 Professional fonctionnant sous Windows XP 32 bits. À l'époque je l'ai contourné en n'utilisant pas les composants Dialog de Delphi et en appelant directement directement dans comdlg32.dll. Cela a résolu le problème à merveille.Violations d'accès dans des endroits étranges lors de l'utilisation des boîtes de dialogue Windows

Aujourd'hui, je travaillais avec des fichiers mappés en mémoire pour la première fois et, bien sûr, les violations d'accès ont commencé à apparaître dans des parties étranges du code. J'ai essayé mes appels directs de comdlg32.dll et cette fois cela n'a pas aidé. Pour isoler le problème en tant que test, j'ai créé une zone de liste avec exactement les mêmes fichiers que j'utilisais pendant les tests. Ce sont exactement les mêmes fichiers de test que je sélectionnais dans une boîte de dialogue Ouvrir un fichier et ensuite lancer mon fichier mappé en mémoire avec. Je configure les choses de sorte qu'en cliquant sur un fichier dans la zone de liste, j'utilise ce fichier dans mon test de fichier mappé en mémoire au lieu d'appeler une fonction de dialogue comdlg32.dll pour sélectionner un fichier de test.

Encore, les violatons d'accès ont disparu. Pour vous montrer à quel point il était dramatique, je suis passé d'une violation d'accès dans 1 à 3 essais à aucun. Malheureusement, il va me mordre plus tard bien sûr quand j'ai besoin d'utiliser des boîtes de dialogue.

Est-ce que quelqu'un d'autre a traité ce problème aussi et a trouvé le vrai coupable? Est-ce que l'un d'entre vous a trouvé une solution que je pourrais utiliser pour résoudre ce problème au lieu de danser autour comme je le suis maintenant?

Merci d'avance.

+0

Vous devez obtenir la pile où l'accident se produit. Utilisez NTSD et configurez les symboles publics. http://msdn.microsoft.com/en-us/library/cc266473.aspx –

+0

Je n'ai jamais vu ce problème, mais une chose qui pourrait (peut-être) aider si vous êtes sur Delphi 6 est de remplacer le gestionnaire de mémoire avec FastMM4, qui est beaucoup plus stable que l'ancien. –

+0

Bonjour Mason. J'utilise FastMM4 et j'ai effectué plusieurs tests avec chaque vérification détaillée que je pouvais trouver, en particulier pour vérifier la corruption du tas. Il n'a rien trouvé. L'accident se produit pendant une instruction de déplacement de mémoire dans mon programme, tout comme il y a longtemps. C'est comme si certaines DLL écrivaient sur un bloc de ma mémoire ou une variable contrôlant l'étendue du déplacement de la mémoire, mais ne le faisaient pas d'une manière qui corrompait les en-têtes de bloc de mémoire de FastMM4. Mais c'est de la spéculation de ma part puisque je ne connais pas la cause première. –

Répondre

5

Je ne comprends pas comment ne pas utiliser les composants de dialogue Delphi évite les DLL d'extension shell causant des ravages dans votre programme si vous appelez directement COMDLG32.DLL directement. Vous utilisez toujours les boîtes de dialogue communes et ces extensions sont toujours injectées. Plus probablement, le fait de ne pas utiliser les composants a eu un effet secondaire dans votre code qui a obscurci ou masqué le problème sous-jacent, l'atténuant au point où il semblait avoir été résolu.

Je pense que c'est le cas ici aussi. Je ne sais pas quel genre d'extensions shell hokey vous avez installées sur votre système - peut-être avez-vous une extension d'impair-ball qui pose quelques problèmes. Tout ce que je peux dire est que dans 15 années impaires de programmation Win32 avec Delphi j'ai jamais connu ou même entendu parler des composants de dialogue de fichier commun Delphi pour être responsable d'un tel comportement. Un moyen simple de tester ceci est de prendre le EXE compilé qui présente les violations d'accès sur votre machine, et d'exécuter le même EXE sur une autre machine XP "clean-room", c'est-à-dire sans shell tiers extensions installées quoi-si-jamais.

Si les AV disparaissent, vous pouvez être plus sûr que le problème est en quelque sorte lié à une extension shell. Ensuite, en installant les extensions de shell connues sur la machine de test une par une jusqu'à ce que les AV réapparaissent, vous pouvez isoler le coupable et décider quoi faire à ce sujet ... s'il en est un que vos utilisateurs/clients ont peu de chance d'être en utilisant alors vous pourriez choisir de simplement le lister comme un problème de compatibilité connu et passer à d'autres problèmes.Cependant, si les AV ne disparaissent pas, vous pouvez pratiquement exclure les boîtes de dialogue Delphi ou les extensions de shell. Plus généralement, il serait plus utile de voir le code dans lequel l'AV se produit, si cela est possible.

Addendum:

je ne trouve this reference to AV's occuring with the Common Dialog components themselves. Cela ne serait pas considéré comme "un endroit étrange" pour un AV, étant constamment reproductible - semble-t-il - dans les composants de dialogue eux-mêmes. Mais je pensais que je le mentionnerais de toute façon. Sans savoir précisément où vos AV se produisent, il est possible que cela soit lié.

+0

Je me suis inquiété à ce sujet depuis longtemps (encore faire), mais quelques détails de plus. J'ai récemment déplacé toute ma configuration vers un nouveau système informatique avec une nouvelle installation de Windows XP. En outre, le projet que j'ai fait pour tester le code de fichier mappé en mémoire est un projet de base avec seulement quelques-uns de mes fichiers de "routine courante" inclus. Tous les composants sur la forme principale de plain vanilla sont stock Delphi VCL (listbox, bouton, etc.). Il est vrai que ma palette de composants est bourrée d'éléments tiers, y compris le JCL et JVCL, mais je ne pense pas que le code des composants inutilisés soit compilé dans le projet. –

+1

Cela dépend ... si ces unités tierces se trouvent dans votre liste d'utilisation et contiennent des sections d'initialisation, alors vous pouvez constater que vous êtes en train de faire glisser des choses que vous n'attendez peut-être pas. Mais encore, voir exactement où/quand ces AVs se produisent (c'est-à-dire le code source) serait le plus utile. Sinon, toute aide ne peut provenir que du "débogage psychique" (lire: conjecture/spéculation). – Deltics

+0

Les erreurs de mon projet en cours se produisent lors d'un appel Move() lorsque j'essaie de copier des données du tampon de données du fichier mappé en mémoire vers une variable. Cela se produit lors de la boucle "repeat move octets" où les octets sont copiés par l'instruction Move (avec le pointeur d'exécution dans la fenêtre CPU car c'est le code de l'assembleur). Lorsque je n'effectue aucun appel de boîte de dialogue, les erreurs disparaissent. Je vais vérifier les sections d'initialisation pour les composants tiers et la liste de DLL dans l'Observateur d'événements. –

Questions connexes