Windbg 如何转储的输出!当堆包含数百万个对象时,是否将堆转储到文件中?

Windbg 如何转储的输出!当堆包含数百万个对象时,是否将堆转储到文件中?,windbg,Windbg,请注意: 0:000> !dumpheap -stat Statistics: MT Count TotalSize Class Name 000007fefa9c8c58 1 24 System.ServiceProcess.Res 000007fef99d3de8 1 24 System.Collections.Generic.GenericArraySortHelper`1[[

请注意:

0:000> !dumpheap -stat
Statistics:
              MT    Count    TotalSize Class Name
000007fefa9c8c58        1           24 System.ServiceProcess.Res
000007fef99d3de8        1           24 System.Collections.Generic.GenericArraySortHelper`1[[System.DateTime, mscorlib]]
000007fef99cf8e8        1           24 System.Collections.Generic.GenericComparer`1[[System.Decimal, mscorlib]]
...
000007fef8f02090    47295    141585288 System.Char[]
000007fe9b1cbe20  1064155    229857480 Xyz.DataServices.Platform.BalanceTransactionForAccrualByOrg
000007fef8f06888    21401    238104833 System.Byte[]
000007fe9cd2efb8  1211503    358604888 Xyz.DataServices.Platform.AEBalanceTransaction
0000000000386b30 11759620   1701611244      Free
000007fef8e94918   777049   2352540408 System.Object[]
000007fe9c4370e8 10571587   2621753576 Xyz.DB.DL.HREEmployeeManager
000007fef8f00e08 131198125   1859306044 System.String
Total 163792779 objects
Fragmented blocks larger than 0.5 MB:
            Addr     Size      Followed by
...
这意味着堆上有上千万个对象。我想把有关他们的信息转储到一个文件中

所以告诉我方法,但是当我们谈论数千万行时,这是我们能得到的最好的方法吗


我想知道是否有一个编程API,我可以根据它直接编程从转储中提取数据,而不是通过WinDBG用户界面。或者可能有一个插件已经实现了…

在一天结束时,我编写了一个powershell脚本,使用CDB运行单个调试器命令。然后将输出保存到文件中

这是:

param(
  [Parameter(Mandatory=$true, Position = 0)][ValidateScript({Test-Path $_ })]
  $dump,
  [Parameter(ParameterSetName='cmd', Mandatory=$true, Position = 1)][ValidateNotNullOrEmpty()]
  $command,
  [Parameter(ParameterSetName='script', Mandatory=$true)][ValidateNotNullOrEmpty()]
  $scriptFile,
  [Parameter(ParameterSetName='init', Mandatory=$true)][ValidateNotNullOrEmpty()][switch]
  $init,
  [Parameter()]
  $imagePath,
  [Parameter()]
  $sosexPath = "e:\utils\sosex\64\sosex.dll",
  [Parameter()][switch]
  $ScanForImages,
  [Parameter()][switch]
  $NoSymbolServer,
  [Parameter()][switch]
  $NoExit
)
$dump = (dir $dump).FullName

$cdb = "C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x64\cdb.exe"
$InternalScriptFile = [io.path]::GetTempFileName()
$log = [io.path]::GetTempFileName()

if ($ScanForImages)
{
  $ImgScan = ".imgscan /l"
}

Set-Content $InternalScriptFile @"
.logopen `"${log}.init`"
.load $sosexPath
"@

if ($init)
{
  $CDBOutputDevice = "Out-Default"
  Add-Content $InternalScriptFile @"
.logclose
!bhi
"@
}
elseif ($command)
{
  $CDBOutputDevice = "Out-Null"
  Add-Content $InternalScriptFile @"
!lhi
$ImgScan
.logclose
.logopen `"${log}`"
$command
.logclose
"@
}
else
{
  $CDBOutputDevice = "Out-Null"
  Add-Content $InternalScriptFile @"
!lhi
$ImgScan
.logclose
.logopen `"${log}`"
"@
  Get-Content $scriptFile | Out-File -FilePath $InternalScriptFile -Encoding ASCII -Append
  Add-Content $InternalScriptFile @"
.logclose
"@
}

if ($NoExit)
{
  $CDBOutputDevice = "Out-Default"
}
else
{
  Add-Content $InternalScriptFile @"
q
"@
}

if ($NoSymbolServer)
{
  $symbols = "e:\Symbols"
}
else
{
  $symbols = "cache*e:\Symbols;srv*http://localhost:33417;srv*http://msdl.microsoft.com/download/symbols"
}
if (Test-Path $imagePath -PathType Container)
{
  $symbols = "$imagePath;$symbols"
}

&$cdb -cf $InternalScriptFile -z $dump -y $symbols | &$CDBOutputDevice
if (!$init -and !$NoExit)
{
  cat $log
}

不理想-我愿意改进。但它是有效的。

相关:,因为我尝试为您实现它,非常感谢。我不知道为什么会有人投反对票。我也不知道有时会有人投反对票。我真的尽力使它尽可能的最小化和完整。也许有人认为我应该附加转储?@mark我想你可以在github的coreclr iirc上找到一些旧的src for sos(实现转储堆的wdbgext样式代码),如果你找不到,我看看我是否缓存了URL这是很多管理器。第一个明显的方法是不要在创建小型转储之前等待太久。第二个明显的方法是得出结论,Windbg不是解决漏洞和使用体面的.NET内存分析器的好方法。