在WinDbg中,我在七个不同的堆损坏引起的故障转储上执行了命令!heap -s -v
,并且都有这些结果:
..................List corrupted: (Blink->Flink = 0000000000000000) != (Block = 00000000026d0010)
HEAP 0000000002030000 (Seg 00000000026d0000) At 00000000026d0000 Error: block list entry corrupted
HEAP 0000000002030000 (Seg 00000000026d0000) At 00000000026d0000 Error: SegmentIndex field corrupted
HEAP 0000000002030000 (Seg 00000000026d0000) At 0000000002749400 Error: invalid block size
我应该如何解释这些结果?
我解释(Seg 00000000026d0000)
意味着WinDbg认为它是一个段(_HEAP_SEGMENT
),但它实际上是大块缓存的地址(这与每个转储一致):
+0x2b8 LargeBlocksIndex : 0x00000000`026d0000 Void
我已经确认,在崩溃发生之前,使用相同操作系统和相同进程进行的转储不会出现任何WinDbg验证问题。
简而言之,我不知道为什么WinDbg会抱怨26d0000
地址,或者为什么它可能会将其解释为一个段(如果这甚至是它正在做的那样)。
所有转储都来自Windows 2003 R2计算机。这个过程是64位的。
答案 0 :(得分:0)
事实证明,我正在处理的特定崩溃是对Windows 2003堆段内数据量限制的结果(~106 GiB)。内存变得过于分散,程序无法在段内找到空间,以便分配不到1 MiB的分配。我最初排除了这一点,因为机器上的物理RAM量(192 GiB)以及RAM使用率(8 TiB)的每个进程限制。
我还没有找出WinDbg结果的原因,但是我愿意忽略它作为一个可能的误报,因为堆处于一个不一致的状态,当堆耗尽段内存时执行的代码路径。