The Black Box of .NET Headline Animator

The Black Box of .NET

Friday, December 9, 2011

Debugging Tools to Diagnose a Memory Leak

Debugging and diagnosing a memory leak or an OutOfMemoryException can be a daunting and challenging task. Fortunately, there are a number of tools to help; some of these are "paid license" apps, but there are even more tools that are free. There is a little bit of irony here; IMHO, the better tools are the free ones...

Free Tools
Licensed Tools
Hope this helps!


Share

Thursday, December 8, 2011

How to Tell if an Assembly is Debug or Release

The DebuggableAttribute is present if you compile in any setting for 'Debug' mode and when Release mode is selected and Debug Info set to anything other than "none". So, just looking for the presence of DebuggableAttribute is not sufficient and could be misleading. So, you could still have an assembly that is JIT optimized where the DebuggableAttribute is present in the Assembly Manifest.

First, you need to define exactly what is meant by "Debug" vs. "Release"...
  • Do you mean that the app is configured with code optimization?
  • Do you mean that you can attach the VS/JIT Debugger to it?
  • Do you mean that it generates DebugOutput?
  • Do you mean that it defines the DEBUG constant?  Remember that you can conditionally compile Methods with the System.Diagnostics.Conditional() attribute.
IMHO, when someone asks whether or not an assembly is "Debug" or "Release", they really mean if the code is optimized...

Sooo, do you want to do this manually or programmatically?

Manually:
You need to view the value of the DebuggableAttribute bitmask for the assembly's metadata.  Here's how to do it:

  1. Open the assembly in ILDASM
  2. Open the Manifest
  3. Look at the DebuggableAttribute bitmask.  If the DebuggableAttribute is not present, it is definitely an Optimized assembly.
  4. If it is present, look at the 4th byte - if it is a '0' it is JIT Optimized - anything else, it is not:
// Metadata version: v4.0.30319
....
     //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 )

    Programmatically: assuming that you want to know programmatically if the code is JITOptimized, here is the correct implementation:

    void Main()
    {
    	var HasDebuggableAttribute = false;
    	var IsJITOptimized = false;
    	var IsJITTrackingEnabled = false;
    	var BuildType = "";
    	var DebugOutput = "";
    	var ReflectedAssembly = Assembly.LoadFile(@"C:\src\TMDE\Git\RedisScalingTest\bin\Release\netcoreapp3.1\RedisScalingTest.dll");
     
    	//	var ReflectedAssembly = Assembly.LoadFile(@"path to the dll you are testing");
    	object[] attribs = ReflectedAssembly.GetCustomAttributes(typeof(DebuggableAttribute), false);
     
    	// If the 'DebuggableAttribute' is not found then it is definitely an OPTIMIZED build
    	if (attribs.Length > 0)
    	{
    		// Just because the 'DebuggableAttribute' is found doesn't necessarily mean
    		// it's a DEBUG build; we have to check the JIT Optimization flag
    		// i.e. it could have the "generate PDB" checked but have JIT Optimization enabled
    		DebuggableAttribute debuggableAttribute = attribs[0] as DebuggableAttribute;
    		if (debuggableAttribute != null)
    		{
    			HasDebuggableAttribute = true;
    			IsJITOptimized = !debuggableAttribute.IsJITOptimizerDisabled;
     
    			// IsJITTrackingEnabled - Gets a value that indicates whether the runtime will track information during code generation for the debugger.
    			IsJITTrackingEnabled = debuggableAttribute.IsJITTrackingEnabled;
    			BuildType = debuggableAttribute.IsJITOptimizerDisabled ? "Debug" : "Release";
     
    			// check for Debug Output "full" or "pdb-only"
    			DebugOutput = (debuggableAttribute.DebuggingFlags &
    							DebuggableAttribute.DebuggingModes.Default) !=
    							DebuggableAttribute.DebuggingModes.None
    							? "Full" : "pdb-only";
    		}
    	}
    	else
    	{
    		IsJITOptimized = true;
    		BuildType = "Release";
    	}
     
    	Console.WriteLine($"{nameof(HasDebuggableAttribute)}{HasDebuggableAttribute}");
    	Console.WriteLine($"{nameof(IsJITOptimized)}{IsJITOptimized}");
    	Console.WriteLine($"{nameof(IsJITTrackingEnabled)}{IsJITTrackingEnabled}");
    	Console.WriteLine($"{nameof(BuildType)}{BuildType}");
    	Console.WriteLine($"{nameof(DebugOutput)}{DebugOutput}");
    }



    Share

    Friday, July 29, 2011

    My Favorite Quotes

    Here are some of my favorite quotes:

    "Debugging is twice as hard as writing code in the first place.  Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."
        - Brian Kernighan

    "Intellectuals solve problems; geniuses prevent them."
        - Albert Einstein

    "There are three categories of open issues with our application: those that we know about, those that we don't know about, and those that we don't know that we don't know about."  Someone in the group actually asked "Can you give an example of the last one?"
        - former coworker

    "It's not a bug, it's a feature"
        - unknown

    "Bugs are a form of job security."
        - unknown

    "If debugging is the process of removing bugs, then programming must be the process of putting them in."
      - Edsger Dijkstra

    "The only difference between a beginning programmer and an experienced one is the complexity of the bugs they write."
      - Dave Black
    Share

    Monday, June 6, 2011

    Finally a good free multi-monitor tool

    timstall: Tool - WinSplit Revolution - move windows between ...: "A coworker showed me a useful (and free!) tool that conveniently positions open windows on your screen. The tool is Winsplit Revolution , ..."
    Share

    Friday, April 29, 2011

    New WinDbg Extension available

    I'm happy to announce that a new version of the WinDbg debugging extension PSSCOR2 (now called PSSCOR4) has been released.  It is available for public download here: 

    http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a06a0fea-a4d4-434e-a527-d6afa2e552dd
    Share

    Thursday, April 28, 2011

    Whitepaper on the Debug Diagnostic Tool v1.1 - IIS debugging and debugdiag - Site Home - MSDN Blogs

    Whitepaper on the Debug Diagnostic Tool v1.1 - IIS debugging and debugdiag - Site Home - MSDN Blogs
    Share

    Wednesday, March 9, 2011

    IIS Tools that you should have...

    Here is a list of IIS tools I've used in the past and their respective links.  Please note that all of these tools are FREE and widely used in the industry.
     
    IIS Web Deploy 2.0
     
     
    IIS 6.0 Resource Kit (many tools included here – most helpful are probably IIS 6.0 Migration Tool and the IIS Metabase Explorer)
     
     
    IIS Diagnostics Kit – IIS Diag
     
    This includes a number of tools which help diagnose various types of problems with IIS setup and configuration:
    • AuthDiag - authentication and ACL problems
    • SSL Diag - SSL-related problems
    • SMTP Diag - smtp-related issues
    • Log Parser - allows for easy reading of IIS log files
    • Debug Diag - allows you to create memory dumps manually or automatically when IIS hangs.  It also can run a memory ananlysis from the memory dump captured!
    • and others...

    Event Log Explorer - allows you to create custom queries and filters against anything in the Event Viewer – very cool!


    And a whole list of the other great tools from the IIS Team at Microsoft:


     
     
    Share

    Friday, March 4, 2011

    DOT NET TRICKS: Dependency Injection & IOC

    DOT NET TRICKS: Dependency Injection & IOC
    Share

    Wednesday, March 2, 2011

    How do you properly implement the IDisposable pattern?

    This is the first post of a series that I'll be making on memory management in .NET.  The subsequent posts will cover guidelines for working with disposable objects, when to implement IDisposable, and maybe a few others.

    I am often asked how to correctly implement the IDisposable pattern. There are many posts you'll see from a Google search that try to answer this question. IMHO, the pattern that you find here is the safest and most correct implementation of the pattern according to .NET Best Practices and my experience. I am confident saying this because of my extensive experience with memory leak debugging, internals of the CLR, code reviews, and implementation of best practices at very large, well-known clients who rely on solid applications.  You will find that my provided implementation of this pattern is slightly different than that which is posted on MSDN.  IMHO, it isn't sufficient.  You have to agree that a large number of samples and examples posted on MSDN are "hacky" and don't do things the way that they should be done in the "real world".

    A couple of notes on implementing the IDisposable pattern:
    1. Simply adding a Dispose() method to a class doesn't implement the pattern (just because it compiles doesn't mean it's correct).  I've seen this mistake made many, many times - it's just not a good idea.
    2. Adding the code below isn't enough - you must also explicitly declare the class inheriting from IDisposable ->  MyDisposableClass : IDisposable.  This is very important since objects creating/managing instances of your class might decide to try to cast it to IDisposable and call Dispose or use a 'using()' statement. If your class isn't explicitly declared to implement IDisposable, the cast will fail and Dispose will never be called.
    3. Just because you implement IDisposable correctly doesn't mean it will get called "magically". What I mean is that the GC never calls Dispose for you - you have to explicitly call it on your class from the owning object.  There is a common misconception that this can somehow magically happen by the GC and that it's not important that you explicitly call it "because the GC cleans up for you" (WRONG!)
    4. Implementing the IDisposable pattern correctly is tricky and can easily lead to problems if not done properly.  This is why I've provided the code below.
    5. I use a code snippet with the exact code below to properly and consistently implement the pattern correctly.
    6. There is great debate on whether or not you should null out rooted references. It certainly never hurts to do so. Nulling these out does do something before GC runs - it removes the rooted reference to that object. The GC later scans its collection of rooted references and collects those that do not have a rooted reference.

      Think of this example when it is good to do so: you have an instance of type "ClassA" - let's call it 'X'. X contains an object of type "ClassB" - let's call this 'Y'. Y implements IDisposable, thus, X should do the same to dispose of Y. Let's assume that X is in Generation 2 or the LOH and Y is in Generation 0 or 1. When Dispose() is called on X AND that implementation nulls out the reference to Y, the rooted reference to Y is immediately removed. If a GC happens for Gen 0 or Gen 1, the memory/resources for Y is cleaned up but the memory/resources for X is not since X lives in Gen 2 or the LOH.
    Here is the code for properly implementing the IDisposable pattern in a base class:


    #region IDisposable base-class implementation
     
    //TODO remember to make this class inherit from IDisposable -> MyDisposableClass : IDisposable
     
    /// <summary>
    /// Gets or sets a value indicating whether this instance is disposed.
    /// </summary>
    /// <value>
    ///  <c>true</c> if this instance is disposed; otherwise, <c>false</c>.
    /// </value>
    /// <remarks>Default initialization for a bool is 'false'</remarks>
    private bool IsDisposed { getset; }
     
    /// <summary>
    /// Implementation of Dispose according to .NET Framework Design Guidelines.
    /// </summary>
    /// <remarks>Do not make this method virtual.
    /// A derived class should not be able to override this method.
    /// </remarks>
    public void Dispose()
    {
        Dispose(true);
     
        // This object will be cleaned up by the Dispose method.
        // Therefore, you should call GC.SupressFinalize to
        // take this object off the finalization queue 
        // and prevent finalization code for this object
        // from executing a second time.
     
        // Always use SuppressFinalize() in case a subclass
        // of this type implements a finalizer.
        GC.SuppressFinalize(this);
    }
     
    /// <summary>
    /// Overloaded Implementation of Dispose.
    /// </summary>
    /// <param name="isDisposing"><c>true</c> to release both managed and unmanaged resources; 
    /// <c>false</c> to release only unmanaged resources.</param>
    /// <remarks>
    /// <list type="bulleted">Dispose(bool isDisposing) executes in two distinct scenarios.
    /// <item>If <paramref name="isDisposing"/> equals true, the method has been called directly
    /// or indirectly by a user's code. Managed and unmanaged resources
    /// can be disposed.</item>
    /// <item>If <paramref name="isDisposing"/> equals <c>false</c>, the method has been called 
    /// by the runtime from inside the finalizer and you should not reference
    /// other objects. Only unmanaged resources can be disposed.</item></list>
    /// </remarks>
    protected virtual void Dispose(bool isDisposing)
    {
        // TODO If you need thread safety, use a lock around these 
        // operations, as well as in your methods that use the resource.
        try
        {
            if (!this.IsDisposed)
            {
                // Explicitly set root references to null to expressly tell the GarbageCollector
                // that the resources have been disposed of and its ok to release the memory 
                // allocated for them.
                if (isDisposing)
                {
                    // Release all managed resources here
    
    
    
    
                    // Need to unregister/detach yourself from the events. Always make sure
                    // the object is not null first before trying to unregister/detach them!
                    // Failure to unregister can be a BIG source of memory leaks
                    if (someDisposableObjectWithAnEventHandler != null)
                    {                 
                        someDisposableObjectWithAnEventHandler.SomeEvent -= someDelegate;
                        someDisposableObjectWithAnEventHandler.Dispose();
                        someDisposableObjectWithAnEventHandler = null;
                    }
    
    
    
    
                    // If this is a WinForm/UI control, uncomment this code
                    //if (components != null)
                    //{
                    //    components.Dispose();
                    //}
                }
                // Release all unmanaged resources here  
                // (example)             if (someComObject != null && Marshal.IsComObject(someComObject))
                {
                    Marshal.FinalReleaseComObject(someComObject);
                    someComObject = null;
                }
            }
        }
        finally
        {
            this.IsDisposed = true;
        }
    }

    //TODO Uncomment this code if this class will contain members which are UNmanaged
    ///// <summary>Finalizer for MyDisposableClass</summary>
    ///// <remarks>This finalizer will run only if the Dispose method does not get called.
    ///// It gives your base class the opportunity to finalize.
    ///// DO NOT provide finalizers in types derived from this class.
    ///// All code executed within a Finalizer MUST be thread-safe!</remarks>
    //  ~MyDisposableClass()
    //  {
    //     Dispose( false );
    //  }
    #endregion IDisposable base-class implementation
     
    Here is the code for properly implementing the IDisposable pattern in a derived class:

    #region IDisposable derived-class implementation

    /// <summary>
    /// Gets or sets a value indicating whether this instance is disposed.
    /// </summary>
    /// <value>
    ///  <c>true</c> if this instance is disposed; otherwise, <c>false</c>.
    /// </value>
    /// <remarks>Default initialization for a bool is 'false'</remarks>
    private bool IsDisposed { getset; }

    /// <summary>
    /// Overloaded Implementation of Dispose.
    /// </summary>
    /// <param name="isDisposing"><c>true</c> to release both managed and unmanaged resources; 
    /// <c>false</c> to release only unmanaged resources.</param>
    /// <remarks>
    /// <list type="bulleted">Dispose(bool isDisposing) executes in two distinct scenarios.
    /// <item>If <paramref name="isDisposing"/> equals true, the method has been called directly
    /// or indirectly by a user's code. Managed and unmanaged resources
    /// can be disposed.</item>
    /// <item>If <paramref name="isDisposing"/> equals <c>false</c>, the method has been called

    /// by the runtime from inside the finalizer and you should not reference
    /// other objects. Only unmanaged resources can be disposed.</item></list>
    /// </remarks>
    protected override void Dispose(bool isDisposing)
    {
        // TODO If you need thread safety, use a lock around these 
        // operations, as well as in your methods that use the resource.
        try
        {
            if (!this.IsDisposed)
            {
                // Explicitly set root references to null to expressly tell the GarbageCollector
                // that the resources have been disposed of and its ok to release the memory 
                // allocated for them.
                if (isDisposing)
                {
                    // Release all managed resources here

                    // Need to unregister/detach yourself from the events. Always make sure
                    // the object is not null first before trying to unregister/detach them!
                    // Failure to unregister can be a BIG source of memory leaks
                    if (someDisposableObjectWithAnEventHandler != null)
                    {                 
                        someDisposableObjectWithAnEventHandler.SomeEvent -= someDelegate;
                        someDisposableObjectWithAnEventHandler.Dispose();
                        someDisposableObjectWithAnEventHandler = null;
                    }
    
                    // If this is a WinForm/UI contrlol, uncomment this code
                    //if (components != null)
                    //{
                    //    components.Dispose();
                    //}
                }

                // Release all unmanaged resources here
     
     
                // (example)
                if (someComObject != null && Marshal.IsComObject(someComObject))
                {
                    Marshal.FinalReleaseComObject(someComObject);
                    someComObject = null;
                }
            }
        }
        finally
        {
            this.IsDisposed = true;

            // explicitly call the base class Dispose implementation
            base.Dispose(isDisposing);

        }
    }
    #endregion IDisposable derived-class implementation


    Share

    Thursday, February 24, 2011

    Tools for Assisting with Collection and Analyzing of Data for Problem Diagnosis

    I was going through my Google Bookmarks and found a bunch of tools that are extremely helpful in diagnosing  many problems that occur on a web/app server and and interpreting the data collected. I’ve used all of them; they are all free and well known and used within the Community.  By no means is this an exhaustive list of all of the Tools and Add-Ins that I use - I'll get around to posting those someday : )

    I’d start with the Data Collector. You can collect everything with Data Collector and then use the Log Parser and Visual Log Parser to help aggregate the data and even run queries against it. You may already know about some of these – but for those you haven’t seen, you should take a look!

    Data Collector (supports IIS6 & IIS7, and can pull most other logs from any server):
    http://blogs.msdn.com/b/carloc/archive/2010/02/01/idevdatacollector.aspx

    Log Parser 2.2:
    http://www.microsoft.com/downloads/en/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&displaylang=en

    Visual Log Parser:
    http://visuallogparser.codeplex.com/

    Log File Analysis:
    http://blogs.msdn.com/b/delay/archive/2007/06/21/powerful-log-file-analysis-for-everyone-releasing-textanalysistool-net.aspx

    Event Log Explorer:
    http://www.eventlogxp.com/

    IIS Log Analyzer (does graphs and reports):
    http://www.iis.net/community/default.aspx?tabid=34&g=6&i=1864

    IIS Diagnostics Toolkit (a suite of tools diagnosing Authentication, Authorization, SSL, Crash/Hang, etc.):
    http://www.microsoft.com/downloads/en/details.aspx?FamilyID=9bfa49bc-376b-4a54-95aa-73c9156706e7

    and then of course the "big daddy" bunch of them all - Debugging Tools for Windows:
    http://www.microsoft.com/whdc/devtools/debugging/default.mspx

    I hope you find these useful : )
    Share