デバッガー オブジェクトでの LINQ の使用

LINQ 構文をデバッガー オブジェクトと一緒に使用して、データを検索および操作できます。 dx コマンドで LINQ 構文を使用すると、デバッガー コマンドを使用する場合と比較して、より一貫性のあるエクスペリエンスが得されます。 表示するデバッガー オブジェクトに関係なく、出力とオプションは一貫しています。 LINQ クエリを使用すると、"最も多くのスレッドを実行している上位 5 つのプロセスとは何か" などの質問をすることができます。

デバッガー オブジェクトは、"Debugger" をルートとする名前空間に投影されます。 プロセス、モジュール、スレッド、スタック、スタック フレーム、ローカル変数はすべて、LINQ クエリで使用できます。

LINQ は概念的には、データベース構造化照会言語 (SQL) に似ています。 複数の LINQ メソッドを使用して、デバッグ データの検索、フィルター処理、解析を行います。 LINQ C# メソッド構文が使用されます。 LINQ と LINQ C# 構文の詳細については、「C# での LINQ はじめにの使用」を参照してください。

デバッガーのサポートで使用される LINQ では、"クエリ構文" ではなく、LINQ の "メソッド構文" が使用されます。 違いの詳細については、「 LINQ (言語統合クエリ)」を参照してください

次のような LINQ コマンドは、デバッガー オブジェクトと一緒に使用できます。 すべての。任意、。カウント。まずは。平ら。Groupby。前の。Orderby。OrderByDescending、。と を選択します。どこ。 これらのメソッドは、(可能な限り) C# LINQ メソッド の形式に従います。

ネイティブ デバッガー オブジェクト

ネイティブ デバッガー オブジェクトは、デバッガー環境のさまざまな構成要素と動作を表します。 デバッガー オブジェクトの例を次に示します。

  • Session
  • スレッド/スレッド
  • プロセス/プロセス
  • スタック フレーム/スタック フレーム
  • ローカル変数
  • モジュール/モジュール
  • ユーティリティ
  • State
  • 設定

NatVis を使用してデバッガー オブジェクトを操作することもできます。 詳細については、「 NatVis のネイティブ デバッガー オブジェクト」を参照してください。 JavaScript でデバッガー オブジェクトを使用する方法については、「 JavaScript 拡張機能でのネイティブ デバッガー オブジェクト」を参照してください。 C++ とドライバー オブジェクトの操作の詳細については、「 デバッガー データ モデル C++ の概要」を参照してください

Dx コマンド

ここで示す例では、dx コマンドを使用します。dx コマンドの操作の詳細については、「dx (デバッガー オブジェクト モデル式の表示)」 を参照してください

LINQ クエリの開発

LINQ デバッガー オブジェクト クエリを開発する 1 つの方法は、表示される DML リンクを使用してデータ モデルを探索し、最初にクエリで使用されるデバッガー オブジェクトを見つける方法です。

この例では、カーネル デバッグ セッション内のプロセスの一覧と、それらの各プロセスのスレッド数を表示します。

探索を開始するには、dx コマンドを使用して、トップ レベルのデバッガー オブジェクトを表示します。

0: kd> dx Debugger
Debugger
    Sessions
    Settings
    State
    Utility

トップ レベルのトピックを選択した後、セッションが最も興味深いと判断されたので、DML リンクを選択してプロセスが含まれているかどうかを確認 します

0: kd> dx -r1 Debugger.Sessions[0]
Debugger.Sessions[0]                 : Remote KD: KdSrv:Server=@{<Local>},Trans=@{NET:Port=50005,Key=MyKey}
    Processes
    Id               : 0
    Attributes

次に、さらに下を選択して特定のプロセスを確認すると、そのプロセスに関連付けられている スレッド が使用可能であるのが分かっています。 プロセスの 1 つで [ スレッド] を選択すると、そのプロセスに関連付けられているすべてのスレッドが使用可能になります。

0: kd> dx -r1 Debugger.Sessions[0].Processes[1428].Threads
Debugger.Sessions[0].Processes[1428].Threads
    [0x598]          : <Unable to get stack trace> [Switch To]
    [0x1220]         : <Unable to get stack trace> [Switch To]
    [0x6f8]          : nt!KiSwapContext+0x76 (fffff806`4466a186)  [Switch To]
    [0x128c]         : <Unable to get stack trace> [Switch To]
    [0x27e4]         : nt!KiSwapContext+0x76 (fffff806`4466a186)  [Switch To] 

これで、プロセスに関連付けられているスレッドの数を表示するために必要なデータがデバッガー オブジェクト モデルで使用できるとわかっています。

LINQ クエリを少し短くするには、このトピックで後述するシステム定義変数を使用して、現在のセッションに関連付けられているプロセスを表示します。

0: kd> dx @$cursession.Processes
@$cursession.Processes                
    [0x0]            : Idle [Switch To]
    [0x4]            : System [Switch To]
    [0x90]           : Registry [Switch To]
...

次に、select ステートメントを追加します。 最初に、[名前] フィールドを指定します。

0: kd> dx @$cursession.Processes.Select(p => p.Name)
@$cursession.Processes.Select(p => p.Name)                
    [0x0]            : Idle
    [0x4]            : System
    [0x90]           : Registry
...

このシナリオでは、スレッドの数も必要です。 フィールドは 2 つあるため、「ユーザー定義変数」で後述する C# の匿名型構文と同様に、new を使用して匿名型を作成します

dx @$cursession.Processes.Select(p => new {Name = p.Name, Threads = p.Threads})

このコマンドを使用すると、'dx' は実際には名前を出力しなくなったので、-r2 (2 つのレベルを再帰) して名前とスレッドを表示します。

dx -r2 @$cursession.Processes.Select(p => new {Name = p.Name, Threads = p.Threads})
@$cursession.Processes.Select(p => new {Name = p.Name, Threads = p.Threads})                
    [0x0]           
        Name             : Idle
        Threads         
    [0x4]           
        Name             : System
        Threads         
    [0x90]          
        Name             : Registry
        Threads       

この時点で、プロセスの名前とスレッドの一覧が表示されます。 ThreadCount を表示するには、 を使用します 。Count() メソッド。

0: kd> dx -r2 @$cursession.Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count()})
@$cursession.Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count()})                
    [0x0]           
        Name             : Idle
        ThreadCount      : 0x4
    [0x4]           
        Name             : System
        ThreadCount      : 0xe7
    [0x90]          
        Name             : Registry
        ThreadCount      : 0x4
...

スレッド数が多いプロセスを確認するには、 OrderByDescending を使用してスレッド数で一覧を順序付けします。

0: kd> dx -r2 @$cursession.Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count()}).OrderByDescending(p => p.ThreadCount)
@$cursession.Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count()}).OrderByDescending(p => p.ThreadCount)                
    [0x4]           
        Name             : System
        ThreadCount      : 0xe7
    [0xa38]         
        Name             : svchost.exe
        ThreadCount      : 0x45
    [0x884]         
        Name             : MemCompression
        ThreadCount      : 0x3e

書式設定されたグリッドでレンダリングするには、'-r2' を '-g' に変更します。 グリッド オプションによって列が適切に表示されるので、再帰のレベルを指定する必要はありません。 最後に、10 進値を出力する ',d' 書式指定子を追加します。

0: kd> dx -g @$cursession.Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count()}).OrderByDescending(p => p.ThreadCount),d
===========================================================================================
=            = Name                                                         = ThreadCount =
===========================================================================================
= [4]        - System                                                       - 231         =
= [2616]     - svchost.exe                                                  - 69          =
= [2180]     - MemCompression                                               - 62          =
= [968]      - explorer.exe                                                 - 61          =

デバッガー オブジェクトの例

この例は、最も多くのスレッドを実行している上位 5 つのプロセスを示しています。

0: kd> dx -r2 Debugger.Sessions.First().Processes.Select(p => new { Name = p.Name, ThreadCount = p.Threads.Count() }).OrderByDescending(p => p.ThreadCount),5
Debugger.Sessions.First().Processes.Select(p => new { Name = p.Name, ThreadCount = p.Threads.Count() }).OrderByDescending(p => p.ThreadCount),5 

: 
    [0x4]            : 
        Name             : <Unknown Image>
        ThreadCount      : 0x73
    [0x708]          : 
        Name             : explorer.exe
        ThreadCount      : 0x2d
    [0x37c]          : 
        Name             : svchost.exe
        ThreadCount      : 0x2c
    [0x6b0]          : 
        Name             : MsMpEng.exe
        ThreadCount      : 0x22
    [0x57c]          : 
        Name             : svchost.exe
        ThreadCount      : 0x15
    [...]       

この例は、プラグ アンド プレイ デバイス ツリー内のデバイスを、物理デバイス オブジェクトのドライバーの名前でグループ化して示しています。 出力の一部が表示されない。

kd> dx -r2 Debugger.Sessions.First().Devices.DeviceTree.Flatten(n => n.Children).GroupBy(n => n.PhysicalDeviceObject->Driver->DriverName.ToDisplayString())
Debugger.Sessions.First().Devices.DeviceTree.Flatten(n => n.Children).GroupBy(n => n.PhysicalDeviceObject->Driver->DriverName.ToDisplayString()) 

: 
    ["\"\\Driver\\PnpManager\""] : 
        [0x0]            : HTREE\ROOT\0
        [0x1]            : ROOT\volmgr\0000 (volmgr)
        [0x2]            : ROOT\BasicDisplay\0000 (BasicDisplay)
        [0x3]            : ROOT\CompositeBus\0000 (CompositeBus)
        [0x4]            : ROOT\vdrvroot\0000 (vdrvroot)
         ...  

Dx コマンド タブのオート コンプリート

コンテキスト TAB キーのオートコンプリートは LINQ クエリ メソッドを認識し、ラムダのパラメーターに対して機能します。

たとえば、次のテキストをデバッガーに入力 (またはコピーして貼り付け) します。 その後、Tab キーを数回押して、入力候補を切り替えます。

dx -r2 Debugger.Sessions.First().Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count() }).OrderByDescending(p => p.

まで Tab キーを押します。[名前] が表示されます。 終了かっこ ")" を追加し、Enter キーを押してコマンドを実行します。

kd> dx -r2 Debugger.Sessions.First().Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count() }).OrderByDescending(p => p.Name)
Debugger.Sessions.First().Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count() }).OrderByDescending(p => p.Name) : 
    [0x274]          : 
        Name             : winlogon.exe
        ThreadCount      : 0x4
    [0x204]          : 
        Name             : wininit.exe
        ThreadCount      : 0x2
    [0x6c4]          : 
        Name             : taskhostex.exe
        ThreadCount      : 0x8
         ...  

この例では、キー比較メソッドを使用した補完を示します。 キーが文字列である場合、置換では文字列メソッドが表示されます。

dx -r2 Debugger.Sessions.First().Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count() }).OrderByDescending(p => p.Name, (a, b) => a.

まで Tab キーを押します。長さ" が表示されます。 終了かっこ ")" を追加し、Enter キーを押してコマンドを実行します。

kd> dx -r2 Debugger.Sessions.First().Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count() }).OrderByDescending(p => p.Name, (a, b) => a.Length)
Debugger.Sessions.First().Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count() }).OrderByDescending(p => p.Name, (a, b) => a.Length) : 
    [0x544]          : 
        Name             : spoolsv.exe
        ThreadCount      : 0xc
    [0x4d4]          : 
        Name             : svchost.exe
        ThreadCount      : 0xa
    [0x438]          : 
        Name             : svchost.exe

ユーザー定義変数

ユーザー定義変数は、変数名の前に @$ を付け、定義できます。 ユーザー定義変数は、ラムダ、LINQ クエリの結果など、dx で利用できるすべての変数に割り当てることができます。

ユーザー変数の値は、次のように作成して設定できます。

kd> dx @$String1="Test String"

定義されたユーザー変数は、 Debugger.State.UserVariables または @$vars を 使用して表示できます

kd> dx Debugger.State.UserVariables
Debugger.State.UserVariables : 
    mySessionVar     : 
    String1          : Test String

を使用して変数を削除できます。削除。

kd> dx @$vars.Remove("String1")

この例では、Debugger.Sesssions を参照するユーザー変数を定義する方法を示します。

kd> dx @$mySessionVar = Debugger.Sessions

次に示すように、ユーザー定義変数を使用できます。

kd> dx -r2 @$mySessionVar 
@$mySessionVar   : 
    [0x0]            : Remote KD: KdSrv:Server=@{<Local>},Trans=@{COM:Port=\\.\com3,Baud=115200,Timeout=4000}
        Processes        : 
        Devices     

システム定義変数

次のシステム定義変数は、任意の LINQ dx クエリで使用できます。

  • @$cursession - 現在のセッション

  • @$curprocess - 現在のプロセス

  • @$curthread - 現在のスレッド

この例では、システム定義変数の使用を示します。

kd> dx @$curprocess.Threads.Count()
@$curprocess.Threads.Count() : 0x4
kd> dx -r1 @$curprocess.Threads
@$curprocess.Threads : 
    [0x4adc]         : 
    [0x1ee8]         : 
    [0x51c8]         : 
    [0x62d8]         : 
     ...

ユーザー定義変数 - 匿名型

この動的オブジェクトの作成は、C# 匿名型構文 (新しい { ... }) を使用して行われます。 匿名型の詳細については、「匿名型 (C# プログラミング ガイド)」を参照してください。 この例では、整数値と文字列値を持つ匿名型を作成します。

kd> dx -r1 new { MyInt = 42, MyString = "Hello World" }
new { MyInt = 42, MyString = "Hello World" } : 
    MyInt            : 42
    MyString         : Hello World

関数オブジェクト (ラムダ式)

データのクエリに使用されるメソッドの多くは、コレクション内のオブジェクト間でユーザー指定の関数を繰り返し実行する概念に基づいて行います。 デバッガーでデータを照会および操作する機能をサポートするために、dx コマンドは、同等の C# 構文を使用したラムダ式をサポートします。 ラムダ式は、 = 演算子の使用によって次のように> 定義されます。

(arguments) => (result)

DX での LINQ の使い方を確認するには、この簡単な例を使用して 5 と 7 を追加してみてください。

kd> dx ((x, y) => (x + y))(5, 7) 

dx コマンドはラムダ式をエコーバックし、12 の結果を表示します。

((x, y) => (x + y))(5, 7)  : 12

このラムダ式の例では、文字列 "Hello" と "World" が結合されています。

kd> dx ((x, y) => (x + y))("Hello", "World")
((x, y) => (x + y))("Hello", "World") : HelloWorld

サポートされている LINQ 構文 - クエリ メソッド

dx が"iterable" として定義するオブジェクト (ネイティブ配列、コンテナーとして記述された NatVis を持つ型、またはデバッガー拡張オブジェクト) には、一連の LINQ (または LINQ と同等の) メソッドが投影されます。 これらのクエリ メソッドについては、以下で説明します。 クエリ メソッドに対する引数のシグネチャは、すべてのクエリ メソッドの後に一覧表示されます。

メソッドのフィルター処理

.Where ( PredicateMethod ): 述語メソッドが true を返した入力コレクション内のすべてのオブジェクトを含む オブジェクトの新しいコレクションを返します。

プロジェクション メソッド

.Flatten ( [KeyProjectorMethod] ): コンテナーの入力コンテナー (ツリー) を取得し、ツリー内のすべての要素を含む 1 つのコンテナーにフラット化します。 オプションのキー プロジェクメソッドが指定されている場合、ツリーは自身がコンテナーであるキーのコンテナーと見なされ、それらのキーはプロジェクション メソッドの呼び出しによって決定されます。

.Select ( KeyProjectorMethod ): 入力コレクション内のすべてのオブジェクトでプロジェクター メソッドを呼び出した結果を含む オブジェクトの新しいコレクションを返します。

グループ化メソッド

.GroupBy ( KeyProjectorMethod, [KeyComparatorMethod] ): 入力コレクション内のすべてのオブジェクトを、キー の投影メソッドを呼び出すことによって決定されたキーを持つすべてのオブジェクトをグループ化することで、コレクションの新しいコレクションを返します。 省略可能な比較メソッドを指定できます。

Join (InnerCollection, Outer key selector method, Inner key selector method, Result selector method, [SelectorMethod]): キー セレクター関数に基づいて 2 つのシーケンスを結合し、値のペアを抽出します。 省略可能な比較メソッドを指定できます。

Intersect (InnerCollection, [IntersectMethod]):セットの交差部分を返します。これは、2 つのコレクションのそれぞれに出現する要素を意味します。 省略可能な比較メソッドを指定できます。

Union (InnerCollection, [Method]): セット共用体を返します。これは、2 つのコレクションのいずれかに出現する一意の要素を意味します。 省略可能な比較メソッドを指定できます。

データ セット メソッド

Contains (Object, [DetermineMethod]): シーケンスに指定された要素が含まれているかどうかを判断します。 要素がシーケンス内のエントリと比較されるたび呼び出される省略可能な比較メソッドを指定できます。

Distinct ([Method]): コレクションから重複する値を削除します。 コレクション内のオブジェクトを比較する必要がある場合は、省略可能な比較メソッドを指定して呼び出しを行います。

(InnerCollection, [Method]) を除く: 設定の違いを返します。これは、1 つのコレクションの要素が 2 番目のコレクションに表示されないことを意味します。 省略可能な比較メソッドを指定できます。

Concat (InnerCollection):2 つのシーケンスを連結して 1 つのシーケンスを形成します。

並べ替えメソッド

.OrderBy ( KeyProjectorMethod, [KeyComparatorMethod] ): 入力コレクション内のすべてのオブジェクトに対してキー プロジェクション メソッドを呼び出すことによって、指定されたキーに従ってコレクションを昇順に並べ替えます。 省略可能な比較メソッドを指定できます。

.OrderByDescending ( KeyProjectorMethod, [KeyComparatorMethod] ): 入力コレクション内のすべてのオブジェクトに対してキー プロジェクション メソッドを呼び出すことによって、指定されたキーに従ってコレクションを降順に並べ替える。 省略可能な比較メソッドを指定できます。

メソッドの集計

Count (): コレクション内の要素の数を返すメソッド。

Sum ([ProjectionMethod]):コレクション内の値の合計を計算します。 必要に応じて、合計が発生する前に要素を変換する投影メソッドを指定できます。

Skip メソッド

Skip (Count):シーケンス内の指定した位置まで要素をスキップします。

SkipWhile (PredicateMethod): 要素が条件を満たさないまで、述語関数に基づいて要素をスキップします。

メソッドの取り出し

Take (Count): シーケンス内の指定した位置まで要素を受け取ります。

TakeWhile (PredicateMethod): 要素が条件を満たさないまで、述語関数に基づいて要素を取得します。

比較メソッド

SequenceEqual (InnerCollection, [ComparMethod]): 2 つのシーケンスがペアの方法で要素を比較して等しいかどうかを判断します。 省略可能な比較子を指定できます。

エラー処理メソッド

AllNonError (PredicateMethod):コレクションのすべてのエラー以外の要素が特定の条件を満たすかどうかを返します。

FirstNonError ([PredicateMethod]): エラーではないコレクションの最初の要素を返します。

LastNonError ([PredicateMethod]): エラーではないコレクションの最後の要素を返します。

その他のメソッド

.All ( PredicateMethod ): 入力コレクション内のすべての要素で指定された述語メソッドを呼び出した結果が true かどうかを返します。

.Any ( PredicateMethod ): 入力コレクション内の任意の要素で指定された述語メソッドを呼び出した結果が true かどうかを返します。

.First ( [PredicateMethod] ): コレクション内の最初の要素を返します。 省略可能な述語が渡された場合、 は、述語の呼び出しが true を返すコレクション内の最初の要素を返します。

.Last ( [PredicateMethod] ): コレクション内の最後の要素を返します。 省略可能な述語が渡された場合、 は、述語の呼び出しが true を返すコレクション内の最後の要素を返します。

Min([KeyProjectorMethod]): コレクションの最小要素を返します。 オプションの投影方法を指定して、各メソッドを他のメソッドと比較する前に投影できます。

Max([KeyProjectorMethod]): コレクションの最大要素を返します。 オプションの投影方法を指定して、各メソッドを他のメソッドと比較する前に投影できます。

Single([PredicateMethod]): リストから唯一の要素を返します (コレクションに複数の要素が含まれている場合はエラーが返されます)。 述語が指定されている場合、 は、その述語を満たす 1 つの要素を返します (複数の要素がそれを満たす場合、関数は代わりにエラーを返します)。

引数のシグネチャ

KeyProjectorMethod : ( obj => 任意のキー ) コレクションの オブジェクトを取得し、そのオブジェクトからキーを返します。
KeyComparatorMethod: ( (a, b) => 整数値 ) 2 つのキーを受け取り、返されるキーを比較します。

-1 if ( a < b )

( a == b) の場合は 0

1 if ( a > b )

PredicateMethod: ( obj => ブール値 ) コレクションの オブジェクトを受け取り、そのオブジェクトが特定の条件を満たすかどうかに基づいて true または false を返します。

サポートされている LINQ 構文 - 文字列操作

すべての文字列オブジェクトには、使用できる次のメソッドが投影されています。

関連するメソッドのプロパティのクエリ&

.Contains ( OtherString ): 入力文字列に OtherString が含まれているかどうかを示すブール値を返します。

.EndsWith ( OtherString ): 入力文字列が OtherString で終わるかどうかを示すブール値を返します。

Length: 文字列の長さを返す プロパティです。

.StartsWith ( OtherString ): 入力文字列が OtherString で始まるかどうかを示すブール値を返します。

.Substring ( StartPos, [Length] ): 指定した開始位置から始まる入力文字列内の部分文字列を返します。 省略可能な長さを指定した場合、返される部分文字列は指定した長さになります。それ以外の場合は、文字列の末尾に移動します。

その他のメソッド

.IndexOf ( OtherString ): 入力文字列内で最初に見つかった OtherString のインデックスを返します。

.LastIndexOf ( OtherString ): 入力文字列内で最後に見つかった OtherString のインデックスを返します。

書式設定メソッド

.PadLeft ( TotalWidth ): 文字列の全体の長さを指定した幅に戻すには、必要に応じて文字列の左側にスペースを追加します。

.PadRight ( TotalWidth ): 文字列の長さの合計を指定した幅に設定するために、必要に応じて文字列の右側にスペースを追加します。

.Remove ( StartPos, [Length] ): 指定した開始位置から始まる入力文字列から文字を削除します。 省略可能な length パラメーターを指定すると、その文字数は削除されます。それ以外の場合は、文字列の末尾のすべての文字が削除されます。

.Replace ( 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 クエリで使用される組み込みのデバッガー オブジェクトを使用して、プラグ アンド プレイ オブジェクトをデバッグする方法について説明します。

すべてのデバイスを表示する

デバイス ツリーで Flatten を使用して、すべてのデバイスを表示します。

 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>)

たとえば、状態が Devicのデバイスを表示するには、次のコマンドを使用します。

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)
...

未開始のデバイスの表示

このコマンドを使用すると、状態が Devicではないデバイスを表示できます。

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

問題コード別のデバイスの表示

特定の問題コードを持つデバイスを表示するには、 devicの オブジェクトを使用します。

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.exe の一覧を表示するには、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 ]

Nt! _LIST_ENTRY 構造体の開始アドレスを使用してデータを表示するには、FromListEntry デバッガーオブジェクトを使用します。

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")

機能別にデバイスを表示する

DevicCapabilityFlags オブジェクトを使用して、機能別にデバイスを表示します。

dx -r1 @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => (n.DeviceNodeObject.CapabilityFlags & <flag>) != 0)

次の表は、一般的なデバイス機能フラグでの dx コマンドの使用方法をまとめたものです。

リムーバブル

dbgcmd 0: kd > dx-r1 @ $cursession。デバイス. DeviceTree (n = > n 子)。Where (n = > (CapabilityFlags & 0x10)! = 0) @ $cursession します。デバイス. DeviceTree (n = > n 子)。ここで、(n = > (CapabilityFlags & 0x10)! = 0)
[0x0]: swd2F8DBBB6-F246-4D84-BB1D-AA8761353885 um {} [0x1]: SWD\ PRINF210BC77-55A1-4FCA-AA80-013E2B408378 um {} [0x2]: SWD\ prin um {07940A8E-11F4-46C3-B714-7FF9B87738F8} [0x3]: DISPLAY \ Default_Monitor \ 6 & 1a097cd8 & 0 & UID5527112 (Monitor)

UniqueID

dbgcmd 0: kd > dx-r1 @ $cursession。デバイス. DeviceTree (n = > n 子)。Where (n = > (CapabilityFlags & 0x40)! = 0) @ $cursession します。デバイス. DeviceTree (n = > n 子)。ここで、(n = > (CapabilityFlags & 0x40)! = 0)
[0x0]: HTREE\ROOT\0 [0x1]: ROOT\volmgr\0000 (volmgr) [0x2]: ROOT\spaceport\0000 (space ポート)...

SilentInstall

dbgcmd 0: kd > dx-r1 @ $cursession。デバイス. DeviceTree (n = > n 子)。Where (n = > (CapabilityFlags & 0x80)! = 0) @ $cursession します。デバイス. DeviceTree (n = > n 子)。ここで、(n = > (CapabilityFlags & 0x80)! = 0)
[0x0]: HTREE\ROOT\0 [0x1]: ROOT\volmgr\0000 (volmgr) [0x2]: ROOT\spaceport\0000 (space ポート)...

RawDeviceOk

dbgcmd 0: kd > dx-r1 @ $cursession。デバイス. DeviceTree (n = > n 子)。Where (n = > (CapabilityFlags & 0x100)! = 0) @ $cursession します。デバイス. DeviceTree (n = > n 子)。ここで、(n = > (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。デバイス. DeviceTree (n = > n 子)。Where (n = > (CapabilityFlags & 0x200)! = 0) @ $cursession します。デバイス. DeviceTree (n = > n 子)。ここで、(n = > (CapabilityFlags & 0x200)! = 0)
[0x0]: SWD\MMDEVAPI\MicrosoftGSWavetableSynth [0x1]: SWD \ IP_TUNNEL_VBUS \ IP_TUNNEL_DEVICE_ROOT [0x2]: Swd/printqueues...

CapabilityFlags の詳細については、「 DEVICE_CAPABILITIES」を参照してください。

関連項目

dx (デバッガー オブジェクト モデル式の表示)

NatVis のネイティブ デバッガー オブジェクト

JavaScript 拡張機能のネイティブ デバッガー オブジェクト