Analyser un dump de worker process avec PowerShell / Worker process dump analysis with PowerShell


 

[MAJ 24/06/2016] Il y a quelques semaines un de mes collègues (Merci Julien !), m’a fait découvrir PowerDbg. PowerDbg est une librairie PowerShell vous permettant de créer facilement des scripts PowersShell pour automatiser des sessions de debugging WinDbg / CDB (plus de détails ici). Ce collègue m’envoya un exemple d’utilisation de PowerDbg pour le debug d’une application ASP.Net au sein d’un worker processus IIS – w3wp.exe). J’ai décidé de développer une version « full » PowerShell de cet exemple (J’ai supprimé des dépences externes de la version originale) que je vous propose dans cet article (le fichier source est disponible ici). Dans cet exemple je charge seulement 2 extensions – SOS and CLR – et je lance seulement deux commandes – !pe and !ClrStack. Vous pouvez personnaliser ou ajouter les extensions que vous voulez charger et les commandes associées. Le résultat est un fichier CSV ressemblant à peu près à celui-ci (sortie volontairement tronquée) :

powerdbg

Si vous désirez générer des dumps de worker processus vous pouvez jeter un coup d’oeil à ces deux ressources :


[Updated 06/24/2016] Some weeks ago a colleague of mine (Thanks Julien !),pointed me to PowerDbg. PowerDbg is a PowerShell library that enables you to easily create PowerShell scripts to automate a WinDbg / CDB debugging session (further details here). This colleague sent to me a PowerDbg use case for debugging an ASP.Net application (inside an IIS worker process – w3wp.exe). I decided to build a full PowerShell version of this example (I removed some external depencies of the original version) and I propose it to you in this article (the source file is available here). In this example I load only 2 extensions – SOS and CLR – and I run only two commands – !pe and !ClrStack. You can add or customize the extensions you want to load and the related commands. The result is a CSV file looking like this one (output was truncated):
 powerdbg
If you want generate worker process dumps you can take a look at this two resources :
#requires -version 2 #requires -Module PowerDbg Import-Module -Name PowerDbg #region My function definitions function New-PDBGCrashAnalysis { <# .SYNOPSIS Runs a debugging session for the dump(s) passed as parameter(s) .DESCRIPTION Runs a debugging session for the dump(s) passed as parameter(s) .PARAMETER FullName The full file path of the dump(s) to analyze .EXAMPLE New-PDBGCrashAnalysis -FullName "C:\Tools\Dumps\w3wp.exe_160518_000457.dmp", "C:\Tools\Dumps\w3wp.exe_160518_002041.dmp" -Verbose Runs a debugging session for the two specified worker process dumps ("C:\Tools\Dumps\w3wp.exe_160518_000457.dmp", "C:\Tools\Dumps\w3wp.exe_160518_002041.dmp" ) .EXAMPLE Get-ChildItem -Path 'C:\Temp' -Filter 'w3wp*.dmp' -Recurse | New-PDBGCrashAnalysis -Verbose Returns all worker processes dumps in the C:\Temp folder (and its subfolders) and runs a debugging session for all of them. #> [CmdletBinding()] Param( [Parameter(Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)] #The BLG File to convert : Checking if the file exists and has the .dmp extension [ValidateScript({ (Test-Path -Path $_ -PathType Leaf) -and ($_ -match '\.dmp$') })] [alias('Source', 'Dump')] [String[]]$FullName ) begin { #Array for storing the results $Analyses = @() } process { #For all files passed as argument outside a pipeline context Foreach ($CurrentFullName in $FullName) { Write-Verbose -Message "Processing $CurrentFullName ..." # Close proactively any existing debugger session if already connected for some reason Exit-DbgSession #Disconnect-Windbg Write-Verbose -Message 'Closing proactively any existing debugger session if already connected for some reason ...' Write-Verbose -Message 'Creating new DBG Session.' New-DbgSession -Dump $CurrentFullName Write-Verbose -Message 'Loading sos and clr extensions' Load-DbgExtension sos Load-DbgExtension clr #Invoke-DbgCommand !pe2 Write-Verbose -Message 'Invoking DBG command : !pe' $Exception = Invoke-DbgCommand !pe Write-Verbose -Message 'Invoking DBG command : !ClrStack' $ClrStack = Invoke-DbgCommand !ClrStack Write-Verbose -Message "Exception : $Exception " Write-Verbose -Message "ClrStack : $ClrStack " $Analyses += New-Object -TypeName PSObject -Property @{ FullName = $CurrentFullName Exception = $Exception[1] Message = $Exception[2] ClrStack = $ClrStack -join "`r`n" } Write-Verbose -Message 'Disconnecting new DBG Session' Exit-DbgSession #Disconnect-Windbg } } end { #returning the data array return $Analyses } } #endregion Clear-Host # Getting the this script path $CurrentScript = $MyInvocation.MyCommand.Path # Getting the directory of this script $CurrentDir = Split-Path -Path $CurrentScript -Parent # Creating CSV file name based on the script full file path and by appending the timestamp at the end of the file name $CSVFile = $CurrentScript.replace((Get-Item -Path $CurrentScript).Extension, '_'+$(Get-Date -Format 'yyyyMMddTHHmmss')+'.csv') # Without pipeline use #$Analyses = New-PDBGCrashAnalysis -FullName "C:\Tools\Dumps\w3wp.exe_160518_000457.dmp", "C:\Tools\Dumps\w3wp.exe_160518_002041.dmp" -Verbose # With pipeline use # Looking for dumps in the script folder (and subfolders) $Analyses = Get-ChildItem -Path $CurrentDir -Filter 'w3wp*.dmp' -Recurse | New-PDBGCrashAnalysis -Verbose $Analyses | Group-Object -Property Message | Sort-Object -Property Count -Descending | Select-Object -Property @{ Name = 'Message' Expression = { $_.Name } }, Count #$Analyses | Format-List * -Force $Analyses | Export-Csv -Path $CSVFile -Force -NoTypeInformation Write-Host -Object "Results are available in '$CSVFile'"

Laurent.


Comments (0)

Skip to main content