[PowerShell Script] Chart and Statistics from Top 20 Objects Leaking
If you want to know the top 20 objects associated with the GC Handles that are leaking, you have manual work to do. Think about it:
a) Run GCHandleLeaks and wait… it’s going to take time.
b) Get the objects’ instances from the handles.
c) Count and classify them.
d) Get the 20 objects that appear most often.
Thus, this script saves you time when you need to get this information since it automates these steps.
Of course, it takes time to finish because it runs !sos.GCHandleLeaks and gets the information for each handle. After that, it shows you the top 20 objects leaking.
If you install LogParser, you can get a beautiful chart that shows you the top 20 objects leaking. (great stuff to put in reports J)
Note: You have the install the latest PowerDbg version to use this script.
Screenshots:
Source code for PowerShellScriptGCHandleLeaksChart.ps1:
########################################################################################################
# Script: PowerDbgScriptGCHandleLeaksChart
#
# Parameters: None.
#
# Purpose: Shows the top 10 objects associated with GC Handles that are leaking and a graphical view
# of these objects.
# Use this script to troubleshoot memory leaks associated with pinned handles, for example.
#
# Attention! This is for 32 bits.
#
# Usage: Before running the script:
# a) Open your workspace to load the symbols.
# b) .wtitle PowerDbg
# c) .reload
# d) .loadby sos mscorwks
#
# Attention! If you don't load the symbols before running the script you may face timing issues.
#
# Changes History:
#
# Roberto Alexis Farah
# All my functions are provided "AS IS" with no warranties, and confer no rights.
########################################################################################################
set-psdebug -strict
$ErrorActionPreference = "continue" # Yes, for this script we expect to have handled exceptions.
trap { continue; }
write-Host "Verifying potential GC Handle leaks... it's going to take time, you can get a cup of coffee now..." -foreground Green -background Black
# Calls !GCHandleLeaks. This command takes A LOT of time to execute.
Send-PowerDbgCommand("!GCHandleLeaks")
# Extracts output from previous command.
Parse-PowerDbgGCHANDLELEAKS
# Converts CSV file to Hash Table.
$output = Convert-PowerDbgCSVtoHashTable
write-Host "Done!" -foreground Green -background Black
# Verify if there are leaks. If not, notify user and quit.
if($output.Count -eq 1)
{
# Notifies user the script finished the execution.
Send-PowerDbgComment "PowerDbgScriptGCHandleLeaks was executed. See the PowerShell window for more information."
write-Host "`n`nThere aren't GC Handles leaking!" -foreground Green -background Black
return
}
# Creates another hash table to stored the objects and the number of times it appears.
$stats = @{}
write-Host "Extracting objects from handles..." -foreground Green -background Black
# Scans all keys and save the value as the key in another hash table.
foreach($key in $output.keys)
{
$objAddress = $output[$key] # The value is the key for the other hash table.
# Use !DumpObj to get the object.
Send-PowerDbgCommand "!DumpObj $objAddress"
Parse-PowerDbgDUMPOBJ
# Here he get the object mapped to a hash table.
$objStruct = Convert-PowerDbgCsvToHashTable
$objName = $objStruct["Name:"]
# If the item is there, increase the number of times it appeared.
$numberOfTimes = $stats[$objName]
# Verifiy if this is the first time the object is going to be saved.
if($numberOfTimes -eq $null)
{
$stats[$objName] = 1
}
else
{
$numberOfTimes++
# Key was there, so increase the number of times it appeared.
$stats[$objName] = $numberOfTimes
}
}
write-Host "Done!" -foreground Green -background Black
write-Host "Creating CSV files..." -foreground Green -background Black
# Prepare string to create CSV file.
$builder = New-Object System.Text.StringBuilder
# Title for the CSV fields.
$builder = $builder.AppendLine("ObjectsLeaking,Occurrences")
# Scans the hash table that contains objects and number of times they appeared.
foreach($key in $stats.keys)
{
$builder = $builder.AppendLine($key + $global:g_CSVDelimiter + $stats[$key])
}
$csvFile = "ObjectsLeaking.CSV"
$csvFileSorted = "SortedObjectsLeaking.CSV"
# Send output to the CSV file.
out-file -filepath $csvFile -inputobject "$builder"
# Sort CSV file and select the top 10 items based on occurrences.
import-csv $csvFile | sort-object Occurrences -desc | select-Object -first 20 | export-csv $csvFileSorted -notypeinformation
# Creates LogParser file.
[string] $logParser = "logparser.exe `"SELECT ObjectsLeaking, Occurrences INTO Top20ObjectsLeaking.gif FROM " + [system.io.path]::GetFullPath($csvFileSorted) + " ORDER BY Occurrences DESC`" -i:CSV -o:CHART -charttype:ColumnClustered -groupsize:512x480 -chartTitle:`"Top 20 Objects Leaking`" -e:1"
$batFile = "Top20ObjectsLeakingChart.bat"
out-File -filepath $batFile -inputobject $logParser -encoding "ASCII"
write-Host "Done!" -foreground Green -background Black
# Notifies user the script finished the execution.
Send-PowerDbgComment "PowerDbgScriptGCHandleLeaks was executed. See the PowerShell window for more information."
$content = import-Csv $csvFileSorted
write-Host "======= Top 20 Objects Leaking From " ($output.Count - 1) " Objects Leaking =======`n`n" -foreground Red -background Black
# Display the top 20 objects leaking.
import-Csv $csvFileSorted
write-Host "`nRun " -foreground Green -background Black -nonewline
write-Host $batFile -foreground Red -background Black -nonewline
write-host " from LogParser folder to see the chart." -foreground Green -background Black
Comments
Anonymous
August 22, 2008
PingBack from http://hubsfunnywallpaper.cn/?p=1985Anonymous
August 24, 2008
@Roberto, if you have not already seen Debugging Toolbox in this cartoon :) http://www.dumpanalysis.org/Cartoons-Narasimha-Vedala/DBG_AtTheChampionships.jpg more: http://www.dumpanalysis.org/arts-photography-linksAnonymous
August 24, 2008
Thanks for the link!:)Anonymous
October 08, 2008
Thanks for the clearest and most useful realworld application of the tool and powershell. tHEY SHOULD INCLUDE YOU ON THE POWERSHELL PAGE. bEING SOMEWHAT OF A NUBIAN i WOULD LOVE TO KNOW HOW TO PLUG LEAKS i FIND IN COMMERCIAL SOFTWARE.Anonymous
October 08, 2008
wHEN WE MANAGE TO SUCCESSFULLY TRACK DOWN THE SOURCE OF buggage IN COMMERCIAL SOFTWARE, HOW DO WE FIX THIS. iS THERE A NET LIBRARY OF GENERAL/COMMON FAULTS AND A FILE DRAWER ON HOW TO FIX THESE BUGS SINCE MOST COMPANIES DON'T HAVE THE SHOP TO TEST PRIOR TO RELEASE, LET ALONE WORRY ABOUT YOU ONCE THEY POCKET YOUR NONEY?Anonymous
October 09, 2008
The comment has been removedAnonymous
February 03, 2009
I’m very excited to present the new PowerDbg v5.0! There’s just one change, but it’s a HUGE change thatAnonymous
March 19, 2009
So, here we go again. This is a minor version with a few new cmdlets. These new cmdlets are those thatAnonymous
April 14, 2009
This version has two improvements and some scripts were changed to be compatible with this new version: