Reputation: 62774
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
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