CA2115 : Appelez GC.KeepAlive lorsque vous utilisez des ressources natives
Élément | Valeur |
---|---|
ID de la règle | CA2115 |
Category | Microsoft.Security |
Modification avec rupture | Sans rupture |
Cause
Une méthode déclarée dans un type avec un finaliseur référence un champ System.IntPtr ou System.UIntPtr, mais n’appelle pas System.GC.KeepAlive.
Notes
Cette règle est déconseillée. Pour plus d’informations, consultez Règles dépréciées.
Description de la règle
Garbage collection finalise un objet s’il n’y a plus de références à cet objet dans le code managé. Les références non managées aux objets n’empêchent pas le garbage collection. Cette règle détecte les erreurs susceptibles de se produire du fait qu’une ressource non managée est en cours de finalisation alors qu’elle est encore utilisée dans un code non managé.
Cette règle suppose que les champs IntPtr et UIntPtr stockent des pointeurs vers des ressources non managées. L'objectif d'un finaliseur étant de libérer les ressources non managées, la règle suppose que le finaliseur libérera la ressource non managée désignée par les champs de pointeurs. Cette règle suppose également que la méthode référence le champ de pointeur pour transmettre la ressource non managée au code non managé.
Comment corriger les violations
Pour corriger une violation de cette règle, ajoutez un appel à KeepAlive à la méthode, en passant l’instance actuelle (this
en C# et C++) en tant qu’argument. Positionnez l'appel après la dernière ligne de code où l'objet doit être protégé contre le garbage collection. Aussitôt après l’appel à KeepAlive, l’objet est à nouveau considéré comme prêt pour le garbage collection en supposant qu’il n’est associé à aucune référence managée.
Quand supprimer les avertissements
Cette règle repose sur certaines hypothèses qui peuvent entraîner des faux positifs. Vous pouvez ignorer en toute sécurité un avertissement de cette règle si :
Le finaliseur ne libère pas le contenu du champ IntPtr ou UIntPtr référencé par la méthode.
La méthode ne transmet pas le champ IntPtr ou UIntPtr au code non managé.
Examinez attentivement les autres messages avant de les ignorer. Cette règle détecte les erreurs difficiles à reproduire et à déboguer.
Exemple
Dans l’exemple suivant, BadMethod
n’inclut pas d’appel à GC.KeepAlive
et enfreint donc la règle. GoodMethod
contient le code corrigé.
Notes
Cet exemple est pseudo-code. Bien que le code se compile et s'exécute, l'avertissement n'est pas déclenché parce qu'une ressource non managée n'est pas créée ou libérée.
using System;
namespace SecurityRulesLibrary
{
class IntPtrFieldsAndFinalizeRequireGCKeepAlive
{
private IntPtr unmanagedResource;
IntPtrFieldsAndFinalizeRequireGCKeepAlive()
{
GetUnmanagedResource (unmanagedResource);
}
// The finalizer frees the unmanaged resource.
~IntPtrFieldsAndFinalizeRequireGCKeepAlive()
{
FreeUnmanagedResource (unmanagedResource);
}
// Violates rule:CallGCKeepAliveWhenUsingNativeResources.
void BadMethod()
{
// Call some unmanaged code.
CallUnmanagedCode(unmanagedResource);
}
// Satisfies the rule.
void GoodMethod()
{
// Call some unmanaged code.
CallUnmanagedCode(unmanagedResource);
GC.KeepAlive(this);
}
// Methods that would typically make calls to unmanaged code.
void GetUnmanagedResource(IntPtr p)
{
// Allocate the resource ...
}
void FreeUnmanagedResource(IntPtr p)
{
// Free the resource and set the pointer to null ...
}
void CallUnmanagedCode(IntPtr p)
{
// Use the resource in unmanaged code ...
}
}
}
Voir aussi
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour