mark
mark

Reputation: 62774

Unable to capture a dump for OutOfMemory exception using ProcDump

I have a .NET program that throws OutOfMemoryException. The exception is handled, since the Main function has the following structure:

public static int Main(string[] args)
{
    try
    {
      ... 
    }
    catch (Exception exc)
    {
        Console.Error.WriteLine(exc);
        return 1;
    }
}

Now I would like a memory dump to be created the moment this exception is thrown. For that I use the following command:

procdump.exe -e 1 -f OutOfMemoryException -g -ma -w Log4Net2DB.exe

But, it does not work:

PS D:\tmp> procdump.exe -e 1 -f OutOfMemoryException -g -ma -w Log4Net2DB.exe

ProcDump v7.0 - Writes process dump files
Copyright (C) 2009-2014 Mark Russinovich
Sysinternals - www.sysinternals.com
With contributions from Andrew Richards

Waiting for process named Log4Net2DB.exe...

Process:               Log4Net2DB.exe (47712)
CPU threshold:         n/a
Performance counter:   n/a
Commit threshold:      n/a
Threshold seconds:     10
Hung window check:     Disabled
Log debug strings:     Disabled
Exception monitor:     First Chance+Unhandled
Exception filter:      *OutOfMemoryException*
Terminate monitor:     Disabled
Cloning type:          Disabled
Concurrent limit:      n/a
Avoid outage:          n/a
Number of dumps:       1
Dump folder:           D:\tmp\
Dump filename/mask:    PROCESSNAME_YYMMDD_HHMMSS


Press Ctrl-C to end monitoring without terminating the process.

[18:09:30] Exception: E0434F4E.CON
[18:09:41] Exception: E0434F4E.CON
[18:09:41] Exception: E0434F4E.CON
[18:09:48] Exception: E0434F4E.CON
[18:10:27] Exception: E0434F4E.CON
[18:10:36] Exception: E0434F4E.CON
[18:10:43] Exception: E0434F4E.CON
[18:10:45] Exception: E0434F4E.CON
[18:10:46] Exception: E0434F4E.CON
[18:10:51] Exception: E0434F4E.CON
[18:10:55] Exception: E0434F4E.CON
[18:10:59] Exception: E0434F4E.CON
[18:11:10] Exception: E0434F4E.CON
[18:11:28] Exception: E0434F4E.CON
[18:11:38] Exception: E0434F4E.CON
[18:11:55] Exception: E0434F4E.CON
[18:13:58] Exception: E0434F4E.CON
[18:15:33] Exception: E06D7363.PAVException@@
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: E0434352.CLR
[18:15:33] Exception: C0020001
[18:15:35] The process has exited.
[18:15:35] Dump count not reached.

PS D:\tmp>

Notice the last message - "Dump count not reached". But the program does terminate with an OutOfMemoryException (handled in the catch statement in the end of the Main function):

PS D:\tmp> logs2db.ps1 -- -dir D:\tmp\us850 -r -db us850
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at System.Security.Cryptography.SHA1Managed..ctor()
   at Log4Net2DB.Program.ComputeHash(ILogEntry logEntry, BinaryWriter bw) in C:\Log4Net2DB\Log4Net2DB\Program.cs:line 246
   at Log4Net2DB.Program.<>c__DisplayClass10_0.<GetBatchSource>b__2(ILogEntry entry) in C:\Log4Net2DB\Log4Net2DB\Program.cs:line 232
   at System.Reactive.Linq.ObservableImpl.Select`2._.OnNext(TSource value)
--- End of stack trace from previous location where exception was thrown ---
   at System.Reactive.PlatformServices.DefaultExceptionServices.Rethrow(Exception exception)
   at System.Reactive.ExceptionHelpers.ThrowIfNotNull(Exception exception)
   at System.Reactive.Subjects.AsyncSubject`1.GetResult()
   at Log4Net2DB.Program.Main(String[] args) in C:\Log4Net2DB\Log4Net2DB\Program.cs:line 200
PS D:\tmp>

For the record, I also tried to run procdump like this:

procdump.exe -e 1 -f C0020001 -g -ma -w Log4Net2DB.exe

To no avail.

Note, that running procdump.exe -e 1 -g -ma -w Log4Net2DB.exe does generate a dump for the very first exception, which is raised and handled internally by the run-time when the GC is triggered, more details are here - RedirectedThreadFrame in Callstack, so I know procdump is able to produce dumps for my program.

But I cannot make it produce the dump for the OOM. What am I doing wrong?

P.S.

My machine is 64 bits, but for some peculiar reason the program runs as 32 bits, even though it does not reference any interop DLLs. And so, OOM is raised when it consumes around 3.7GB of RAM.

Upvotes: 5

Views: 2787

Answers (1)

codekaizen
codekaizen

Reputation: 27419

You need to leave off the -g flag. You want to catch the managed exception, and -g attaches procdump as a native debugger.

Consider this LinqPad query which generates an OutOfMemoryException:

void Main()
{
    var list = new List<Int32>();
    for (var i = 0; i < Int32.MaxValue; i++)
    {
        list.Add(i);
    }
}

Running with -g:

> procdump -ma -e 1 -f OutOfMemoryException -g -w "LINQPad.UserQuery"

...

Press Ctrl-C to end monitoring without terminating the process.

[00:52:33] Exception: E06D7363.PAVException@@
[00:52:33] Exception: E0434352.CLR
[00:52:34] The process has exited.
[00:52:34] Dump count not reached.

Without -g:

procdump -ma -e 1 -f OutOfMemoryException -w "LINQPad.UserQuery"

...

CLR Version: v4.0.30319

[00:53:01] Exception: E0434F4D.System.OutOfMemoryException
[00:53:01] Dump 1 initiated: LINQPad.UserQuery.exe_170720_005301.dmp
[00:53:02] Dump 1 writing: Estimated dump file size is 496 MB.
[00:53:02] Dump 1 complete: 497 MB written in 0.5 seconds
[00:53:02] Dump count reached.

Also, to address the 32 bit issue - .Net 4.5+ binaries have a new flag which specifies "Prefer 32-bit" even if it is set to AnyCPU and running on a 64-bit OS. You can control this in the project properties.

Upvotes: 5

Related Questions