Sdílet prostřednictvím


CA2115: Volejte GC.KeepAlive při použití nativních zdrojů

Název_typu

CallGCKeepAliveWhenUsingNativeResources

CheckId

CA2115

Kategorie

Microsoft.Security

Změnit rozdělení

Bez rozdělení

Příčina

Metody deklarované v typu finalizačních metod s odkazy IntPtr nebo UIntPtr poli, ale není volání GC.KeepAlive.

Popis pravidla

Pokud nejsou žádné další odkazy ve spravovaném kódu, dokončí úklid objektu.Nespravovaná odkazy na objekty nebrání úklid.Toto pravidlo zjistí chyby, které mohou nastat, protože nespravované prostředku je ukončen v době, kdy je stále používán v nespravovaný kód.

Toto pravidlo předpokládá, že IntPtr a UIntPtr pole obsahují ukazatele nespravované prostředky.Protože účelem finalizačních metod bez nespravované prostředky, pravidlo předpokládá, že uvolní finalizačních metod nespravované prostředku odkazuje na pole ukazatel myši.Toto pravidlo rovněž předpokládá metody odkazují pole ukazatel nespravované prostředku předat nespravovaný kód.

Jak vyřešit narušení

Porušení tohoto pravidla odstranit, přidat volání KeepAlive na metodu předávání aktuální instance (this v C# a C++) jako argument.Umístěte volání po poslední řádek kódu, kde objekt musí být chráněny před uvolněné.Ihned po volání KeepAlive, objekt znovu považován připraven pro úklid za předpokladu, že neexistují žádné spravované odkazy.

Při potlačení upozornění

Toto pravidlo provádí některé předpoklady, které mohou vést k falešně pozitivních výsledků.Můžete bezpečně potlačit varování od tohoto pravidla, pokud:

  • Finalizačních metod není volný obsah IntPtr nebo UIntPtr pole odkazuje na metodu.

  • Metoda neprojde IntPtr nebo UIntPtr pole nespravovaný kód.

Pečlivě zkontrolujte ostatní zprávy před jejich vyloučení.Toto pravidlo zjistí chyby, které se obtížně reprodukovat a ladění.

Příklad

V následujícím příkladu BadMethod nezahrnuje volání GC.KeepAlive a proto porušuje pravidlo.GoodMethodobsahuje Opravený kód.

[!POZNÁMKA]

V tomto příkladu je pseudo-code, přestože kód zkompiluje a spustí, upozornění není aktivována, protože nespravované prostředku není vytvořen nebo uvolněna.

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

   }

}

Viz také

Referenční dokumentace

GC.KeepAlive

IntPtr

Object.Finalize

UIntPtr

Další zdroje

Implementing Finalize and Dispose to Clean Up Unmanaged Resources