Delen via


LINQ gebruiken met de foutopsporingsprogrammaobjecten

LINQ-syntaxis kan worden gebruikt met de foutopsporingsprogramma-objecten om gegevens te doorzoeken en te bewerken. Het gebruik van de LINQ-syntaxis met dx-opdracht biedt een consistentere ervaring in vergelijking met het gebruik van foutopsporingsprogramma-opdrachten. De uitvoer en opties zijn consistent, ongeacht het foutopsporingsprogramma-object dat u bekijkt. MET LINQ-query's kunt u vragen stellen, zoals 'Wat zijn de vijf belangrijkste processen die de meeste threads uitvoeren?'.

Debugger-objecten worden geprojecteerd in een naamruimte die is gebaseerd op Debugger. Processen, modules, threads, stackframes en lokale variabelen zijn allemaal beschikbaar voor gebruik in een LINQ-query.

LINQ is conceptueel vergelijkbaar met de Structured Query Language (SQL) die wordt gebruikt om query's uit te voeren op databases. U kunt een aantal LINQ-methoden gebruiken voor het zoeken, filteren en parseren van foutopsporingsgegevens. De syntaxis van de LINQ C#-methode wordt gebruikt. Zie voor meer informatie over LINQ en de LINQ C#-syntaxis Aan de slag met LINQ in C#

LINQ die wordt gebruikt in de ondersteuning voor foutopsporingsprogramma' gebruikt de 'methodesyntaxis' van LINQ en niet de 'querysyntaxis'. Meer informatie over de verschillen in LINQ (Language-Integrated Query).

LINQ-opdrachten zoals het volgende kunnen worden gebruikt met de foutopsporingsprogrammaobjecten. Selecteer alles, .Enig, .Tellen, .Eerste, .Flatten, .GroupBy, .Laatste, .OrderBy, .OrderByDescending, .Selecteer en .Waar. Deze methoden volgen (zo dicht mogelijk) de C#LINQ-methodevorm.

Systeemeigen debugger-objecten

Systeemeigen foutopsporingsprogrammaobjecten vertegenwoordigen verschillende constructies en gedrag van de foutopsporingsprogramma-omgeving. Voorbeelden van foutopsporingsprogrammaobjecten zijn het volgende.

  • Sessie
  • Threads/draad
  • Processen/proces
  • Stapelraam (Stack Frame) / Stapelramen (Stack Frames)
  • Lokale variabelen
  • Modules/Module
  • Nutsvoorzieningen
  • Staat
  • Instellingen

U kunt ook met de foutopsporingsprogrammaobjecten werken met NatVis. Voor meer informatie, zie Systeemeigen foutopsporingsobjecten in NatVis. Zie Native Debugger Objects in JavaScript Extensionsvoor meer informatie over het gebruik van foutopsporingsprogrammaobjecten met JavaScript. Zie Overzicht van gegevensmodel C++voor meer informatie over het werken met C++ en de stuurprogrammaobjecten.

Dx-opdracht

De voorbeelden die hier worden weergegeven, gebruiken de dx-opdracht, voor meer informatie over het werken met de dx-opdracht, zie dx (Display Debugger Object Model Expression).

Een LINQ-query ontwikkelen

Een manier om een LINQ-foutopsporingsprogrammaquery te ontwikkelen, is door de DML-koppelingen te gebruiken die worden weergegeven om het gegevensmodel te verkennen om eerst het foutopsporingsprogrammaobject te vinden dat in de query wordt gebruikt.

In dit voorbeeld willen we een lijst met processen weergeven in een kernelfoutopsporingssessie en het aantal threads voor elk van deze processen.

Om onze verkenning te starten, kunnen we de dx-opdracht gebruiken om het foutopsporingsprogramma-object op het hoogste niveau weer te geven.

0: kd> dx Debugger
Debugger
    Sessions
    Settings
    State
    Utility

Nadat we de onderwerpen op het hoogste niveau hebben geselecteerd, vinden we dat Sessions het interessantst lijkt. Daarom selecteren we de DML-link om te zien dat deze Processenbevat.

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

Vervolgens selecteren we verder om naar een specifiek proces te kijken en zien we dat de Threads die aan dat proces zijn gekoppeld, beschikbaar zijn. Wanneer we Threads selecteren voor een van de processen, zien we dat alle threads die aan dat proces zijn gekoppeld, beschikbaar zijn.

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] 

We weten nu dat de gegevens die we nodig hebben om het aantal threads weer te geven dat aan een proces is gekoppeld, beschikbaar is in het objectmodel voor foutopsporingsprogramma's.

Om de LINQ-query iets korter te maken, kunnen we de Door het systeem gedefinieerde variabelen gebruiken verderop in dit onderwerp beschreven om de processen weer te geven die zijn gekoppeld aan de huidige sessie.

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

Voeg vervolgens een select-instructie toe. Om te beginnen kunnen we het veld Naam opgeven.

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

Voor ons scenario hebben we ook het aantal threads nodig. Omdat er twee velden zijn, maakt u een anoniem type met behulp van nieuwe, vergelijkbaar met de hieronder beschreven anonieme typesyntaxis van C# in door de gebruiker gedefinieerde variabelen.

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

Met deze opdracht drukt 'dx' de naam niet meer af, dus voeg -r2 (recurse twee niveaus) toe om naam en threads weer te geven.

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       

Op dit moment geven we de naam van het proces en een lijst met threads weer. Als u ThreadCount wilt weergeven, gebruikt u de methode .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
...

Als u wilt zien welke processen een groot aantal threads hebben, rangschikt u de lijst op aantal threads met behulp van 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

Als u wilt weergeven in een opgemaakt raster, wijzigt u de waarde '-r2' in '-g'. Het recursieniveau hoeft niet te worden opgegeven, omdat de rasteroptie de kolommen op de juiste manier weergeeft. Voeg ten slotte de notatieaanduiding ',d' toe aan de uitvoerdecimaalwaarden.

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          =

Voorbeelden van foutopsporingsprogrammaobjecten

In dit voorbeeld ziet u de vijf belangrijkste processen die de meeste threads uitvoeren:

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
    [...]       

In dit voorbeeld ziet u de apparaten in de plug-and-play-apparaatstructuur gegroepeerd op de naam van het stuurprogramma van het fysieke apparaatobject. Niet alle uitvoer wordt weergegeven.

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 Command Tab Automatisch aanvullen

Contextuele TAB-sleutel automatisch aanvullen is op de hoogte van de LINQ-querymethoden en werkt voor parameters van lambdas.

Typ bijvoorbeeld de volgende tekst (of kopieer en plak deze in het foutopsporingsprogramma). Druk vervolgens meerdere keren op de TAB-toets om door mogelijke voltooiingen te bladeren.

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

Druk op de Tab-toets totdat ".Naam" wordt weergegeven. Voeg een sluitend haakje toe en druk op de Enter-toets om de opdracht uit te voeren.

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

In dit voorbeeld ziet u de voltooiing met een vergelijkingsmethode voor sleutels. De substitutie toont stringmethoden, omdat de sleutel een tekenreeks is.

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

Druk op de TAB-toets totdat '.Length' wordt weergegeven. Voeg een sluitend haakje ")" toe en druk op Enter om de opdracht uit te voeren.

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

Door de gebruiker gedefinieerde variabelen

Een door de gebruiker gedefinieerde variabele kan worden gedefinieerd door de naam van de variabele vooraf te laten gaan door @$. Een door de gebruiker gedefinieerde variabele kan worden toegewezen aan alles wat dx kan gebruiken, bijvoorbeeld lambdas, de resultaten van LINQ-query's, enzovoort.

U kunt de waarde van een gebruikersvariabele zoals deze maken en instellen.

kd> dx @$String1="Test String"

U kunt de gedefinieerde gebruikersvariabelen weergeven met Debugger.State.UserVariables of @$vars.

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

U kunt een variabele verwijderen met behulp van . Verwijderen.

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

In dit voorbeeld ziet u hoe u een gebruikersvariabele definieert om te verwijzen naar Debugger.Sesssions.

kd> dx @$mySessionVar = Debugger.Sessions

De door de gebruiker gedefinieerde variabele kan vervolgens worden gebruikt zoals hieronder wordt weergegeven.

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

Door het systeem gedefinieerde variabelen

De volgende door het systeem gedefinieerde variabelen kunnen worden gebruikt in elke LINQ dx-query.

  • @$cursession - De huidige sessie

  • @$curprocess - Het huidige proces

  • @$curthread - De huidige thread

In dit voorbeeld ziet u het gebruik van de door het systeem gedefinieerde variabelen.

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

Door de gebruiker gedefinieerde variabelen - Anonieme typen

Dit maken van dynamische objecten wordt uitgevoerd met behulp van de syntaxis van het anonieme type C# (nieuw { ... }). Zie Anonieme typen (C#-programmeerhandleiding)voor meer informatie over anonieme typen. In dit voorbeeld wordt een anoniem type gemaakt met een geheel getal en een tekenreekswaarde.

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

Functieobjecten (Lambda-expressies)

Veel van de methoden die worden gebruikt om query's uit te voeren op gegevens, zijn gebaseerd op het concept van het herhaaldelijk uitvoeren van een door de gebruiker geleverde functie voor objecten in een verzameling. Ter ondersteuning van de mogelijkheid om gegevens in het foutopsporingsprogramma op te vragen en te bewerken, ondersteunt de dx-opdracht lambda-expressies met behulp van de equivalente C#-syntaxis. Een lambda-expressie wordt als volgt gedefinieerd door het gebruik van de operator =>:

(argumenten) => (resultaat)

Als u wilt zien hoe LINQ wordt gebruikt met dx, kunt u dit eenvoudige voorbeeld proberen om 5 en 7 samen te voegen.

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

Met de dx-opdracht wordt de lambda-expressie herhaald en wordt het resultaat van 12 weergegeven.

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

In dit voorbeeld combineert de lambda-expressie de tekenreeksen 'Hallo' en 'Wereld'.

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

Ondersteunde LINQ-syntaxis - Querymethoden

Elk object dat dx definieert als itereerbaar (zij het een systeemeigen array, een type waarvoor NatVis geschreven is dat het als een container beschrijft, of een debug-extensieobject) heeft een reeks LINQ-methoden (of LINQ-equivalent) die erop geprojecteerd worden. Deze querymethoden worden hieronder beschreven. De handtekeningen van de argumenten voor de querymethoden worden weergegeven na alle querymethoden.

Filtermethoden

. Where ( PredicateMethod ): retourneert een nieuwe verzameling objecten die elk object in de invoerverzameling bevatten waarvoor de predicaatmethode waar heeft geretourneerd.

Projectiemethoden

. Flatten ( [KeyProjectorMethod] ): Neemt een invoercontainer van containers (een boomstructuur) en platte deze tot één container die alle elementen van de boomstructuur bevat. Als de optionele sleutelprojectormethode wordt opgegeven, wordt de structuur beschouwd als een container met sleutels die zelf containers zijn en die sleutels worden bepaald door een aanroep van de projectiemethode.

. Select ( KeyProjectorMethod ): retourneert een nieuwe verzameling objecten met het resultaat van het aanroepen van de projectormethode op elk object in de invoerverzameling.

Groeperingsmethoden

. GroupBy ( KeyProjectorMethod, [KeyComparatorMethod] ): retourneert een nieuwe verzameling verzamelingen door alle objecten in de invoerverzameling te groeperen met dezelfde sleutel als wordt bepaald door de sleutelprojectormethode aan te roepen. Er kan een optionele comparatormethode worden opgegeven.

Join (InnerCollection, Outer key selector methode, Inner key selector methode, Resultaatselector methode, [ComparatorMethod]): Voegt twee reeksen samen op basis van sleutelselectorfuncties en extraheert paren van waarden. Er kan ook een optionele comparatormethode worden opgegeven.

Intersect (InnerCollection, [ComparatorMethod]): retourneert het snijpunt van de set, wat betekent dat elementen in elk van twee verzamelingen worden weergegeven. Er kan ook een optionele comparatormethode worden opgegeven.

Union (InnerCollection, [ComparatorMethod]): retourneert de set-samenvoeging, wat unieke elementen betekent die in een van de twee verzamelingen worden weergegeven. Er kan ook een optionele comparatormethode worden opgegeven.

Datasetmethoden

Bevat (Object, [ComparatorMethod]): Bepaalt of een reeks een opgegeven element bevat. Er kan een optionele vergelijkingsmethode worden opgegeven die telkens wordt aangeroepen wanneer het element wordt vergeleken met een vermelding in de reeks.

Distinct ([ComparatorMethod]): hiermee verwijdert u dubbele waarden uit een verzameling. Er kan een optionele comparatormethode worden opgegeven die telkens moet worden aangeroepen wanneer objecten in de verzameling moeten worden vergeleken.

Except (InnerCollection, [ComparatorMethod]): retourneert het verschil van de verzamelingen, wat betekent dat de elementen van één verzameling niet voorkomen in een tweede verzameling. Er kan een optionele comparatormethode worden opgegeven.

Concat (InnerCollection): voegt twee reeksen samen om één reeks te vormen.

Bestelmethoden

. OrderBy ( KeyProjectorMethod, [KeyComparatorMethod] ): Sorteert de verzameling in oplopende volgorde op basis van een sleutel, zoals wordt opgegeven door de sleutelprojectiemethode aan te roepen voor elk object in de invoerverzameling. Er kan een optionele comparatormethode worden opgegeven.

. OrderByDescending ( KeyProjectorMethod, [KeyComparatorMethod] ): Sorteert de verzameling in aflopende volgorde op basis van een sleutel, zoals wordt opgegeven door de sleutelprojectiemethode aan te roepen voor elk object in de invoerverzameling. Er kan een optionele comparatormethode worden opgegeven.

Het samenvoegen van methoden

Count (): een methode die het aantal elementen in de verzameling retourneert.

Sum ([ProjectionMethod]): berekent de som van de waarden in een verzameling. U kunt desgewenst een projectormethode opgeven om de elementen te transformeren voordat de som plaatsvindt.

Methoden overslaan

Overslaan (aantal): Hiermee worden elementen overgeslagen tot een bepaalde positie in een reeks.

SkipWhile (PredicateMethod): Slaat elementen over op basis van een predicaatfunctie totdat een element niet aan de voorwaarde voldoet.

Methoden gebruiken

Take (Count): Neemt elementen tot een opgegeven positie in een reeks.

TakeWhile (PredicateMethod): Neemt elementen op basis van een predicaatfunctie totdat een element niet aan de voorwaarde voldoet.

Vergelijkingsmethoden

SequenceEqual (InnerCollection, [ComparatorMethod]): bepaalt of twee reeksen gelijk zijn door elementen op een paar manieren te vergelijken. Er kan een optionele vergelijkingsmachine worden opgegeven.

Methoden voor foutafhandeling

AllNonError (PredicateMethod): geeft als resultaat of alle niet-foutelementen van een verzameling aan een bepaalde voorwaarde voldoen.

FirstNonError ([PredicateMethod]): retourneert het eerste element van een verzameling die geen fout is.

LastNonError ([PredicateMethod]): retourneert het laatste element van een verzameling die geen fout is.

Andere methoden

. All ( PredicateMethod ): geeft als resultaat of het resultaat van het aanroepen van de opgegeven predicaatmethode voor elk element in de invoerverzameling waar is.

. Any ( PredicateMethod ): geeft als resultaat of het resultaat van het aanroepen van de opgegeven predicaatmethode op een element in de invoerverzameling waar is.

. First ( [PredicateMethod] ): retourneert het eerste element in de verzameling. Indien het optionele predicaat wordt doorgegeven, wordt het eerste element in de verzameling geretourneerd waarvoor een aanroep van het predicaat waar retourneert.

. Last ( [PredicateMethod] ): retourneert het laatste element in de verzameling. Als het optionele predicaat wordt doorgegeven, wordt het laatste element in de verzameling geretourneerd waarvoor een oproep naar het predicaat waar oplevert.

Min([KeyProjectorMethod]): retourneert het minimale element van de verzameling. Een optionele projectormethode kan worden opgegeven om elke methode te projecteren voordat deze wordt vergeleken met anderen.

Max([KeyProjectorMethod]): retourneert het maximumelement van de verzameling. Een optionele projectormethode kan worden opgegeven om elke methode te projecteren voordat deze wordt vergeleken met anderen.

Single([PredicateMethod]): retourneert het enige element uit de lijst (of een fout als de verzameling meer dan één element bevat). Als een predicaat is opgegeven, wordt het enige element geretourneerd dat voldoet aan dat predicaat (als er meer dan één element aan het predicaat voldoet, retourneert de functie in plaats daarvan een fout).

handtekeningen van de argumenten

KeyProjectorMethod : ( obj => willekeurige sleutel ) Neemt een object van de verzameling en retourneert een sleutel van dat object.
KeyComparatorMethod: ( (a, b) => integervalue ) Neemt twee sleutels en vergelijkt deze, retourneert:

-1 if ( a < b )

0 if ( a == b)

1 if ( a > b )

PredicateMethod: ( obj => booleaanse waarde ) Neemt een object van de verzameling en retourneert waar of onwaar op basis van of dat object voldoet aan bepaalde criteria.

Ondersteunde LINQ-syntaxis - Tekenreeksmanipulatie

Alle tekenreeksobjecten hebben de volgende methoden in hen geïntegreerd, waardoor ze beschikbaar zijn voor gebruik.

Vraag relevante methoden van & eigenschappen

. Bevat ( OtherString ): retourneert een Booleaanse waarde die aangeeft of de invoertekenreeks OtherString bevat.

. EndsWith ( OtherString ): retourneert een Booleaanse waarde die aangeeft of de invoertekenreeks eindigt op OtherString.

Length: een eigenschap die de lengte van een tekenreeks retourneert.

. StartsWith ( OtherString ): retourneert een Booleaanse waarde die aangeeft of de invoertekenreeks begint met OtherString.

. Subtekenreeks ( StartPos, [Lengte] ): retourneert een subtekenreeks binnen de invoertekenreeks die begint bij de opgegeven beginpositie. Als de optionele lengte wordt opgegeven, is de geretourneerde subtekenreeks van de opgegeven lengte; anders gaat deze naar het einde van de tekenreeks.

Diverse methoden

.IndexOf(OtherString): retourneert de index van het eerste voorkomen van OtherString in de invoertekenreeks.

.LastIndexOf(OtherString): Geeft de index van het laatste voorkomen van OtherString in de invoertekenreeks.

Opmaakmethoden

. PadLeft ( TotalWidth ): Voegt indien nodig spaties toe aan de linkerkant van de tekenreeks om de totale lengte van de tekenreeks naar de opgegeven breedte te brengen.

. PadRight ( TotalWidth ): Voegt indien nodig spaties toe aan de rechterkant van de tekenreeks om de totale lengte van de tekenreeks naar de opgegeven breedte te brengen.

. Remove ( StartPos, [Length] ): Verwijdert tekens uit de invoertekenreeks die begint als de opgegeven beginpositie. Als de optionele lengteparameter wordt opgegeven, wordt dat aantal tekens verwijderd; anders worden alle tekens aan het einde van de tekenreeks verwijderd.

. Replace ( SearchString, ReplaceString ): Vervangt elk voorkomen van SearchString in de invoertekenreeks door de opgegeven ReplaceString.

Projecties van stringobjecten

Naast de methoden die rechtstreeks naar tekenreeksobjecten worden geprojecteerd, heeft elk object dat zelf een tekenreeksconversie heeft de volgende methode geprojecteerd, waardoor deze methode beschikbaar is voor gebruik:

. ToDisplayString ( ): retourneert een tekenreeksconversie van het object. Dit is de tekenreeksconversie die wordt weergegeven in een dx-aanroep voor het object. U kunt een opmaakaanduiding opgeven om de uitvoer van ToDisplayString op te maken. Zie voor meer informatie Opmaakaanduidingen voor C++ in het foutopsporingsprogramma van Visual Studio

De volgende voorbeelden illustreren het gebruik van opmaakaanduidingen.

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

Voorbeeld van foutopsporing voor Plug and Play

In deze sectie ziet u hoe de ingebouwde foutopsporingsprogrammaobjecten die worden gebruikt met LINQ-query's, kunnen worden gebruikt voor het opsporen van fouten in plug- en play-objecten.

Alle apparaten weergeven

Gebruik de opdracht Flatten in de apparaathierarchie om alle apparaten weer te geven.

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

rasterweergave

Net als bij andere dx-opdrachten kunt u een opdracht selecteren en vasthouden (of met de rechtermuisknop klikken) nadat deze is uitgevoerd en selecteer 'Weergeven als raster' of voeg '-g' toe aan de opdracht om een rasterweergave van de resultaten op te halen.

# 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]    =
...

apparaten per status weergeven

Gebruik Where om een specifieke apparaatstatus op te geven.

dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.State <operator> <state number>)

Als u bijvoorbeeld apparaten wilt weergeven met de status DeviceNodeStarted, gebruikt u deze opdracht.

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

Apparaten weergeven die niet zijn gestart

Gebruik deze opdracht om apparaten weer te geven die niet de status DeviceNodeStarted hebben.

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

apparaten weergeven op probleemcode

Gebruik de DeviceNodeObject.Problem object om apparaten met specifieke foutcodes weer te geven.

dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.DeviceNodeObject.Problem <operator> <problemCode>)

Als u bijvoorbeeld apparaten wilt weergeven met een niet-nulprobleemcode, gebruikt u deze opdracht. Dit biedt vergelijkbare informatie als '!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)

alle apparaten zonder probleem weergeven

Gebruik deze opdracht om alle apparaten zonder een probleem weer te geven

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

alle apparaten met een specifiek probleem weergeven

Gebruik deze opdracht om apparaten met een probleemstatus van 0x16 weer te geven.

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)

Apparaten weergeven per functiestuurprogramma

Gebruik deze opdracht om apparaten per functiestuurprogramma weer te geven.

dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => n.ServiceName <operator> <service name>)

Gebruik deze opdracht om apparaten weer te geven met behulp van een bepaald functiestuurprogramma, zoals 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)

Een Lijst met Opstartdrivers Weergeven

Als u de lijst wilt bekijken van wat winload heeft geladen als opstartstuurprogramma's, moet u zich in een context bevinden waar u toegang hebt tot het LoaderBlock en vroeg genoeg is het LoaderBlock nog steeds aanwezig. Bijvoorbeeld tijdens nt!IopInitializeBootDrivers. Een onderbrekingspunt kan worden ingesteld om te stoppen in deze context.

1: kd> g
Breakpoint 0 hit
nt!IopInitializeBootDrivers:
8225c634 8bff            mov     edi,edi

Gebruik de ?? Opdracht om de structuur van het opstartstuurprogramma weer te geven.

1: kd> ?? LoaderBlock->BootDriverListHead
struct _LIST_ENTRY
 [ 0x808c9960 - 0x808c8728 ]
   +0x000 Flink            : 0x808c9960 _LIST_ENTRY [ 0x808c93e8 - 0x808a2e18 ]
   +0x004 Blink            : 0x808c8728 _LIST_ENTRY [ 0x808a2e18 - 0x808c8de0 ]

Gebruik het object Debugger.Utility.Collections.FromListEntry debugger om de gegevens weer te geven met behulp van het beginadres van de structuur 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]
...

Gebruik de optie -g om een rasterweergave van de gegevens te maken.

dx -r1 -g Debugger.Utility.Collections.FromListEntry(*(nt!_LIST_ENTRY *)0x808c9960, "nt!_BOOT_DRIVER_LIST_ENTRY", "Link")

Apparaten weergeven op mogelijkheden

Apparaten weergeven op capaciteit via het object DeviceNodeObject.CapabilityFlags.

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

Deze tabel bevat een overzicht van het gebruik van de dx-opdracht met algemene apparaatfunctionaliteitsvlagken.

Afneembaar

dbgcmd 0: kd> dx -r1 @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => (n.DeviceNodeObject.CapabilityFlags & 0x10) != 0) @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => (n.DeviceNodeObject.CapabilityFlags & 0x10) != 0)
[0x0] : SWD\PRINTENUM{2F8DBBB6-F246-4D84-BB1D-AA8761353885} [0x1] : SWD\PRINTENUM{F210BC77-55A1-4FCA-AA80-013E2B408378} [0x2] : SWD\PRINTENUM{07940A8E-11F4-46C3-B714-7FF9B87738F8} [0x3] : DISPLAY\Default_Monitor\6&1a097cd8&0&UID5527112 (monitor)

UniqueID

dbgcmd 0: kd> dx -r1 @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => (n.DeviceNodeObject.CapabilityFlags & 0x40) != 0) @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(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).Where(n => (n.DeviceNodeObject.CapabilityFlags & 0x80) != 0) @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(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).Where(n => (n.DeviceNodeObject.CapabilityFlags & 0x100) != 0) @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(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).Where(n => (n.DeviceNodeObject.CapabilityFlags & 0x200) != 0) @$cursession.Devices.DeviceTree.Flatten(n => n.Children).Where(n => (n.DeviceNodeObject.CapabilityFlags & 0x200) != 0)
[0x0] : SWD\MMDEVAPI\MicrosoftGSWavetableSynth [0x1] : SWD\IP_TUNNEL_VBUS\IP_TUNNEL_DEVICE_ROOT [0x2] : SWD\PRINTENUM\PrintQueues ...

Zie DEVICE_CAPABILITIESvoor meer informatie over de CapabilityFlags.

Zie ook

dx (Display Debugger Object Model Expression)

Systeemeigen debug-objecten in NatVis

Systeemeigen Debugger-objecten in JavaScript-extensies