无法使用ProcDump捕获OutOfMemory异常的转储

时间:2017-01-12 00:22:33

标签: c# out-of-memory dump

我有一个抛出OutOfMemoryException的.NET程序。处理异常,因为Main函数具有以下结构:

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

现在我希望在抛出此异常时创建内存转储。为此,我使用以下命令:

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

但是,它不起作用:

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>

注意最后一条消息 - “未达到转储计数”。但该程序以OutOfMemoryException终止(在catch函数末尾的Main语句中处理):

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>

为了记录,我还试图像这样运行procdump

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

无济于事。

注意,运行procdump.exe -e 1 -g -ma -w Log4Net2DB.exe确实会为第一个异常生成转储,该异常由GC触发时的运行时内部引发和处理,更多详细信息在此处 - RedirectedThreadFrame in Callstack,所以我知道procdump能够为我的程序生成转储。

但是我无法让它为OOM生成转储。我做错了什么?

P.S。

我的机器是64位,但由于某些特殊原因,程序运行为32位,即使它没有引用任何互操作DLL。因此,OOM在消耗大约3.7GB RAM时会被提升。

1 个答案:

答案 0 :(得分:3)

您需要取消-g标志。您希望捕获托管异常,-g将procdump作为本机调试器附加。

考虑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);
    }
}

使用-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.

没有-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.

此外,为解决32位问题 - .Net 4.5+二进制文件有一个新标志,指定“首选32位”,即使它设置为AnyCPU并在64位操作系统上运行。 You can control this in the project properties