Share via


CA2115: GC.KeepAlive beim Verwenden systemeigener Ressourcen aufrufen

TypeName

CallGCKeepAliveWhenUsingNativeResources

CheckId

CA2115

Kategorie

Microsoft.Security

Unterbrechende Änderung

Nicht unterbrechend

Ursache

In einer Methode, die in einem Typ mit einem Finalizer deklariert wird, wird auf ein System.IntPtr-Feld oder ein System.UIntPtr-Feld verwiesen, GC.KeepAlive wird aber nicht aufgerufen.

Regelbeschreibung

Garbage Collection gibt ein Objekt frei, wenn im verwalteten Code keine Verweise mehr darauf vorhanden sind. Nicht verwaltete Verweise auf Objekte verhindern die Garbage Collection nicht. Diese Regel erkennt Fehler, die auftreten können, wenn eine nicht verwaltete Ressource freigegeben wird, während sie in nicht verwaltetem Code noch verwendet wird.

Diese Regel geht davon aus, dass in IntPtr-Feldern und UIntPtr-Feldern Zeiger auf nicht verwaltete Ressourcen gespeichert werden. Weil ein Finalizer dem Zweck dient, nicht verwaltete Ressourcen freizugeben, geht die Regel davon aus, dass der Finalizer die nicht verwaltete Ressource freigibt, auf die die Zeigerfelder zeigen. Diese Regel setzt auch voraus, dass die Methode auf das Zeigerfeld verweist, um die nicht verwaltete Ressource an nicht verwalteten Code zu übergeben.

Behandeln von Verstößen

Um einen Verstoß gegen diese Regel zu beheben, fügen Sie der Methode einen Aufruf von KeepAlive hinzu und übergeben die aktuelle Instanz (this in C# und C++) als Argument. Fügen Sie den Aufruf nach der letzten Codezeile ein, in der das Objekt vor der Garbage Collection geschützt werden muss. Unmittelbar nach dem Aufruf von KeepAlive wird das Objekt wieder als für die Garbage Collection bereit betrachtet, weil davon ausgegangen wird, dass keine verwalteten Verweise auf das Objekt mehr vorhanden sind.

Wann sollten Warnungen unterdrückt werden?

Diese Regel geht von einigen Annahmen aus, die zu unbegründeten Warnungen führen können. Sie können eine Warnung dieser Regel gefahrlos unterdrücken, wenn folgende Bedingungen erfüllt sind:

  • Der Finalizer gibt den Inhalt des IntPtr-Felds oder des UIntPtr-Felds nicht frei, auf das die Methode verweist.

  • Die Methode übergibt das IntPtr-Feld oder das UIntPtr-Feld nicht an nicht verwalteten Code.

Überprüfen Sie vorher sorgfältig andere Meldungen, bevor Sie sie ausschließen. Diese Regel erkennt Fehler, die schwierig zu reproduzieren und zu debuggen sind.

Beispiel

In diesem Beispiel verstößt BadMethod gegen die Regel. GoodMethod enthält den korrigierten Code.

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 ...
      }

   }

}

Siehe auch

Referenz

Implementieren der Methoden "Finalize" und "Dispose" zum Bereinigen von nicht verwalteten Ressourcen

GC.KeepAlive

System.IntPtr

Object.Finalize

System.UIntPtr