kd> dx ((x, y) => (x + y))("Hello", "World")
((x, y) => (x + y))("Hello", "World") : HelloWorld
支持的 LINQ 语法 - 查询方法
dx 定义为可 (的对象是本机数组、已编写 NatVis(描述为容器)或调试器扩展对象) 具有一系列 LINQ (或 LINQ 等效的) 方法。 下面介绍了这些查询方法。 查询方法的参数签名在所有查询方法之后列出。
.其中 ( PredicateMethod ) : 返回一个新的 对象集合,其中包含谓词方法返回 true 的输入集合中每个对象。
.平展 ( [KeyProjectorMethod] ) :采用容器的输入容器 (树) 并平展到具有树中每个元素的单个容器中。 如果提供了可选的密钥投影仪方法,则树被视为密钥容器,这些密钥本身是容器,这些密钥由对投影方法的调用确定。
.选择 ( KeyProjectorMethod ) :返回对象的新集合,其中包含对输入集合中每个对象调用投影仪方法的结果。
.GroupBy ( KeyProjectorMethod, [KeyComparatorMethod] ) :通过分组输入集合中与调用密钥投影仪方法确定相同的键的所有对象,返回集合的新集合。 提供可选的比较器方法。
联接 (InnerCollection、外部 键选择器方法、内部键选择器方法、结果选择器方法 [ComparatorMethod]) :基于键选择器函数联接两个序列并提取值对。 还可以指定可选的比较器方法。
Intersect (InnerCollection, [ComparatorMethod]) : 返回集交集,这意味着出现在两个集合中每个集合中的元素。 还可以指定可选的比较器方法。
Union (InnerCollection, [ComparatorMethod]) :返回集联合,这意味着出现在两个集合之一中的唯一元素。 还可以指定可选的比较器方法。
数据集方法
包含 (对象 [ComparatorMethod]) :确定序列是否包含指定的元素。 提供可选的比较器方法,每次将元素与序列中的条目进行比较时,都将调用该方法。
Distinct ([ComparatorMethod]) :从集合中删除重复值。 每次必须比较集合中的对象时,都可以提供一个可选的比较器方法来调用该方法。
除了 (InnerCollection,[ComparatorMethod]) :返回集差异,这意味着一个集合的元素不会出现在第二个集合中。 可指定可选的比较器方法。
Concat (InnerCollection) :连接两个序列以形成一个序列。
.OrderBy ( KeyProjectorMethod, [KeyComparatorMethod] ) :根据对输入集合中每个对象调用键投影方法提供的键,按升序对集合进行排序。 提供可选的比较器方法。
.OrderByDescending ( KeyProjectorMethod, [KeyComparatorMethod] ) :根据对输入集合中每个对象调用键投影方法提供的键,按降序对集合进行排序。 提供可选的比较器方法。
Count () :返回集合中的元素数的方法。
Sum ([ProjectionMethod]) :计算集合中值的总和。 可以选择指定一种投影仪方法,在求和之前转换元素。
跳过 (计数) :将元素跳过至序列中的指定位置。
SkipWhile (PredicateMethod) :基于谓词函数跳过元素,直到元素不满足条件。
Take 方法
采用 (计数) :将元素取至序列中的指定位置。
TakeWhile (PredicateMethod) :基于谓词函数采用元素,直到元素不满足条件。
SequenceEqual (InnerCollection, [ComparatorMethod]) :通过成对比较元素确定两个序列是否相等。 可指定可选的比较器。
错误处理方法
AllNonError (PredicateMethod) :返回集合的所有非错误元素是否满足给定条件。
FirstNonError ([PredicateMethod]) :返回集合的第一个元素,该元素不是错误。
LastNonError ([PredicateMethod]) :返回集合中不是错误的最后一个元素。
.所有 ( PredicateMethod ) :返回对输入集合中每个元素调用指定谓词方法的结果是否为 true。
.任何 ( PredicateMethod ) :返回对输入集合中任何元素调用指定谓词方法的结果是否为 true。
.第 ( [PredicateMethod] ) : 返回集合中的第一个元素。 如果传递了可选谓词,则 返回集合中对谓词的调用返回 true 的第一个元素。
.最后 ( [PredicateMethod] ) : 返回集合中的最后一个元素。 如果传递了可选谓词,则 返回集合中对谓词的调用返回 true 的最后一个元素。
Min ([KeyProjectorMethod]) :返回集合的最小元素。 可指定可选的投影仪方法,在将每个方法与其他方法进行比较之前进行投影。
Max ([KeyProjectorMethod]) :返回集合的最大元素。 可指定可选的投影仪方法,在将每个方法与其他方法进行比较之前进行投影。
单 ([PredicateMethod]) :返回列表中唯一的元素 (如果集合包含多个元素,则返回) 。 如果指定了谓词,则 返回满足该谓词的单个元素 (如果多个元素满足该谓词,则函数将返回错误) 。
自变量的签名
所有字符串对象都将以下方法预测到它们中,以便它们可供使用:
查询相关方法 & 属性
.包含 ( OtherString ) :返回一个布尔值,该值指示输入字符串是否包含 OtherString。
.EndsWith ( OtherString ) :返回一个布尔值,该值指示输入字符串是否以 OtherString 结尾。
Length:返回字符串长度的属性。
.StartsWith ( OtherString ) :返回一个布尔值,该值指示输入字符串是否以 OtherString 开头。
.StartPos ( [Length] 的 子字符串) :返回从给定起始位置开始的输入字符串中的子字符串。 如果提供了可选长度,则返回的子字符串的长度为指定长度;否则 , 将转到字符串的末尾。
.IndexOf ( OtherString ) :返回输入字符串中 OtherString 第一个匹配项的索引。
.LastIndexOf ( OtherString ) :返回输入字符串中 OtherString 的最后一个匹配项的索引。
格式设置方法
.PadLeft ( TotalWidth ) :在字符串左侧添加空格,使字符串的总长度调整为指定宽度。
.PadRight ( TotalWidth ) :在字符串右侧添加空格,使字符串的总长度调整为指定宽度。
.删除 ( StartPos,[Length] ) :从输入字符串中删除字符,从开始位置开始指定位置。 如果提供了可选的 length 参数,将删除该字符数;否则 – 将删除字符串末尾的所有字符。
.将 ( SearchString,ReplaceString ) :将输入字符串中每次出现的 SearchString 替换为指定的 ReplaceString。
字符串对象投影
除了直接投射到字符串对象上的方法外,本身具有字符串转换的任何对象还具有以下方法,使其可供使用:
.ToDisplayString ( ) :返回 对象的字符串转换。 这是字符串转换,将在对象的 dx 调用中显示。 可以提供格式设置说明器来设置 ToDisplayString 的输出格式。 有关详细信息,请参阅调试器中的 C++ Visual Studio说明符
以下示例演示了格式说明符的使用。
kd> dx (10).ToDisplayString("d")
(10).ToDisplayString("d") : 10
kd> dx (10).ToDisplayString("x")
(10).ToDisplayString("x") : 0xa
kd> dx (10).ToDisplayString("o")
(10).ToDisplayString("o") : 012
kd> dx (10).ToDisplayString("b")
(10).ToDisplayString("b") : 0y1010
kd> dx ("some wchar string here").ToDisplayString("su")
("some wchar string here").ToDisplayString("su") : "some wchar string here"
kd> dx ("some wchar string here").ToDisplayString("sub")
("some wchar string here").ToDisplayString("sub") : some wchar string here
调试即插即用示例
本部分说明如何使用与 LINQ 查询一起使用的内置调试器对象来调试即插即用对象。
查看所有设备
使用 设备 树上的"平展"查看所有设备。
1: kd> dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children)
@$cursession.Devices.DeviceTree.Flatten(n => n.Children)
[0x0] : HTREE\ROOT\0
[0x1] : ROOT\volmgr\0000 (volmgr)
[0x2] : ROOT\BasicDisplay\0000 (BasicDisplay)
[0x3] : ROOT\CompositeBus\0000 (CompositeBus)
[0x4] : ROOT\vdrvroot\0000 (vdrvroot)
[0x5] : ROOT\spaceport\0000 (spaceport)
[0x6] : ROOT\KDNIC\0000 (kdnic)
[0x7] : ROOT\UMBUS\0000 (umbus)
[0x8] : ROOT\ACPI_HAL\0000
与其他 dx 命令一样,可以在命令执行后选择并按住 (或右键单击) 命令,然后选择"显示为网格"或向命令添加"-g",获取结果的网格视图。
# 0: kd> dx -g @$cursession.Devices.DeviceTree.Flatten(n => n.Children)
=====================================================================================================================================================================================================================================================================================================================
# = = (+) DeviceNodeObject = InstancePath = ServiceName = (+) PhysicalDeviceObject = State = (+) Resoures = (+) Children =
=====================================================================================================================================================================================================================================================================================================================
= [0x0] : HTREE\ROOT\0 - {...} - HTREE\ROOT\0 - - 0xffffb6075614be40 : Device for "\Driver\PnpManager" - DeviceNodeStarted (776) - {...} - [object Object] =
= [0x1] : ROOT\volmgr\0000 (volmgr) - {...} - ROOT\volmgr\0000 - volmgr - 0xffffb607561fbe40 : Device for "\Driver\PnpManager" - DeviceNodeStarted (776) - {...} - [object Object] =
= [0x2] : ROOT\BasicDisplay\0000 (BasicDisplay) - {...} - ROOT\BasicDisplay\0000 - BasicDisplay - 0xffffb607560739b0 : Device for "\Driver\PnpManager" - DeviceNodeStarted (776) - {...} - [object Object] =
= [0x3] : ROOT\CompositeBus\0000 (CompositeBus) - {...} - ROOT\CompositeBus\0000 - CompositeBus - 0xffffb607561f9060 : Device for "\Driver\PnpManager" - DeviceNodeStarted (776) - {...} - [object Object] =
按状态查看设备
使用 Where 指定特定设备状态。
dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.State <operator> <state number>)
例如,若要查看状态为 DeviceNodeStarted 的设备,请使用此命令。
1: kd> dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.State == 776)
@$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.State == 776)
[0x0] : HTREE\ROOT\0
[0x1] : ROOT\volmgr\0000 (volmgr)
[0x2] : ROOT\BasicDisplay\0000 (BasicDisplay)
[0x3] : ROOT\CompositeBus\0000 (CompositeBus)
[0x4] : ROOT\vdrvroot\0000 (vdrvroot)
查看未启动的设备
使用此命令查看未在 DeviceNodeStarted 状态的设备。
1: kd> dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.State != 776)
@$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.State != 776)
[0x0] : ACPI\PNP0C01\1
[0x1] : ACPI\PNP0000\4&215d0f95&0
[0x2] : ACPI\PNP0200\4&215d0f95&0
[0x3] : ACPI\PNP0100\4&215d0f95&0
[0x4] : ACPI\PNP0800\4&215d0f95&0
[0x5] : ACPI\PNP0C04\4&215d0f95&0
[0x6] : ACPI\PNP0700\4&215d0f95&0 (fdc)
[0x7] : ACPI\PNP0C02\1
[0x8] : ACPI\PNP0C02\2
按问题代码查看设备
使用 DeviceNodeObject.Problem 对象查看具有特定问题代码的设备。
dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.DeviceNodeObject.Problem <operator> <problemCode>)
例如,若要查看具有非零问题代码的设备,请使用此命令。 这提供与"!devnode 0 21"类似的信息。
1: kd> dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.DeviceNodeObject.Problem != 0)
@$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.DeviceNodeObject.Problem != 0)
[0x0] : HTREE\ROOT\0
[0x1] : ACPI\PNP0700\4&215d0f95&0 (fdc)
查看所有设备,无问题
使用此命令查看所有设备,而没有任何问题
1: kd> dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.DeviceNodeObject.Problem == 0)
@$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.DeviceNodeObject.Problem == 0)
[0x0] : ROOT\volmgr\0000 (volmgr)
[0x1] : ROOT\BasicDisplay\0000 (BasicDisplay)
[0x2] : ROOT\CompositeBus\0000 (CompositeBus)
[0x3] : ROOT\vdrvroot\0000 (vdrvroot)
查看具有特定问题的所有设备
使用此命令可以查看问题状态为 0x16。
1: kd> dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.DeviceNodeObject.Problem == 0x16)
@$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.DeviceNodeObject.Problem == 0x16)
[0x0] : HTREE\ROOT\0
[0x1] : ACPI\PNP0700\4&215d0f95&0 (fdc)
按功能驱动程序查看设备
使用此命令按函数驱动程序查看设备。
dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.ServiceName <operator> <service name>)
若要使用特定函数驱动程序(如 atapi)查看设备,请使用此命令。
1: kd> dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.ServiceName == "atapi")
@$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.ServiceName == "atapi")
[0x0] : PCIIDE\IDEChannel\4&10bf2f88&0&0 (atapi)
[0x1] : PCIIDE\IDEChannel\4&10bf2f88&0&1 (atapi)
查看启动启动驱动程序列表
若要查看作为启动启动驱动程序加载的 winload 的列表,你需要处于一个上下文中,你有权访问 LoaderBlock,并且 LoaderBlock 还足够早。 例如,在 nt!IopInitializeBootDrivers。 可以将断点设置为在此上下文中停止。
1: kd> g
Breakpoint 0 hit
nt!IopInitializeBootDrivers:
8225c634 8bff mov edi,edi
查询半结构化 用于显示启动驱动程序结构的 命令。
1: kd> ?? LoaderBlock->BootDriverListHead
struct _LIST_ENTRY
[ 0x808c9960 - 0x808c8728 ]
+0x000 Flink : 0x808c9960 _LIST_ENTRY [ 0x808c93e8 - 0x808a2e18 ]
+0x004 Blink : 0x808c8728 _LIST_ENTRY [ 0x808a2e18 - 0x808c8de0 ]
使用 Debugger.Utility.Collections.FromListEntry 调试器对象查看数据,使用 nt!_LIST_ENTRY 的起始地址。
1: kd> dx Debugger.Utility.Collections.FromListEntry(*(nt!_LIST_ENTRY *)0x808c9960, "nt!_BOOT_DRIVER_LIST_ENTRY", "Link")
Debugger.Utility.Collections.FromListEntry(*(nt!_LIST_ENTRY *)0x808c9960, "nt!_BOOT_DRIVER_LIST_ENTRY", "Link")
[0x0] [Type: _BOOT_DRIVER_LIST_ENTRY]
[0x1] [Type: _BOOT_DRIVER_LIST_ENTRY]
[0x2] [Type: _BOOT_DRIVER_LIST_ENTRY]
[0x3] [Type: _BOOT_DRIVER_LIST_ENTRY]
[0x4] [Type: _BOOT_DRIVER_LIST_ENTRY]
[0x5] [Type: _BOOT_DRIVER_LIST_ENTRY]
使用 -g 选项创建数据的网格视图。
dx -r1 -g Debugger.Utility.Collections.FromListEntry(*(nt!_LIST_ENTRY *)0x808c9960, "nt!_BOOT_DRIVER_LIST_ENTRY", "Link")
按功能查看设备
使用 DeviceNodeObject.CapabilityFlags 对象按功能查看设备。
dx -r1 @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => (n.DeviceNodeObject.CapabilityFlags & <flag>) != 0)
下表总结了 dx 命令与常用设备功能标志的使用。
dbgcmd 0:kd> dx -r1 @$cursession。Devices.DeviceTree.Flatten (n => n.Children) 。其中 (n => (n.DeviceNodeObject.CapabilityFlags & 0x10) != 0) @$cursession。Devices.DeviceTree.Flatten (n => n.Children) 。其中 (n => (n.DeviceNodeObject.CapabilityFlags & 0x10) != 0)
[0x0] : SWD\PRINTENUM{2F8DBBB6-F246-4D84-BB1D-AA8761353885} [0x1] : SWD\PRINTENUM{F210BC77-55A1-4FCA-AA80-013E2B4083 78} [0x2] :SWD\PRINTENUM{07940A8E-11F4-46C3-B714-7FF9B87738F8} [0x3] : DISPLAY\Default_Monitor\61a097cd80UID5527112&&& (monitor)
UniqueID
dbgcmd 0:kd> dx -r1 @$cursession。Devices.DeviceTree.Flatten (n => n.Children) 。其中 (n => (n.DeviceNodeObject.CapabilityFlags & 0x40) != 0) @$cursession。Devices.DeviceTree.Flatten (n => n.Children) 。其中 (n => (n.DeviceNodeObject.CapabilityFlags & 0x40) != 0)
[0x0] : HTREE\ROOT\0 [0x1] : ROOT\volmgr\0000 (volmgr) [0x2] : ROOT\spaceport\0000 (spaceport) ...
SilentInstall
dbgcmd 0:kd> dx -r1 @$cursession。Devices.DeviceTree.Flatten (n => n.Children) 。其中 (n => (n.DeviceNodeObject.CapabilityFlags & 0x80) != 0) @$cursession。Devices.DeviceTree.Flatten (n => n.Children) 。其中 (n => (n.DeviceNodeObject.CapabilityFlags & 0x80) != 0)
[0x0] : HTREE\ROOT\0 [0x1] : ROOT\volmgr\0000 (volmgr) [0x2] : ROOT\spaceport\0000 (spaceport) ...
RawDeviceOk
dbgcmd 0:kd> dx -r1 @$cursession。Devices.DeviceTree.Flatten (n => n.Children) 。其中 (n => (n.DeviceNodeObject.CapabilityFlags & 0x100) != 0) @$cursession。Devices.DeviceTree.Flatten (n => n.Children) 。其中 (n => (n.DeviceNodeObject.CapabilityFlags & 0x100) != 0)
[0x0] : HTREE\ROOT\0 [0x1] : SWD\MMDEVAPI\MicrosoftGSWavetableSynth [0x2] : SWD\IP_TUNNEL_VBUS\IP_TUNNEL_DEVICE_ROOT ...
SurpriseRemovalOK
dbgcmd 0:kd> dx -r1 @$cursession。Devices.DeviceTree.Flatten (n => n.Children) 。其中 (n => (n.DeviceNodeObject.CapabilityFlags & 0x200) != 0) @$cursession。Devices.DeviceTree.Flatten (n => n.Children) 。其中 (n => (n.DeviceNodeObject.CapabilityFlags & 0x200) != 0)
[0x0] : SWD\MMDEVAPI\MicrosoftGSWavetableSynth [0x1] : SWD\IP_TUNNEL_VBUS\IP_TUNNEL_DEVICE_ROOT [0x2] : SWD\PRINTENUM\PrintQueues ...