Export (0) Print
Expand All
Expand Minimize

CA2115: Call GC.KeepAlive when using native resources

TypeName

CallGCKeepAliveWhenUsingNativeResources

CheckId

CA2115

Category

Microsoft.Security

Breaking Change

Non Breaking

A method declared in a type with a finalizer references a System.IntPtr or System.UIntPtr field, but does not call GC.KeepAlive.

Garbage collection finalizes an object if there are no more references to it in managed code. Unmanaged references to objects do not prevent garbage collection. This rule detects errors that might occur because an unmanaged resource is being finalized while it is still being used in unmanaged code.

This rule assumes that IntPtr and UIntPtr fields store pointers to unmanaged resources. Because the purpose of a finalizer is to free unmanaged resources, the rule assumes that the finalizer will free the unmanaged resource pointed to by the pointer fields. This rule also assumes that the method is referencing the pointer field to pass the unmanaged resource to unmanaged code.

To fix a violation of this rule, add a call to KeepAlive to the method, passing the current instance (this in C# and C++) as the argument. Position the call after the last line of code where the object must be protected from garbage collection. Immediately after the call to KeepAlive, the object is again considered ready for garbage collection assuming that there are no managed references to it.

This rule makes some assumptions that can lead to false positives. You can safely suppress a warning from this rule if:

  • The finalizer does not free the contents of the IntPtr or UIntPtr field referenced by the method.

  • The method does not pass the IntPtr or UIntPtr field to unmanaged code.

Carefully review other messages before excluding them. This rule detects errors that are difficult to reproduce and debug.

In the following example, BadMethod does not include a call to GC.KeepAlive and therefore violates the rule. GoodMethod contains the corrected code.

Note Note

This example is pseudo-code Although the code compiles and runs, the warning is not fired because an unmanaged resource is not created or freed.

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

   }

}
Show:
© 2014 Microsoft