I thought I’d share a script I’ve been using on some recent cases to generate memory dump files on multiple machines for intermittent crashes. The scenario this script targets is that you have a process, say Outlook.exe, which is crashing for a number of users, but you haven’t yet narrowed down a repro scenario. You’d like to get memory dumps when the process crashes, and you’d also like to get extra debugging information which may help you hone in on the issue. You'd also like to set all of this up so the user doesn't have to do anything themselves. They just run the process and data is generated automatically for you to collect later.

This script, set through Image File Execution Options, attaches Procdump.exe to your process every time it starts, so it can listen for exceptions and write dump files when interesting ones occur. It also captures Procdump’s debug spew in a log file which you can use to identify first chance exceptions that you'd also like to get dumps for. Once enabled, you'll just need to visit the user's machine periodically to collect the dumps and logs for analysis.

To use this script, create a file called DoProcDump.cmd and place it in c:\tools alongside procdump.exe (you can configure these paths differently if you like, but you’ll need to modify the script) and then create an entry under Image File Execution Options. Next time the user starts the process, Procdump will attach and listen for exceptions. There are a number of ways you can change up the data collection, such as enabling first chance exceptions, or getting dumps on process shutdown (useful for silent exits, though this is even better). Look at the comments in the script to see how to enable and configure these.

To disable this script, just remove the reg key you created under Image File Execution Options.

BTW, I got the unique file name code from here: http://blogs.msdn.com/b/myocom/archive/2005/06/03/creating-unique-filenames-in-a-batch-file.aspx

Enjoy!

@ECHO off
REM *****DoProcDump.cmd*****
REM Configure this in Image File Execution Options like so:
REM [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\Outlook.exe]
REM "Debugger"="cmd /c c:\\tools\\DoProcdump.cmd"
REM (Double \\ are how \ are represented in .reg files. If setting this value manually, use single \.)

REM Change these paths to reflect the location of Procdump and the location to which the output files should be written.
REM Data collection should include .dmp files and all procdumpOutput*.txt files written to the out path.
set PDOutPath="C:\tools"
set PDExe="C:\tools\Procdump.exe"

REM Only enable one of the following.
REM Use this filter to catch only second chance exceptions.
Set PDFilter=/e
REM Enable this filter to catch specific first chance exceptions in addition to second chance exceptions.
REM Set PDFilter=/e 1 /f "System.Threading.ThreadAbortException" /f "System.AccessViolationException"

REM Configure the maximum number of dumps to gather here.
Set PDNumDumps=5

REM Enable this also gather dumps on process shutdown.
REM Set PDTerm=/t

set PDCfg=/ma /n %PDNumDumps% %PDTerm% %PDFilter% /x

@ECHO *************************************************************
@ECHO *                                                           *
@ECHO *               DO NOT CLOSE THIS WINDOW!                   *
@ECHO *                                                           *
@ECHO * This window will close automatically  when Outlook exits. *
@ECHO *                                                           *
@ECHO *************************************************************
@ECHO.
@ECHO Running: %PDExe% %PDCfg% %PDOutPath% %*

REM This generates a good file name for our log file.
for /f "delims=/ tokens=1-3" %%a in ("%DATE:~4%") do (
   for /f "delims=:. tokens=1-4" %%m in ("%TIME: =0%") do (
      set LOGFILE=%PDOutPATH%\procdumpOutput-%username%-%%c-%%b-%%a-%%m%%n%%o%%p.txt
   )
)

@ECHO %* > %LOGFILE%
@ECHO Current time %TIME: =0% >> %LOGFILE%
@ECHO Running: %PDExe% %PDCfg% %PDOutPath% %* >> %LOGFILE%

%PDExe% %PDCfg% %PDOutPath% %* >> %LOGFILE% 2>&1