为什么启用用户模式堆栈跟踪后无法获得完整的堆栈跟踪信息?

4

我正在解决一些内存碎片问题,一直在试图找出为什么会被分配和最终进行分配的原因。所以我启用了进程的用户模式堆栈跟踪(gflags中的+UST标志),并得到了一个转储文件。当我分析转储文件并使用 !heap -p -a Some_Address 命令时,我看到了一个堆栈跟踪,但它肯定不是完整的跟踪。通常我只能看到4-7个函数的跟踪,然后就停止了。堆栈中没有报告错误,但不幸的是它没有足够的信息。我检查了一堆分配,并且它们似乎都有同样的问题。我原以为可能是堆栈数据库的大小问题,但我本来希望失去整个条目而不是只是失去部分条目。是否有什么我可以做来增加可视堆栈的总大小?下面是我看到的一些堆栈示例。

0:000> !heap -p -a 3cb49008
    address 3cb49008 found in
    _HEAP @ 80000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        3cb49000 0fdd 0000  [07]   3cb49008    07ed0 - (busy)
        Trace: 6b69
        7c855014 ntdll!RtlAllocateHeapSlowly+0x00000041
        7c83d9aa ntdll!RtlAllocateHeap+0x00000e9f
        776bcfce ole32!CRetailMalloc_Alloc+0x00000016
        77d0404a oleaut32!APP_DATA::AllocCachedMem+0x0000004f
        77d04341 oleaut32!SysAllocStringByteLen+0x0000003c
        77d03f9b oleaut32!ErrStringCopyNoNull+0x00000016
        77d0456f oleaut32!VariantCopy+0x0000007e
        3ff1946 xxxx!_variant_t::_variant_t+0x00000016


0:000> !heap -p -a 2774cfc8
    address 2774cfc8 found in
    _HEAP @ 3cc0000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        2774cfc0 0008 0000  [17]   2774cfc8    00020 - (busy)
        Trace: 7de8
        7c855014 ntdll!RtlAllocateHeapSlowly+0x00000041
        7c83d9aa ntdll!RtlAllocateHeap+0x00000e9f
        4f6ad17 xxxx!malloc+0x0000007a


0:000> !heap -p -a 3ca25e08
    address 3ca25e08 found in
    _HEAP @ 80000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        3ca25e00 0007 0000  [07]   3ca25e08    00020 - (busy)
        Trace: 8588
        7c855014 ntdll!RtlAllocateHeapSlowly+0x00000041
        7c83d9aa ntdll!RtlAllocateHeap+0x00000e9f
        776bcfce ole32!CRetailMalloc_Alloc+0x00000016
        77d0404a oleaut32!APP_DATA::AllocCachedMem+0x0000004f
        77d04341 oleaut32!SysAllocStringByteLen+0x0000003c
        77d03f9b oleaut32!ErrStringCopyNoNull+0x00000016
        77d0456f oleaut32!VariantCopy+0x0000007e
        4f35abd xxxx!std::_Construct<_variant_t,_variant_t>+0x0000004d

我在想 - 你的构建是否会省略帧指针? - Eran
我刚刚检查了项目,似乎我们没有使用FPO。因此不应该存在FPO问题。 - Zipper
vs2005运行时使用fpo,您可能依赖的其他第三方也可能使用fpo。 - deemok
1个回答

3

在32位Windows系统中,系统使用EBP链来获取堆栈跟踪。您需要禁用FPO优化(/Oy-)。在64位Windows上,即使进行了优化,您也将获得良好的堆栈跟踪。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接