如何在DPH_BLOCK_INFORMATION中避免“(null)”StackTrace?

时间:2009-09-18 00:41:58

标签: heap windbg cdb

我正在追踪一些堆腐败。我已经使用

启用了标准页面堆验证
gflags /p /enable myprogram.exe

这成功地证实了腐败:

===========================================================
VERIFIER STOP 00000008: pid 0x1040: corrupted suffix pattern 

    10C61000 : Heap handle
    19BE0CF8 : Heap block
    00000010 : Block size
    00000000 : 
===========================================================

当我打开整页堆验证(gflags /p /enable myprogram.exe /full)时,预计这会导致在引入损坏时发生错误,我什么也没得到。

我在阅读Advanced Windows Debugging: Memory Corruption Part II—Heaps时开始抱起我的希望,这是Advanced Windows Debugging的一章。我安装了WinDbg,并根据http://support.microsoft.com/kb/311503下载了user32.dllkernel32.dllntdll.dll的调试符号。现在,当程序在调试器中暂停时,我可以发出此命令以查看有关堆页面的信息:

0:000> dt _DPH_BLOCK_INFORMATION 19BE0CF8-0x20
ntdll!_DPH_BLOCK_INFORMATION
   +0x000 StartStamp       : 0xabcdaaaa
   +0x004 Heap             : 0x90c61000 
   +0x008 RequestedSize    : 0x10
   +0x00c ActualSize       : 0x38
   +0x010 FreeQueue        : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x010 TraceIndex       : 0
   +0x018 StackTrace       : (null) 
   +0x01c EndStamp         : 0xdcbaaaaa

我对(null)堆栈跟踪感到沮丧。现在,http://msdn.microsoft.com/en-us/library/ms220938%28VS.80%29.aspx说:

  

由于各种原因,StackTrace字段不会始终包含非null值。首先,仅在x86平台上支持堆栈跟踪检测,其次,即使在x86机器上,堆栈跟踪检测算法也不完全可靠。如果块是已分配的块,则堆栈跟踪用于分配时刻。如果块被释放,则堆栈跟踪是空闲时刻。

但是我想知道是否有人想要增加从分配时刻看到堆栈跟踪的机会。

感谢阅读!

2 个答案:

答案 0 :(得分:1)

啊哈哈!事实证明我需要启用更多gflags选项:

gflags /i myprogram.exe +ust

具有这种效果:

ust - Create user mode stack trace database

当我看到参数说明时,似乎很简单。傻我。但我似乎还需要设置跟踪数据库的大小才能生效:

gflags /i myprogram.exe /tracedb 512

......或其他(以MB为单位)。

答案 1 :(得分:1)

根据Microsoft的说法,C运行时(CRT)模块中的malloc函数在某些Windows版本中使用了帧指针省略(FPO)。您可能看不到malloc函数的完整堆栈信息。 (http://support.microsoft.com/kb/268343)

如果可能,尝试链接调试版CRT,例如链接/ MDd选项,以解决此问题。