Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
LINQ-syntax kan användas med felsökningsobjekten för att söka efter och manipulera data. Med hjälp av LINQ-syntaxen med dx-kommandot kan du få en mer konsekvent upplevelse jämfört med att använda felsökningskommandon. Utdata och alternativ är konsekventa oavsett vilket felsökningsobjekt du tittar på. MED LINQ-frågor kan du ställa frågor som "Vilka är de 5 vanligaste processerna som kör flest trådar?".
Felsökningsobjekt är hänförda till ett namnområde som har sin grund i "Debugger". Processer, moduler, trådar, staplar, stackramar och lokala variabler är alla tillgängliga för användning i en LINQ-fråga.
LINQ liknar konceptuellt det strukturerade frågespråket (SQL) som används för att köra frågor mot databaser. Du kan använda ett antal LINQ-metoder för att söka efter, filtrera och parsa felsökningsdata. LINQ C#-metodsyntaxen används. Mer information om LINQ och LINQ C#-syntaxen finns i Komma igång med LINQ i C#
LINQ som används i felsökningsstödet använder "metodsyntaxen" för LINQ och inte "frågesyntaxen". Du hittar mer information om skillnaderna i LINQ (Language-Integrated Query).
LINQ-kommandon som följande kan användas med felsökningsobjekten. Alla(). Any(). Count(). Första(). Flatten(). GroupBy(). Sista(). OrderBy(). OrderByDescending(). Välj(). Var(). Dessa metoder följer (så nära som möjligt) C# LINQ-metodformuläret.
Inbyggda debugger-objekt
Interna felsökningsobjekt representerar olika konstruktioner och beteenden i felsökningsmiljön. Exempel på felsökningsobjekt är följande.
- Sittning
- Trådar/tråd
- Processer/process
- Stackramar/Stackram
- Lokala variabler
- Moduler/modul
- Nytta
- Stat/län
- Inställningar
Du kan också arbeta med felsökningsobjekten med NatVis. Mer information finns i Interna felsökningsobjekt i NatVis. Information om hur du använder felsökningsobjekt med JavaScript finns i interna felsökningsobjekt i JavaScript-tillägg. För information om hur man arbetar med C++ och drivarobjekt kan du se Översikt över Debugger Data Model C++.
Dx-kommando
Exemplen som visas här använder dx-kommandot. Mer information om hur du arbetar med dx-kommandot finns i dx (Display Debugger Object Model Expression).
Utveckla en LINQ-fråga
Ett sätt att utveckla en LINQ-felsökningsobjektfråga är att använda de DML-länkar som visas för att utforska datamodellen för att först hitta felsökningsobjektet som ska användas i frågan.
I det här exemplet vill vi visa en lista över processer i en kernel-felsökningssession och antalet trådar för var och en av dessa processer.
För att starta vår utforskning kan vi använda dx-kommandot för att visa felsökningsobjektet på den översta nivån.
0: kd> dx Debugger
Debugger
Sessions
Settings
State
Utility
När vi har valt ämnen på den översta nivån anser vi att sessioner ser mest intressanta ut, så vi väljer DML-länken för att visa att den innehåller processer.
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
Sedan väljer vi längre ned för att titta på en specifik process och vi ser att de trådar som är associerade med den processen är tillgängliga. När vi väljer Trådar för en av processerna ser vi att alla trådar som är associerade med den processen är tillgängliga.
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]
Vi vet nu att de data som vi behöver för att visa antalet trådar som är associerade med en process är tillgängliga i felsökningsobjektmodellen.
För att göra LINQ-frågan lite kortare kan vi använda systemdefinierade variabler som beskrivs senare i det här avsnittet för att visa de processer som är associerade med den aktuella sessionen.
0: kd> dx @$cursession.Processes
@$cursession.Processes
[0x0] : Idle [Switch To]
[0x4] : System [Switch To]
[0x90] : Registry [Switch To]
...
Lägg sedan till en select-instruktion. Till att börja med kan vi ange fältet Namn.
0: kd> dx @$cursession.Processes.Select(p => p.Name)
@$cursession.Processes.Select(p => p.Name)
[0x0] : Idle
[0x4] : System
[0x90] : Registry
...
I vårt scenario behöver vi också antalet trådar. Eftersom det finns två fält skapar du en anonym typ med hjälp av ny, ungefär som C#:s syntax för anonym typ som beskrivs nedan i Användardefinierade variabler.
dx @$cursession.Processes.Select(p => new {Name = p.Name, Threads = p.Threads})
Med det kommandot skriver "dx" inte ut namnet längre, så lägg till -r2 (upprepa två nivåer) för att visa namn och trådar.
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
Nu visar vi namnet på processen och en lista med trådar. Om du vill visa ThreadCount använder du . Count() -metod.
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
...
Om du vill se vilka processer som har ett stort antal trådar sorterar du listan efter trådantal med 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
Om du vill rendera i ett formaterat rutnät ändrar du "-r2" till "-g". Rekursionsnivån behöver inte anges eftersom rutnätsalternativet visar kolumnerna på rätt sätt. Slutligen lägger du till formatspecificeraren ",d" för att mata ut decimalvärden.
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 =
Exempel på felsökningsobjekt
Det här exemplet visar de 5 vanligaste processerna som kör flest trådar:
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
[...]
Det här exemplet visar enheterna i plug and play-enhetsträdet grupperat efter namnet på drivrutinen för det fysiska enhetsobjektet. Alla utdata visas inte.
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)
...
Automatisk slutförande av Dx-kommandoflik
Automatisk komplettering av kontextuell TAB-nyckel är medveten om LINQ-frågemetoderna och fungerar för parametrar för lambdas.
Skriv till exempel (eller kopiera och klistra in) följande text i felsökningsprogrammet. Tryck sedan på TAB-tangenten flera gånger för att gå igenom potentiella slutföranden.
dx -r2 Debugger.Sessions.First().Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count() }).OrderByDescending(p => p.
Tryck på TAB-tangenten till ". Namn" visas. Lägg till en avslutande parentes ")" och tryck på Retur för att köra kommandot.
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
...
Det här exemplet visar slutförande med en nyckeljämförelsemetod. Ersättningen visar strängmetoder eftersom nyckeln är en sträng.
dx -r2 Debugger.Sessions.First().Processes.Select(p => new {Name = p.Name, ThreadCount = p.Threads.Count() }).OrderByDescending(p => p.Name, (a, b) => a.
Tryck på TAB-tangenten till ". Längd" visas. Lägg till en avslutande parentes ")" och tryck på Retur för att köra kommandot.
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
Användardefinierade variabler
En användardefinierad variabel kan definieras genom att prefixera variabelnamnet med @$. En användardefinierad variabel kan tilldelas till allt som dx kan använda, till exempel lambdas, resultatet av LINQ-frågor osv.
Du kan skapa och ange värdet för en användarvariabel som den här.
kd> dx @$String1="Test String"
Du kan visa de definierade användarvariablerna med hjälp av Debugger.State.UserVariables eller @$vars.
kd> dx Debugger.State.UserVariables
Debugger.State.UserVariables :
mySessionVar :
String1 : Test String
Du kan ta bort en variabel med hjälp av . Avlägsna.
kd> dx @$vars.Remove("String1")
Det här exemplet visar hur du definierar en användarvariabel för att referera till Debugger.Sesssions.
kd> dx @$mySessionVar = Debugger.Sessions
Den användardefinierade variabeln kan sedan användas enligt nedan.
kd> dx -r2 @$mySessionVar
@$mySessionVar :
[0x0] : Remote KD: KdSrv:Server=@{<Local>},Trans=@{COM:Port=\\.\com3,Baud=115200,Timeout=4000}
Processes :
Devices
Systemdefinierade variabler
Följande systemdefinierade variabler kan användas i alla LINQ dx-frågor.
@$cursession – den aktuella sessionen
@$curprocess – den aktuella processen
@$curthread – Den aktuella tråden
Det här exemplet visar användningen av systemdefinierade variabler.
kd> dx @$curprocess.Threads.Count()
@$curprocess.Threads.Count() : 0x4
kd> dx -r1 @$curprocess.Threads
@$curprocess.Threads :
[0x4adc] :
[0x1ee8] :
[0x51c8] :
[0x62d8] :
...
Användardefinierade variabler – Anonyma typer
Den här skapandet av dynamiska objekt görs med hjälp av syntaxen för anonym C#-typ (ny { ... }). Mer information finns i Anonyma typer (C#-programmeringsguide). Det här exemplet skapar en anonym typ med ett heltal och ett strängvärde.
kd> dx -r1 new { MyInt = 42, MyString = "Hello World" }
new { MyInt = 42, MyString = "Hello World" } :
MyInt : 42
MyString : Hello World
Funktionsobjekt (Lambda-uttryck)
Många av de metoder som används för att fråga efter data baseras på begreppet att upprepade gånger köra en användarfunktion över objekt i en samling. För att stödja möjligheten att fråga och manipulera data i felsökningsprogrammet stöder dx-kommandot lambda-uttryck med motsvarande C#-syntax. Ett lambda-uttryck definieras av användning av operatorn => enligt följande:
(argument) => (resultat)
Om du vill se hur LINQ används med dx kan du prova det här enkla exemplet för att lägga ihop 5 och 7.
kd> dx ((x, y) => (x + y))(5, 7)
DX-kommandot ekar tillbaka lambda-uttrycket och visar resultatet av 12.
((x, y) => (x + y))(5, 7) : 12
Det här lambda-exemplet kombinerar strängarna "Hello" och "World".
kd> dx ((x, y) => (x + y))("Hello", "World")
((x, y) => (x + y))("Hello", "World") : HelloWorld
LINQ-syntax som stöds – frågemetoder
Alla objekt som dx definierar som iterbara (oavsett om det är en intern matris, en typ som har NatVis skrivet som beskriver det som en container eller ett felsökningstilläggsobjekt) har en serie LINQ-metoder (eller LINQ-motsvarande) som projiceras på den. Dessa frågemetoder beskrivs nedan. Signaturerna för argumenten till frågemetoderna visas efter alla frågemetoder.
Filtreringsmetoder
. Where ( PredicateMethod ): Returnerar en ny samling objekt som innehåller varje objekt i indatasamlingen som predikatmetoden returnerade sant för.
Projektionsmetoder
. Platta ut ( [KeyProjectorMethod] ): Tar en indatacontainer med containrar (ett träd) och plattar ut den till en enda container som har varje element i trädet. Om den valfria nyckelprojektormetoden anges betraktas trädet som en container med nycklar som själva är containrar och dessa nycklar bestäms av ett anrop till projektionsmetoden.
. Select ( KeyProjectorMethod ): Returnerar en ny samling objekt som innehåller resultatet av att anropa projektormetoden för varje objekt i indatasamlingen.
Grupperingsmetoder
. GroupBy ( KeyProjectorMethod, [KeyComparatorMethod] ): Returnerar en ny samling samlingar genom att gruppera alla objekt i indatasamlingen med samma nyckel som bestäms genom att anropa nyckelprojektormetoden. Du kan ange en valfri jämförelsemetod.
Join (InnerCollection, Outer key selector method, Inner key selector method, Result selector method, [ComparatorMethod]): Ansluter två sekvenser baserat på nyckelväljarens funktioner och extraherar par med värden. Du kan också ange en valfri jämförelsemetod.
Intersect (InnerCollection, [ComparatorMethod]): Returnerar den angivna skärningspunkten, vilket innebär element som visas i var och en av två samlingar. Du kan också ange en valfri jämförelsemetod.
Union (InnerCollection, [ComparatorMethod]): Returnerar uppsättningens union, vilket innebär unika element som visas i någon av två samlingar. Du kan också ange en valfri jämförelsemetod.
Datauppsättningsmetoder
Contains (Object, [ComparatorMethod]): Avgör om en sekvens innehåller ett angivet element. En valfri jämförelsemetod kan anges som anropas varje gång elementet jämförs med en post i sekvensen.
Distinct ([ComparatorMethod]): Tar bort dubblettvärden från en samling. En valfri jämförelsemetod kan anges för att anropas varje gång objekt i samlingen måste jämföras.
Förutom (InnerCollection, [ComparatorMethod]): Returnerar den angivna skillnaden, vilket innebär elementen i en samling som inte visas i en andra samling. En valfri jämförelsemetod kan anges.
Concat (InnerCollection): Sammanfogar två sekvenser för att bilda en sekvens.
Beställningsmetoder
. OrderBy ( KeyProjectorMethod, [KeyComparatorMethod] ): Sorterar samlingen i stigande ordning enligt en nyckel som tillhandahålls genom att anropa metoden för nyckelprojektion för varje objekt i indatasamlingen. Du kan ange en valfri jämförelsemetod.
. OrderByDescending ( KeyProjectorMethod, [KeyComparatorMethod] ): Sorterar samlingen i fallande ordning enligt en nyckel som tillhandahålls genom att anropa metoden för nyckelprojektion för varje objekt i indatasamlingen. Du kan ange en valfri jämförelsemetod.
Aggregeringsmetoder
Antal (): En metod som returnerar antalet element i samlingen.
Summa ([ProjectionMethod]): Beräknar summan av värdena i en samling. Du kan också ange en projektormetod för att transformera elementen innan sammanfattningen sker.
Hoppa över metoder
Hoppa över (antal): Hoppar över element upp till en specificerad position i en sekvens.
SkipWhile (PredicateMethod): Hoppar över element baserat på en predikatfunktion tills ett element inte uppfyller villkoret.
Använd metoder
Take (Count): Tar element upp till en angiven position i en sekvens.
TakeWhile (PredicateMethod): Tar element baserat på en predikatfunktion tills ett element inte uppfyller villkoret.
Jämförelsemetoder
SequenceEqual (InnerCollection, [ComparatorMethod]): Avgör om två sekvenser är lika med genom att jämföra element på ett parvis sätt. En valfri jämförelse kan anges.
Metoder för felhantering
AllNonError (PredicateMethod): Returnerar om alla icke-felelement i en samling uppfyller ett visst villkor.
FirstNonError ([PredicateMethod]): Returnerar det första elementet i en samling som inte är ett fel.
LastNonError ([PredicateMethod]): Returnerar det sista elementet i en samling som inte är ett fel.
Andra metoder
. Alla ( PredicateMethod ): Returnerar om resultatet av att anropa den angivna predikatmetoden för varje element i indatasamlingen är sant.
. Any ( PredicateMethod ): Returnerar om resultatet av att anropa den angivna predikatmetoden på något element i indatasamlingen är sant.
. First ( [PredicateMethod] ): Returnerar det första elementet i samlingen. Om ett valfritt predikat anges returneras det första elementet i samlingen för vilket ett anrop till predikatet returnerar sant.
. Last ( [PredicateMethod] ): Returnerar det sista elementet i samlingen. Om det valfria predikatet skickas returnerar det sista elementet i samlingen som ett anrop till predikatet returnerar sant för.
Min([KeyProjectorMethod]): Returnerar det minsta elementet i samlingen. En valfri projektormetod kan anges för att projicera varje metod innan den jämförs med andra.
Max([KeyProjectorMethod]): Returnerar det maximala elementet i samlingen. En valfri projektormetod kan anges för att projicera varje metod innan den jämförs med andra.
Single([PredicateMethod]): Returnerar det enda elementet från listan (eller ett fel om samlingen innehåller mer än ett element). Om ett predikat anges returnerar det enda element som uppfyller predikatet (om fler än ett element uppfyller det returnerar funktionen ett fel i stället).
Signaturer för argumenten
| KeyProjectorMethod : ( obj => godtycklig nyckel ) | Tar ett objekt i samlingen och returnerar en nyckel från objektet. |
| KeyComparatorMethod: ( (a, b) => heltalsvärde ) | Tar två nycklar och jämför dem och returnerar: -1 om ( a < b ) 0 om ( a == b) 1 ifall ( a > b ) |
| PredicateMethod: ( obj => booleskt värde ) | Tar ett objekt i samlingen och returnerar sant eller falskt baserat på om objektet uppfyller vissa villkor. |
LINQ-syntax som stöds – strängmanipulering
Alla strängobjekt har följande metoder som projiceras i dem, så att de är tillgängliga för användning:
Sök efter relevanta metoder och egenskaper
. Contains ( OtherString ): Returnerar ett booleskt värde som anger om indatasträngen innehåller OtherString.
. EndsWith ( OtherString ): Returnerar ett booleskt värde som anger om indatasträngen slutar med OtherString.
Längd: En egenskap som returnerar strängens längd.
. StartsWith ( OtherString ): Returnerar ett booleskt värde som anger om indatasträngen börjar med OtherString.
. Delsträng ( StartPos, [Längd] ): Returnerar en delsträng i indatasträngen med början vid den angivna startpositionen. Om den valfria längden anges kommer den returnerade delsträngen att vara av den angivna längden. annars går den till slutet av strängen.
Diverse metoder
. IndexOf ( OtherString ): Returnerar indexet för den första förekomsten av OtherString i indatasträngen.
. LastIndexOf ( OtherString ): Returnerar indexet för den senaste förekomsten av OtherString i indatasträngen.
Formateringsmetoder
. PadLeft ( TotalWidth ): Lägger till blanksteg efter behov till vänster i strängen för att få den totala längden på strängen till den angivna bredden.
.PadRight ( TotalWidth ): Lägger till mellanslag vid behov till höger i strängen för att få strängens totala längd till den angivna bredden.
. Ta bort ( StartPos, [Längd] ): Tar bort tecken från indatasträngen från och med den angivna startpositionen. Om den valfria längdparametern anges tas det antalet tecken bort. annars tas alla tecken i slutet av strängen bort.
. Replace ( SearchString, ReplaceString ): Ersätter varje förekomst av SearchString i indatasträngen med den angivna ReplaceString.
Projektioner för strängobjekt
Förutom de metoder som projiceras direkt på strängobjekt har alla objekt som i sig har en strängkonvertering följande metod projicerad på den, vilket gör den tillgänglig för användning:
. ToDisplayString ( ): Returnerar en strängkonvertering av objektet. Det här är strängkonverteringen som visas i ett dx-anrop för objektet. Du kan ange en formateringsspecificerare för att formatera utdata från ToDisplayString. Mer information finns i Formatera specificerare för C++ i Visual Studio-felsökningsprogrammet
Följande exempel illustrerar användningen av formatspecificerare.
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
Felsökning av Plug and Play-exempel
Det här avsnittet visar hur de inbyggda felsökningsobjekten som används med LINQ-frågor kan användas för att felsöka plug and play-objekt.
Visa alla enheter
Använd Platta ut i enhetsträdet för att visa alla enheter.
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
...
rutnätsvisning
Precis som med andra dx-kommandon kan du välja och hålla (eller högerklicka) ett kommando efter att det kördes och välja "Visa som rutnät" eller lägga till "-g" i kommandot för att få en rutnätsvy över resultaten.
# 0: kd> dx -g @$cursession.Devices.DeviceTree.Flatten(n => n.Children)
=====================================================================================================================================================================================================================================================================================================================
# = = (+) DeviceNodeObject = InstancePath = ServiceName = (+) PhysicalDeviceObject = State = (+) Resources = (+) 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] =
...
Visa enheter efter tillstånd
Använd Var för att ange ett specifikt enhetstillstånd.
dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.State <operator> <state number>)
Om du till exempel vill visa enheter i tillståndet DeviceNodeStarted använder du det här kommandot.
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)
...
Visa enheter som inte har startats
Använd det här kommandot om du vill visa enheter som inte är i tillståndet 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
Visa enheter efter problemkod
Använd objektet DeviceNodeObject.Problem för att visa enheter som har specifika problemkoder.
dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.DeviceNodeObject.Problem <operator> <problemCode>)
Om du till exempel vill visa enheter som har en problemkod som inte är noll använder du det här kommandot. Detta ger liknande information som "!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)
Visa alla enheter utan problem
Använd det här kommandot för att visa alla enheter utan problem
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)
...
Visa alla enheter med ett specifikt problem
Använd det här kommandot om du vill visa enheter med problemtillståndet 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)
Visa enheter efter funktionsdrivrutin
Använd det här kommandot för att visa enheter efter funktionsdrivrutin.
dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.ServiceName <operator> <service name>)
Om du vill visa enheter med hjälp av en viss funktionsdrivrutin, till exempel atapi, använder du det här kommandot.
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)
Visa en lista över startdrivrutiner
För att se listan över de startdrivrutiner som winload.exe läste in, måste du vara i en kontext där du har tillgång till LoaderBlock och gör detta tidigt nog så att LoaderBlock fortfarande är tillgänglig. Till exempel under nt!IopInitializeBootDrivers. En brytpunkt kan ställas in för att stoppa i den här kontexten.
1: kd> g
Breakpoint 0 hit
nt!IopInitializeBootDrivers:
8225c634 8bff mov edi,edi
Använd ?? kommandot för att visa startdrivrutinsstrukturen.
1: kd> ?? LoaderBlock->BootDriverListHead
struct _LIST_ENTRY
[ 0x808c9960 - 0x808c8728 ]
+0x000 Flink : 0x808c9960 _LIST_ENTRY [ 0x808c93e8 - 0x808a2e18 ]
+0x004 Blink : 0x808c8728 _LIST_ENTRY [ 0x808a2e18 - 0x808c8de0 ]
Använd felsökningsobjektet Debugger.Utility.Collections.FromListEntry för att visa data med hjälp av startadressen för nt!_LIST_ENTRY-strukturen.
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]
...
Använd alternativet -g för att skapa en rutnätsvy av data.
dx -r1 -g Debugger.Utility.Collections.FromListEntry(*(nt!_LIST_ENTRY *)0x808c9960, "nt!_BOOT_DRIVER_LIST_ENTRY", "Link")
Visa enheter efter kapacitet
Visa enheter efter funktion med hjälp av objektet DeviceNodeObject.CapabilityFlags.
dx -r1 @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => (n.DeviceNodeObject.CapabilityFlags & <flag>) != 0)
Den här tabellen sammanfattar användningen av dx-kommandot med vanliga enhetsfunktionsflaggor.
| Avtagbar |
|
| UniqueID |
|
| SilentInstall |
|
| RawDeviceOk |
|
| SurpriseRemovalOK |
|
Mer information om CapabilityFlags finns i DEVICE_CAPABILITIES.
Se även
dx (Visning av objektmodelluttryck för felsökningsprogram)
interna felsökningsobjekt i NatVis
interna felsökningsobjekt i JavaScript-tillägg