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

发布于 2025-01-03 09:35:23 字数 3008 浏览 4 评论 0原文

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

对于其他三个发现的异常,我了解它们为何存在以及它们是默认创建的:

  1. System.ExecutionEngineException

  2. System.StackOverflowException

  3. System.OutOfMemoryException

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> !pe 01021144

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

所以我的问题是:

  1. 这两个也是默认创建的 - 如果是的话 - 为什么有两个?
  2. 如果不是,为什么它们是空的?

内存转储来自 Windows 服务。

使用转储

0:000> 中的线程信息进行更新!线程

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)

I am investigating a memory dump with WinDBG and I am wondering why the heap holds two System.Threading.ThreadAbortExceptions which are both empty.

For the other three found exceptions I understand why they are there and that they are created by default:

  1. System.ExecutionEngineException

  2. System.StackOverflowException

  3. System.OutOfMemoryException

WinDBG output

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> !pe 01021144

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

So my questions would be:

  1. Are these two also created by default and - if so - why are there two?
  2. If not, why are they empty?

The memory dump is from a Windows Service.

Update with thread information from dump

0:000> !threads

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眼泪都笑了 2025-01-10 09:35:23

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

从 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();

Same file, 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 -> Thread.Abort() ->;新的 ThreadAbortException() -> OutOfMemoryException ->线程.Abort()。等等。

出于完全相同的原因,同一源文件还具有 GetPrealulatedOutOfMemoryException()、GetPrealulatedStackOverflowException() 和 GetPrealulatedExecutionEngineException()。

They are pre-allocated by the CLR. I'll let these snippets from the SSCLI20 version of the CLR tell the story:

From 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();

Same file, CLRException::GetPreallocatedRudeThreadAbortException() method:

// 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);

"The cycle repeats" could use some explanation: OutOfMemoryException -> Thread.Abort() -> new ThreadAbortException() -> OutOfMemoryException -> Thread.Abort(). Etcetera.

The same source file also has GetPreallocatedOutOfMemoryException(), GetPreallocatedStackOverflowException() and GetPreallocatedExecutionEngineException() for the exact same reasons.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文