为什么没有使用WinDbg!heap -a -p和.Net NT服务的堆栈跟踪?

时间:2016-02-03 18:33:26

标签: .net debugging windbg

我有一个用.Net 4.5编写的Windows NT服务,带有非托管内存泄漏。

我相信我已经找到了泄漏的分配,但我没有得到任何堆栈跟踪。这是我所看到的:     0:022> !heap -s

******************************************************************
                                          NT HEAP STATS BELOW
******************************************************************
LFH Key                   : 0x057e4cff15073499
Termination on corruption : ENABLED
      Heap     Flags   Reserv  Commit  Virt   Free  List   UCR
                        (k)     (k)    (k)     (k) length
------------------------------------------------------------------
000000d80a200000 00000002    8376   7964   8176    564   236     4
000000d80a070000 00008000      64      4     64      2     1     1
000000d80a470000 00001002     260     64     60      8     7     1
000000d80a420000 00001002    1280    104   1080     15    10     2
000000d80a870000 00001002      60      8     60      2     1     1
000000d80a940000 00041002      60      8     60      5     1     1
000000d823320000 00041002      60     16     60      5     1     1
000000d8238f0000 00001002    7416   3160   7216     52    54     4
000000d8241f0000 00001002     260     64     60      7     5     1
000000d825110000 00001002      60      8     60      5     1     1
000000d825280000 00001002      60     12     60      3     2     1
000000d824e60000 00001002      60      8     60      5     1     1
000000d825840000 00001002     260     44     60      9     7     1
------------------------------------------------------------------

接下来,000000d8238f0000堆看起来很可疑:

0:022> !heap -stat -h 000000d8238f0000
heap @ 000000d8238f0000
group-by: TOTSIZE max-display: 20
size     #blocks     total     ( %) (percent of total busy bytes)
370 60f - 14d390  (58.11)
50 59e - 1c160  (4.90)
21a 46 - 931c  (1.60)
87c5 1 - 87c5  (1.48)
200 32 - 6400  (1.09)
298 26 - 6290  (1.07)
219 2c - 5c4c  (1.01)
278 22 - 53f0  (0.91)
1b7 30 - 5250  (0.90)
1e3 29 - 4d5b  (0.84)
1cd 28 - 4808  (0.79)
279 1b - 42c3  (0.73)
26a 1b - 412e  (0.71)
25b 1b - 3f99  (0.69)
1e9 21 - 3f09  (0.69)
344 13 - 3e0c  (0.68)
2e2 14 - 39a8  (0.63)
2b6 15 - 38ee  (0.62)
216 1b - 3852  (0.61)
213 1b - 3801  (0.61)

接下来分配大小为370:

 0:022> !heap -flt s 370
_HEAP @ d80a200000
          HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
    000000d8237c96a0 0038 0000  [00]   000000d8237c96b0    00370 - (free)
    000000d8237c9a20 0038 0038  [00]   000000d8237c9a30    00370 - (free)
    000000d8237c9da0 0038 0038  [00]   000000d8237c9db0    00370 - (free)
    000000d8237ca120 0038 0038  [00]   000000d8237ca130    00370 - (free)
_HEAP @ d80a070000
_HEAP @ d80a470000
_HEAP @ d80a420000
_HEAP @ d80a870000
_HEAP @ d80a940000
_HEAP @ d823320000
_HEAP @ d8238f0000
    000000d8238f8a00 0038 0038  [00]   000000d8238f8a10    00370 - (busy)
    000000d8238f8f30 0038 0038  [00]   000000d8238f8f40    00370 - (busy)
    000000d8238fbc00 0038 0038  [00]   000000d8238fbc10    00370 - (busy)

最后是分配的堆栈跟踪:

0:022> !heap -p -a 000000d8237c96b0
address 000000d8237c96b0 found in
_HEAP @ d80a200000
          HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
    000000d8237c96a0 0038 0000  [00]   000000d8237c96b0    00370 - (free)

有没有人知道为什么没有堆栈跟踪?我已经尝试了几个分配,没有显示堆栈。完整转储和实时调试的行为相同。

此外,加载和未加载SOS的结果相同。

1 个答案:

答案 0 :(得分:1)

WinDbg帮助说

  

-p指定正在请求页堆信息

     

-a [...]只要可用,就会包含堆栈跟踪。 [...]

所以你正在使用正确的选项。但是,需要考虑“只要可用”这一点。

要获取这些堆栈,请使用gflags并启用“创建用户模式堆栈跟踪数据库”并为其定义大小。 50 MB是完全正常的,因为它只会记录地址并稍后解析符号名称(因此它不会存储包含所有方法名称的字符串)。

GFlags enable stack trace database

SOS适用于.NET,在非托管泄漏的情况下无用。