为什么我的堆中有两个空的ThreadAbortException?

时间:2012-02-08 11:05:53

标签: c# windows-services clr windbg

我正在调查WinDBG的内存转储,我想知道为什么堆中有两个System.Threading.ThreadAbortExceptions都是空的。

对于其他三个发现的异常,我理解它们为什么存在并且它们是默认创建的:

  1. System.ExecutionEngineException

  2. System.StackOverflowException

  3. System.OutOfMemoryException

  4. WinDBG输出

    0:000> !dumpheap -type System.Threading.ThreadAbortException

    Address       MT     Size
    010210fc 79330ef8       72     
    01021144 79330ef8       72     
    total 2 objects
    
    Statistics:
    MT    Count    TotalSize Class Name
    79330ef8        2          144 System.Threading.ThreadAbortException
    
    Total 2 objects
    

    0:000> !pe 010210fc

    Exception object: 010210fc
    Exception type: System.Threading.ThreadAbortException
    Message: <none>
    InnerException: <none>
    StackTrace (generated):<none>
    StackTraceString: <none>
    HResult: 80131530
    

    0:000&GT; !pe 01021144

    Exception object: 01021144
    Exception type: System.Threading.ThreadAbortException
    Message: <none>
    InnerException: <none>
    StackTrace (generated): <none>
    StackTraceString: <none>
    HResult: 80131530
    

    所以我的问题是:

    1. 这两个也是默认创建的 - 如果是 - 为什么还有两个?
    2. 如果没有,为什么他们是空的?
    3. 内存转储来自Windows服务。

      使用转储

      中的线程信息进行更新

      0:000&GT; !线程

      ThreadCount: 14
      UnstartedThread: 0
      BackgroundThread: 8
      PendingThread: 0
      DeadThread: 4
      Hosted Runtime: no
      PreEmptive   GC Alloc           Lock
      
      ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
      0    1 11d4 0015c538      a020 Enabled  00000000:00000000 00163aa0     0 MTA
      2    2  71c 0016f6a0      b220 Enabled  00000000:00000000 00163aa0     0 MTA (Finalizer)
      3    4 1914 0019ac48   180b220 Enabled  6a205b0c:6a207910 00163aa0     0 MTA (Threadpool Worker)
      5    6 1bd4 001b1580   200b020 Enabled  00000000:00000000 00163aa0     0 MTA
      6    7 16a4 001bd260   200b220 Enabled  6a1dc7b8:6a1dd910 00163aa0     0 MTA
      7    8  870 001c4a58   200b220 Enabled  6a1da740:6a1db910 00163aa0     0 MTA
      8    9 2204 001cf798      b220 Enabled  00000000:00000000 00163aa0     0 MTA
      9    d  4d8 0021cb98    80a220 Enabled  00000000:00000000 00163aa0     0 MTA (Threadpool Completion Port)
      10    e 1b70 002227c0   200b220 Enabled  6a27d820:6a27d910 00163aa0     0 MTA
      11   89 2224 68a3fbd0   880b220 Enabled  00000000:00000000 00163aa0     0 MTA (Threadpool Completion Port)
      XXXX   11    0 2336e658   8801820 Enabled  00000000:00000000 00163aa0     0 Ukn (Threadpool Completion Port)
      XXXX   46    0 16d17270   8801820 Enabled  00000000:00000000 00163aa0     0 Ukn (Threadpool Completion Port)
      XXXX   3a    0 16ca7a70   8801820 Enabled  00000000:00000000 00163aa0     0 Ukn (Threadpool Completion Port)
      XXXX   3b    0 10e64250   8801820 Enabled  00000000:00000000 00163aa0     0 Ukn (Threadpool Completion Port)
      

1 个答案:

答案 0 :(得分:5)

它们由CLR预先分配。我将让CLCL的SSCLI20版本中的这些片段讲述这个故事:

来自clr / src / vm / clrex.cpp,CLRException :: GetThrowable():

// If creating a normal ThreadAbortException fails, due to OOM or StackOverflow,
// use a pre-created one.
// We do not won't to change a ThreadAbortException into OOM or StackOverflow, because
// it will cause recursive call when escalation policy is on:
// Creating ThreadAbortException fails, we throw OOM.  Escalation leads to ThreadAbort.
// The cycle repeats.
throwable = GetPreallocatedThreadAbortException();

相同的文件,CLRException :: GetPreallocatedRudeThreadAbortException()方法:

// When we are hosted, we pre-create this exception.
// This function should be called only if the exception has been created.
_ASSERTE(g_pPreallocatedRudeThreadAbortException);
return ObjectFromHandle(g_pPreallocatedRudeThreadAbortException);

“循环重复”可以使用一些解释:OutOfMemoryException - &gt; Thread.Abort() - &gt; new ThreadAbortException() - &gt; OutOfMemoryException - &gt; Thread.Abort的()。等等。

同样的源文件也有GetPreallocatedOutOfMemoryException(),GetPreallocatedStackOverflowException()和GetPreallocatedExecutionEngineException(),原因完全相同。