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:
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
Další zdroje
Implementing Finalize and Dispose to Clean Up Unmanaged Resources