2010-07-04 5 views
1

J'ai une DLL déchargée dynamiquement chargée & qui nécessite COMCTL32.dll> = v6.0 et MSVCR> = v9.0. Pour vous assurer que les versions correctes sont chargées, activer la génération de fichier manifeste dans un cadre de projet Visual Studio et ajouter cette entrée à un autre fichier manifeste:Une fuite de handle de fichier sur une DLL chargée dynamiquement provoquée par le contexte d'activation

<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>

Dans un programme de test que j'appelle LoadLibrary() suivi par FreeLibrary() de cette DLL et ProcessExplorer indique que les descripteurs de fichiers suivants ont été divulgués:

  • C: \ WINDOWS \ WinSxS \ x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_6f74963e
  • C: \ WINDOWS \ WinSxS \ x86_Microso ft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83

De trace le démontage de la pile d'appel j'ai appris que le LoadLibrary(), un contexte d'activation a été automatiquement créé et il ouvre les poignées à chacun de ces dossiers. Mais il semble que le contexte d'activation ne soit pas supprimé sur FreeLibrary().

Si je supprime les fichiers manifest et que vous définissez les paramètres du projet pour désactiver la génération de manifeste, ces fuites ont disparu. Cependant, de cette façon, je serai incapable de m'assurer que les MSVCR et COMCTL corrects sont utilisés, puisque cette DLL est chargée par des processus sur lesquels je n'ai aucun contrôle.

Existe-t-il un moyen de supprimer cette fuite sans supprimer les fichiers manifest?

Merci!

Répondre

1

Les rapports de fuite ProcessExplorer HANDLE sont un symptôme d'une fuite de contexte d'activation. Très probablement cette fuite est dans votre code indirectement en ce que vous n'avez pas correctement appelé MFC. Pour vous aider à valider que c'est votre bogue et non MFC, vous pouvez créer une simple DLL MFC à partir de AppWizard sans aucun de votre code et confirmer que lorsqu'il est LoadLibrary/FreeLibrary plusieurs fois, il n'y a aucune fuite cumulative.

L'appel OS manquant est soit un ReleaseActCtx, soit un DeactivateActCtx manquant qui a causé l'échec de la version. En pratique, MFC appelle ces fonctions pour vous afin que vous soyez à la recherche d'un appel MFC manquant quelconque. La meilleure technique de débogage serait probablement de tracer ou d'arrêter les fonctions create/activate/deactivate/release du contexte d'activation principal (http://msdn.microsoft.com/fr-fr/library/aa374166(VS.85) .aspx) et voir ce qui se passe. Vous pouvez voir une série d'appels, donc une sorte de traçage peut être nécessaire. Idéalement, vous pouvez capturer les callstack à chaque appel et les examiner. Votre débogueur peut être en mesure de vous aider à le faire.Les versions récentes de VS peuvent exécuter des macros lorsqu'elles atteignent des points d'arrêt. En outre, vous avez raison de dire que vous avez besoin des fichiers manifestes et que vous ne devez pas les supprimer.

Martyn

0

Il est possible que ces poignées ne fuient pas - elles sont simplement mises en mémoire cache. Si vous modifiez votre programme de test pour charger et décharger votre DLL de manière répétée plusieurs fois, voyez-vous une nouvelle paire de handles fuite chaque fois que DLL se décharge? Sinon, ce n'est pas un problème.

+0

Merci pour votre réponse. J'ai essayé cela plus tôt, et pour chaque paire LoadLibrary - FreeLibrary, il y a deux nouvelles handles de fichiers montrés dans ProcessExplorer. J'ai enregistré les données de processus à différents points et les diff pour être sûr. – edwinbs

0

Est-ce que votre DLL utilise MFC par hasard? J'ai eu un problème avec une DLL qui utilise MFC et appelle AfxWinInit() qui peut être liée. Cette DLL (à tort) a appelé AfxWinInit() à plusieurs reprises et il s'est avéré qu'il a divulgué un contexte d'activation pour chacun de ces appels. Étonnamment, cela ne s'est produit que lorsque l'application appelante a utilisé un manifeste.

1

Les rapports de fuite de POIGNÉE de ProcessExplorer sont un symptôme d'une fuite de contexte d'activation. Très probablement cette fuite est dans votre code indirectement en ce que vous n'avez pas correctement appelé MFC.

Il n'est pas associé à une utilisation de code spécifique. Le problème a été confirmé par Microsoft: http://support.microsoft.com/kb/2624911

Il existe en effet une fuite d'activation de contexte dans SHELL32.DLL lors de l'appel UnregisterClass, affectant Windows Vista et plus. La seule solution à ce problème consiste à ne pas charger et décharger plusieurs fois SHELL32.DLL. Microsoft cherche un correctif pour ce problème dans les versions plus récentes de Windows.

Questions connexes