Interactive Debugging and How to create PlugCommands

date March 4, 2009 22:39 by author Sukesh Ashok Kumar

There are times when these automated tools don’t cover everything what we need out of memory dumps. Sometimes information in the dumps might not be required for reports but only required to be checked in specific scenarios. Interactive debugging option in Debug Analyzer.NET is just for that but powered with the same simplicity and object model.

In the previous post I discussed how simple it is to draw graph in such a small number of lines. Let us see how the same information can be added as a PlugCommand for Interactive Debugging session.

//Function Attributes required to enable the function as PlugCommand
[PlugCommand(
Command="top10heapbyreservedsize",
Description="Shows Top 10 Heap By Reserved Size",
Usage="Top10HeapByReservedSize")]
public string Top10HeapByReservedSize()
{
    //Top 10 heaps by reserved memory
    IEnumerable<NTHeap> _Top10HeapByReservedSize = 
                    Analyzer.HeapCollection.AsQueryable().OrderByDescending(h => h.ReservedMemory).Take(10);
    StringBuilder heapstr = new StringBuilder();
    heapstr.AppendFormat("{0} {1} {2} {3}",
                                                "[Handle]".PadRight(10),
                                                "[Reserve Size]".PadLeft(15),
                                                "[Heap Name]",
                                                Environment.NewLine);
    foreach (NTHeap h in _Top10HeapByReservedSize)
    {
        heapstr.AppendFormat("{0} {1} {2} {3}",
                                                Analyzer.GetAsHexString(h.Handle),
                                                Analyzer.FormatByteToString(h.ReservedMemory).PadLeft(15),
                                                h.HeapName,
                                                Environment.NewLine);
    }
    return heapstr.ToString();
}

So the only requirement for PlugCommand is that it should be a function which returns a string and all string parameters (if any) and the “PlugCommand” attribute should be added which publishes the function as a Command to the ‘Plug Framework’

Lets see how it looks like in the output of Interactive session below

Plugcommand Reservedsize

Please let me know the feedback through comments!

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Sample Code : How to show a graph with Top 10 Heaps by Reserved Size?

date March 2, 2009 01:04 by author Sukesh Ashok Kumar

Let us see the output first and then check the Plug code required to get the same.

Top10HeapsByReservedSize

Now let us check the Analysis code snippet!

void GraphTop10HeapByReservedSize()
{
    //Top 10 Heaps by Reserved Memory Size
    IEnumerable<NTHeap> _Top10HeapByReservedSize = 
                            Analyzer.HeapCollection.AsQueryable().OrderByDescending(h => h.ReservedMemory).Take(10);
    double largestSize = 0;

    WriteBoldLine("Top 10 Heaps by Reserved Size");
    foreach (NTHeap h in _Top10HeapByReservedSize)
    {
        if (largestSize == 0)       
        {
            largestSize = h.ReservedMemory;
            WriteGraphLine(GraphColors.LightGreen, 100,        //1st element is always 100%
                                string.Format("Heap Handle - {0}, Size - {1}, Name - {2}",
                                CreateAnchor(AnchorType.Heap, Analyzer.GetAsHexString(h.Handle)),
                                Analyzer.FormatByteToString(h.ReservedMemory),
                                h.HeapName
                                ));
        }
        else
            //Calculate percentage relative to the 1st element
            WriteGraphLine(GraphColors.LightGreen, (int)((h.ReservedMemory/largestSize)*100) ,
                                string.Format("Heap Handle - {0}, Size - {1}, Name - {2}",
                                CreateAnchor(AnchorType.Heap, Analyzer.GetAsHexString(h.Handle)),
                                Analyzer.FormatByteToString(h.ReservedMemory),
                                h.HeapName
                                ));
    }
    WriteBlankLine();
    WriteBlankLine();
}

You must’ve noticed a function called ‘CreateAnchor’ which is actually used to link that Heap handle to details of Heap in the report… You can see how easy it is to use Lambda expression to get the results we need. Drawing graph has been never this easy. Isn’t it?

Now here is a question. How to show graph for Top 10 Heaps by Committed Size? No prizes for answer!

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Sample Code : How to show list of threads (Windbg kbn)?

date February 21, 2009 00:07 by author Sukesh Ashok Kumar

This code snipped shows how easy it is to show list of threads and it's frames with details in the report

// This code snippet shows how easy it is to show list of threads and it's frames with details
public class ThreadAnalysis : iPlugType
{
    public override void RunAnalysis()
    {
        BeginReport("Thread Analysis");

        // ****************** THREAD INFO ********************
        // Iterate through all threads
        foreach (ThreadStack threaditem in Analyzer.ThreadStackCollection)
        {
            WriteHTMLLine("<b>Thread # {0}, SystemID # {1}</b>" , 
                                CreateBookmark(AnchorType.Thread, threaditem.ThreadID.ToString()) ,
                                threaditem.SystemID.ToString());

            WriteDataLine("Entry point : {0}" , 
                                Analyzer.GetSymbolFromAddress(Analyzer.GetEntryPointForThread(threaditem.ThreadID)));
            WriteDataLine("Create Time : {0} {1}" , 
                                threaditem.CreateTime.ToShortDateString(),
                                threaditem.CreateTime.ToLongTimeString());
            WriteDataLine("Time spent in User Mode : {0}",threaditem.UserTimeAsString);
            WriteDataLine("Time spent in Kernel Mode : {0}",threaditem.KernelTimeAsString);
            
            WriteBlankLine();

            //Iterate through all frames
            WriteDataLine("Fr#.ChildEBP...ReturnAddr.Function Arguments");    // Heading
            foreach (ThreadFrame frameitem in threaditem.ThreadFrameCollection)
            {
                WriteDataLine("{0} {1} {2} {3} {4} {5} {6} {7} {8}",
                            frameitem.FrameNumber.ToString("x3"),
                            Analyzer.GetAsHexString(frameitem.ChildEBP),
                            Analyzer.GetAsHexString(frameitem.ReturnAddress),
                            Analyzer.GetAsHexString(frameitem.arg1),
                            Analyzer.GetAsHexString(frameitem.arg2),
                            Analyzer.GetAsHexString(frameitem.arg3),
                            Analyzer.GetAsHexString(frameitem.arg4),
                            frameitem.FunctionName,
                            frameitem.SourceInfo
                            );
            }
            WriteBlankLine();
        }
        EndReport();
    }
}

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Hello World Analysis Plug

date February 20, 2009 23:31 by author Sukesh Ashok Kumar

A lot of work was done to keep simplicity and zero learning curve for writing Analysis Plugs. Steps to create a Hello World Plug mentioned below

  • Using Visual Studio or Visual Studio Express create a 'Class Library' project
  • Add reference to PlugFramework.Api
  • Inherit the Class from iPlugType
  • Override a method called RunAnalysis()
  • Build the DLL and copy to 'Plugs' folder
  • Add to any Analysis Template!
public class Class1 : iPlugType                                     // Derive your analysis class from iPlugType
{
    public override void RunAnalysis()                              // Override RunAnalysis()
    { 
        // Begin Report & specify Title of Analysis section
        BeginReport("Hello World!");                                

        WriteDataLine("1st Line of the report!");                     // Normal report line using fixed width font
        WriteBlankLine();                                             // Add blank line in the report
        WriteBoldLine("Drawing Graph has become easy as well...");    // Add Bold line
        WriteGraphLine(GraphColors.Gray, 70, "msvcrt.dll - 70%");     // Add Graph with color, percentage and label
        
        // Adding HTML content
        WriteHTMLLine("Testing for HTML content inline like <b>bold</b> <i>italics</i> <u>underline</u> words");

        // Adding analysis recommendation
        WriteRecommendation(ResultSeverity.Information, 
                            "Process crashed during Heap function call normally indicates Heap Corruption",
                            "Please Enable page heap and configure DebugDiag with Crash Rule"
                        );

        // End Reporting
        EndReport();
    }
}

This is a sample plug to show the different functions available but does not do any analysis by itself!

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5



Application Disclaimer

Debug Analyzer.NET and the associated documentation are provided "as-is". You bear the risk of using it. No express warranties, guarantees or conditions are provided. It is not supported or endorsed by my Employer and should be used at your own risk.

Disclaimer

All opinions posted here are those of the author and are in no way intended to represent the opinions of his employer. All posts are provided "AS IS" with no warranties, and confers no rights. © Copyright 2009

Recent Comments

Sign in