Search code examples
debuggingwindbgfirst-chance-exceptiongflagsprocdump

Generate dumps on first chance exceptions of multiple instances of an application


I would like to generate a dump for first chance exceptions for a specific application that get's launched at random intervals several times a day, running multiple instances at any one time.

What have I tried

Procdump

To use procdump I have to know the PID or wait for the process to launch. As multiple instances get launched, this will not work to start monitoring all the launched instances

gflags

Using gflags I could attach a debugger but I don't want to manually continue each process and I have no idea how to automate the process. I tried using procdump as debugger in gflags but I don't know how to pass the process to procdump.


Solution

  • In my comments I was mixing up the %ld parameter from the AeDebug registry setting with that of GFlags. However, AeDebug will not be useful here, since it only comes into play when the application is crashing, which isn't the case here.

    I'm using the following demo application to generate some first chance exceptions:

    using System;    
    namespace ThrowSomeFirstChance
    {
        static class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine(args[0]);
                try
                {
                    throw new ApplicationException("Exception 1");
                }
                catch (Exception){}
                try
                {
                    throw new ApplicationException("Exception 2");
                }
                catch (Exception){}
                Console.ReadLine();
            }
        }
    }
    

    GFlags + ProcDump

    The whole idea of that GFlags setting (which affects the Image File Execution Options registry key) is to run the application under the debugger to really debug all sorts of things right from the start of the application. So if you use the GFlags setting, you can't pass a process ID, since at that time, the process has not been started yet. The process must be started by the debugger.

    With the following GFlags setting, ProcDump works fine for me:

    E:\debug\procdump.exe -ma -e 1 -n 4 -x e:\debug\dumps
    

    where

    • -ma gets the full memory, which is useful for .NET
    • -e 1 captures first chance exceptions
    • -n 4 specifies a maximum amount of dumps to generate (some applications may generate hundred of exceptions)
    • -x <dump folder> <application> <arguments> specifies the executable to launch

      Note that the -x option seems to be incomplete, but that's ok since Windows will pass the application name and arguments automatically and probably was the reason for the odd order of arguments here.

    GFlags settings

    GFlags + WinDbg

    Doing the same with WinDbg is much more work. You'll need to run WinDbg in the correct bitness to get good results and catching all first chance exceptions isn't simple.

    "E:\debug\x86\WinDbg.exe"  -G -Q -c $$<e:\debug\dump.dbg 
    
    • -G skip the final breakpoint when the application terminates (minimize user interaction)
    • -Q skip the "Save workspace" question (minimize user interaction)
    • -c $$<dump.dbg run a script

      The script will be run at the initial breakpoint, so don't use the -g option (skip initial breakpoint). Instead, set up the things at that time and continue with g. A script may look like

      sxe -c ".dump /ma /u e:\debug\dotnet.dmp;g" clr
      g
      

      However, note that this only covers .NET first chance exceptions and the debugger will wait for input for other exceptions. If you want to get this complete, you'll need to set up commands for all types of exceptions, which is far from convenient (see also this answer).