Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Systeemeigen foutopsporingsprogrammaobjecten vertegenwoordigen verschillende constructies en gedrag van de foutopsporingsprogramma-omgeving. De objecten kunnen worden doorgegeven aan (of verkregen in) JavaScript-extensies om de status van het foutopsporingsprogramma te manipuleren.
Voorbeelden van foutopsporingsprogrammaobjecten zijn het volgende.
- Sessie
- Threads/draad
- Processen/proces
- Stapelraam (Stack Frame) / Stapelramen (Stack Frames)
- Lokale variabelen
- Modules/Module
- Nutsvoorzieningen
- Staat
- Instellingen
Het object host.namespace.Debugger.Utility.Control.ExecuteCommand kan bijvoorbeeld worden gebruikt om de opdracht u naar het foutopsporingsprogramma te verzenden met de volgende twee regels JavaScript-code.
var ctl = host.namespace.Debugger.Utility.Control;
var outputLines = ctl.ExecuteCommand("u");
In dit onderwerp wordt beschreven hoe u met algemene objecten kunt werken en referentie-informatie kunt vinden over de kenmerken en het gedrag ervan.
Zie JavaScript Debugger Scripting voor algemene informatie over het werken met JavaScript. Zie Voorbeeldscripts voor JavaScript Debugger voor voorbeelden die gebruikmaken van de debugger-objecten. Zie .settings (Instellingen voor foutopsporing instellen) voor informatie over het werken met de instellingenobjecten.
Als u de objecten wilt verkennen die beschikbaar zijn in een foutopsporingsprogrammasessie, gebruikt u de opdracht dx (Display NatVis Expression). U kunt bijvoorbeeld enkele foutopsporingsprogrammaobjecten op het hoogste niveau weergeven met deze dx-opdracht.
0: kd> dx -r2 Debugger
Debugger
Sessions : [object Object]
[0x0] : Remote KD: KdSrv:Server=@{<Local>},Trans=@{NET:Port=50000,Key=1.2.3.4,Target}
Settings
Debug
Display
EngineInitialization
Extensions
Input
Sources
Symbols
AutoSaveSettings : false
State
DebuggerVariables
PseudoRegisters
Scripts
UserVariables
Utility
Collections
Control
Objects
Alle items die hierboven worden vermeld, zijn klikbaar DML en kunnen verder naar beneden worden teruggezet om de objectstructuur van het foutopsporingsprogramma weer te geven.
Het foutopsporingsprogramma uitbreiden via het gegevensmodel
Met het gegevensmodel voor foutopsporing kunt u een interface maken voor informatie over toepassingen en stuurprogramma's in Windows met de volgende kenmerken.
- Is detecteerbaar en georganiseerd: een logisch gestructureerde naamruimte kan worden opgevraagd met behulp van de dx-opdracht.
- Kan worden opgevraagd met LINQ: hiermee kunt u gegevens extraheren en sorteren met behulp van een standaardquerytaal.
- Kan logisch en consistent worden uitgebreid. Uitbreidbaar met behulp van technieken die in dit onderwerp worden beschreven met foutopspoorscriptproviders zoals Natvis en JavaScript.
Een foutopsporingsprogrammaobject uitbreiden in JavaScript
Naast het maken van een visualisatie in JavaScript kunnen scriptextensies ook de kernconcepten van het foutopsporingsprogramma wijzigen: sessies, processen, threads, stackframes, lokale variabelen en zelfs publiceren als uitbreidingspunten die andere extensies kunnen gebruiken.
In deze sectie wordt beschreven hoe u een kernconcept in het foutopsporingsprogramma kunt uitbreiden. Extensies die zijn gebouwd om te worden gedeeld, moeten voldoen aan de richtlijnen die worden gepresenteerd in systeemeigen foutopsporingsprogrammaobjecten in JavaScript Extensions - Ontwerp- en testoverwegingen.
een extensie registreren
Een script kan het feit registreren dat het een extensie biedt via een vermelding in de matrix die wordt geretourneerd door de initializeScript-methode.
function initializeScript()
{
return [new host.namedModelParent(comProcessExtension, "Debugger.Models.Process")];
}
De aanwezigheid van een host.namedModelParent-object in de geretourneerde array geeft aan dat een bepaald prototypeobject of de ES6-klasse (comProcessExtension in dit geval) zullen dienen als oudergegevensmodel voor het model dat is geregistreerd onder de naam Debugger.Models.Process.
Objectextensiepunten voor foutopsporingsprogramma
De volgende foutopsporingsprogramma-extensiepunten zijn integraal voor het foutopsporingsprogramma en zijn beschikbaar voor gebruik door scriptproviders zoals JavaScript.
Debugger.Models.Sessions: de lijst met sessies (doelen) waaraan het foutopsporingsprogramma is gekoppeld
Debugger.Models.Session: een afzonderlijke sessie (doel) waaraan het foutopsporingsprogramma is gekoppeld (live gebruikersmodus, KD, enzovoort...)
Debugger.Models.Processes: de lijst met processen binnen een sessie
Debugger.Models.Threads: de lijst met threads binnen een proces
Debugger.Models.Thread: een afzonderlijke thread binnen een proces (ongeacht of de gebruikers- of kernelmodus)
Debugger.Models.Stack: De stack van een thread
Debugger.Models.StackFrames: de verzameling frames waaruit een stack bestaat
Debugger.Models.StackFrame: een afzonderlijk stackframe binnen een stack
Debugger.Models.LocalVariables: de lokale variabelen binnen een stackframe
Debugger.Models.Parameters: de parameters voor een aanroep binnen een stackframe
Debugger.Models.Module: een afzonderlijke module binnen de adresruimte van een proces
Aanvullende gegevensmodelobjecten
Daarnaast zijn er enkele aanvullende gegevensmodelobjecten die worden gedefinieerd door het kerngegevensmodel.
DataModel.Models.Intrinsiek: Een intrinsieke waarde (ordinale waarden, floatgetallen, enzovoort)
DataModel.Models.String: een tekenreeks
DataModel.Models.Array: een systeemeigen matrix
DataModel.Models.Guid: een GUID
DataModel.Models.Error: een foutobject
DataModel.Models.Concepts.Iterable: Toegepast op elk object dat kan worden herhaald
DataModel.Models.Concepts.StringDisplayable: Toegepast op elk object met een weergavetekenreeksconversie
Overzicht van de COM-debugger-objectextensie
Laten we eens kijken naar een voorbeeld. Stel dat u een foutopsporingsprogramma-extensie wilt maken om informatie weer te geven die specifiek is voor COM, zoals de algemene interfacetabel (GIT).
In het verleden is er mogelijk een bestaande foutopsporingsprogramma-extensie met een aantal opdrachten die een middel bieden om toegang te krijgen tot zaken over COM. Met één opdracht kan procesgerichte informatie worden weergegeven (bijvoorbeeld de algemene interfacetabel). Een andere opdracht kan threadgerichte informatie bieden, zoals binnen welke appartementscode er wordt uitgevoerd. Mogelijk moet u meer weten over en een tweede foutopsporingsprogramma-extensie laden om andere aspecten van COM te verkennen.
In plaats van een set moeilijk te detecteren opdrachten, kan een JavaScript-extensie het concept van het foutopsporingsprogramma wijzigen van wat een proces en een thread is, om deze informatie toe te voegen op een manier die natuurlijk, verkennend en composeerbaar is met andere foutopsporingsprogramma-extensies.
Objectextensie voor foutopsporingsprogramma in de gebruikers- of kernelmodus
Het foutopsporingsprogramma en de foutopsporingsprogrammaobjecten hebben een ander gedrag in de gebruikers- en kernelmodus. Wanneer u uw foutopsporingsprogrammamodelobjecten maakt, moet u bepalen in welke omgevingen u gaat werken. Omdat we met COM werken in de gebruikersmodus, maken en testen we deze com-extensie in de gebruikersmodus. In andere situaties kunt u mogelijk een foutopsporingsprogramma in JavaScript maken dat werkt in foutopsporing in zowel de gebruikers- als kernelmodus.
Een subnaamruimte maken
Als we teruggaan naar ons voorbeeld, kunnen we een prototype of ES6-klasse definiëren, comProcessExtension die de set dingen bevat die we aan een procesobject willen toevoegen.
Belangrijk De intentie met de subnaamruimte is het maken van een logisch gestructureerd en natuurlijk doorzoekbaar paradigma. Vermijd bijvoorbeeld het dumpen van niet-gerelateerde items in dezelfde subnaamruimte. Bekijk zorgvuldig de informatie die wordt besproken in systeemeigen foutopsporingsprogrammaobjecten in JavaScript Extensions - Ontwerp- en testoverwegingen voordat u een subnaamruimte maakt.
In dit codefragment voegen we een subnaamruimte genaamd 'COM' toe op het bestaande foutopsporingsobject voor processen.
var comProcessExtension =
{
//
// Add a sub-namespace called 'COM' on process.
//
get COM()
{
//
// What is 'this' below...? It's the debugger's process object. Yes -- this means that there is a cross-language
// object hierarchy here. A C++ object implemented in the debugger has a parent model (prototype) which is
// implemented in JavaScript.
//
return new comNamespace(this);
}
}
Naamruimte-implementatie
Maak vervolgens het object dat de subnaamruimte COM implementeert op een proces.
Belangrijk Er kunnen meerdere processen zijn (gekoppeld aan dergelijke processen in de gebruikersmodus of onder KD). Deze extensie kan niet aannemen dat de huidige status van het foutopsporingsprogramma de bedoeling is van de gebruiker. Iemand kan <someProcess>.COM in een variabele vastleggen en wijzigen, wat kan leiden tot het presenteren van informatie uit de verkeerde procescontext. De oplossing is het toevoegen van code in de extensie, zodat elke instantie bijhoudt aan welk proces het is gekoppeld. Voor dit codevoorbeeld wordt deze informatie doorgegeven via de aanwijzer 'deze' van de eigenschap.
this.__process = process;
class comNamespace
{
constructor(process)
{
//
// This is an entirely JavaScript object. Each instantiation of a comNamespace will keep track
// of what process it is attached to (passed via the ''this'' pointer of the property getter
// we authored above.
//
this.__process = process;
}
get GlobalObjects()
{
return new globalObjects(this.__process);
}
}
Implementatielogica voor de algemene com-interfacetabel
Om de implementatielogica voor de COM Global Interface Table duidelijker te scheiden, definiëren we een ES6-klasse, gipTable, die de COM GIP-tabel abstraheert, en een andere klasse, globalObjects, die wordt geretourneerd door de GlobalObjects()-getter die is gedefinieerd in het hierboven getoonde codefragment van de Namespace Implementatie. Al deze details kunnen worden verborgen in de sluiting van initializeScript om te voorkomen dat u een van deze interne gegevens publiceert in de naamruimte van het foutopsporingsprogramma.
// gipTable:
//
// Internal class which abstracts away the GIP Table. It iterates objects of the form
// {entry : GIPEntry, cookie : GIT cookie}
//
class gipTable
{
constructor(gipProcess)
{
//
// Windows 8 through certain builds of Windows 10, it's in CGIPTable::_palloc. In certain builds
// of Windows 10 and later, this has been moved to GIPEntry::_palloc. We need to check which.
//
var gipAllocator = undefined;
try
{
gipAllocator = host.getModuleSymbol("combase.dll", "CGIPTable::_palloc", "CPageAllocator", gipProcess)._pgalloc;
}
catch(err)
{
}
if (gipAllocator == undefined)
{
gipAllocator = host.getModuleSymbol("combase.dll", "GIPEntry::_palloc", "CPageAllocator", gipProcess)._pgalloc;
}
this.__data = {
process : gipProcess,
allocator : gipAllocator,
pageList : gipAllocator._pPageListStart,
pageCount : gipAllocator._cPages,
entriesPerPage : gipAllocator._cEntriesPerPage,
bytesPerEntry : gipAllocator._cbPerEntry,
PAGESHIFT : 16,
PAGEMASK : 0x0000FFFF,
SEQNOMASK : 0xFF00
};
}
*[Symbol.iterator]()
{
for (var pageNum = 0; pageNum < this.__data.pageCount; ++pageNum)
{
var page = this.__data.pageList[pageNum];
for (var entryNum = 0; entryNum < this.__data.entriesPerPage; ++entryNum)
{
var entryAddress = page.address.add(this.__data.bytesPerEntry * entryNum);
var gipEntry = host.createPointerObject(entryAddress, "combase.dll", "GIPEntry *", this.__data.process);
if (gipEntry.cUsage != -1 && gipEntry.dwType != 0)
{
yield {entry : gipEntry, cookie : (gipEntry.dwSeqNo | (pageNum << this.__data.PAGESHIFT) | entryNum)};
}
}
}
}
entryFromCookie(cookie)
{
var sequenceNo = (cookie & this.__data.SEQNOMASK);
cookie = cookie & ~sequenceNo;
var pageNum = (cookie >> this.__data.PAGESHIFT);
if (pageNum < this.__data.pageCount)
{
var page = this.__data.pageList[pageNum];
var entryNum = (cookie & this.__data.PAGEMASK);
if (entryNum < this.__data.entriesPerPage)
{
var entryAddress = page.address.add(this.__data.bytesPerEntry * entryNum);
var gipEntry = host.createPointerObject(entryAddress, "combase.dll", "GIPEntry *", this.__data.process);
if (gipEntry.cUsage != -1 && gipEntry.dwType != 0 && gipEntry.dwSeqNo == sequenceNo)
{
return {entry : gipEntry, cookie : (gipEntry.dwSeqNo | (pageNum << this.__data.PAGESHIFT) | entryNum)};
}
}
}
//
// If this exception flows back to C/C++, it will be a failed HRESULT (according to the type of error -- here E_BOUNDS)
// with the message being encapsulated by an error object.
//
throw new RangeError("Unable to find specified value");
}
}
// globalObjects:
//
// The class which presents how we want the GIP table to look to the data model. It iterates the actual objects
// in the GIP table indexed by their cookie.
//
class globalObjects
{
constructor(process)
{
this.__gipTable = new gipTable(process);
}
*[Symbol.iterator]()
{
for (var gipCombo of this.__gipTable)
{
yield new host.indexedValue(gipCombo.entry.pUnk, [gipCombo.cookie]);
}
}
getDimensionality()
{
return 1;
}
getValueAt(cookie)
{
return this.__gipTable.entryFromCookie(cookie).entry.pUnk;
}
}
Gebruik tot slot host.namedModelRegistration om de nieuwe COM-functionaliteit te registreren.
function initializeScript()
{
return [new host.namedModelParent(comProcessExtension, "Debugger.Models.Process"),
new host.namedModelRegistration(comNamespace, "Debugger.Models.ComProcess")];
}
Sla de code op in GipTableAbstractor.js met behulp van een programma zoals kladblok.
Hier vindt u de procesinformatie die beschikbaar is in de gebruikersmodus voordat u deze extensie laadt.
0:000:x86> dx @$curprocess
@$curprocess : DataBinding.exe
Name : DataBinding.exe
Id : 0x1b9c
Threads
Modules
Laad de JavaScript-extensie.
0:000:x86> .scriptload C:\JSExtensions\GipTableAbstractor.js
JavaScript script successfully loaded from 'C:\JSExtensions\GipTableAbstractor.js'
Gebruik vervolgens de dx-opdracht om informatie over het proces weer te geven met behulp van de vooraf gedefinieerde @$curprocess.
0:000:x86> dx @$curprocess
@$curprocess : DataBinding.exe
Name : DataBinding.exe
Id : 0x1b9c
Threads
Modules
COM : [object Object]
0:000:x86> dx @$curprocess.COM
@$curprocess.COM : [object Object]
GlobalObjects : [object Object]
0:000:x86> dx @$curprocess.COM.GlobalObjects
@$curprocess.COM.GlobalObjects : [object Object]
[0x100] : 0x12f4fb0 [Type: IUnknown *]
[0x201] : 0x37cfc50 [Type: IUnknown *]
[0x302] : 0x37ea910 [Type: IUnknown *]
[0x403] : 0x37fcfe0 [Type: IUnknown *]
[0x504] : 0x12fe1d0 [Type: IUnknown *]
[0x605] : 0x59f04e8 [Type: IUnknown *]
[0x706] : 0x59f0eb8 [Type: IUnknown *]
[0x807] : 0x59f5550 [Type: IUnknown *]
[0x908] : 0x12fe340 [Type: IUnknown *]
[0xa09] : 0x5afcb58 [Type: IUnknown *]
Deze tabel is ook programmatisch toegankelijk via GIT-cookies.
0:000:x86> dx @$curprocess.COM.GlobalObjects[0xa09]
@$curprocess.COM.GlobalObjects[0xa09] : 0x5afcb58 [Type: IUnknown *]
[+0x00c] __abi_reference_count [Type: __abi_FTMWeakRefData]
[+0x014] __capture [Type: Platform::Details::__abi_CapturePtr]
Objectconcepten voor foutopsporingsprogramma uitbreiden met LINQ
Naast het kunnen uitbreiden van objecten zoals proces en thread, kan JavaScript ook concepten uitbreiden die zijn gekoppeld aan het gegevensmodel. Het is bijvoorbeeld mogelijk om een nieuwe LINQ-methode toe te voegen aan elke iterable. Bekijk een voorbeeldextensie: DuplicateDataModel, waarmee elke vermelding in een iterable N-tijden wordt gedupliceerd. De volgende code laat zien hoe dit kan worden geïmplementeerd.
function initializeScript()
{
var newLinqMethod =
{
Duplicate : function *(n)
{
for (var val of this)
{
for (var i = 0; i < n; ++i)
{
yield val;
}
};
}
};
return [new host.namedModelParent(newLinqMethod, "DataModel.Models.Concepts.Iterable")];
}
Sla de code op in DuplicateDataModel.js met behulp van een gebruikersprogramma zoals Notepad.
Laad indien nodig de JavaScript-scriptprovider en laad vervolgens de DuplicateDataModel.js-extensie.
0:000:x86> !load jsprovider.dll
0:000:x86> .scriptload C:\JSExtensions\DuplicateDataModel.js
JavaScript script successfully loaded from 'C:\JSExtensions\DuplicateDataModel.js'
Gebruik de dx-opdracht om de nieuwe functie Dupliceren te testen.
0: kd> dx -r1 Debugger.Sessions.First().Processes.First().Threads.Duplicate(2),d
Debugger.Sessions.First().Processes.First().Threads.Duplicate(2),d : [object Generator]
[0] : nt!DbgBreakPointWithStatus (fffff800`9696ca60)
[1] : nt!DbgBreakPointWithStatus (fffff800`9696ca60)
[2] : intelppm!MWaitIdle+0x18 (fffff805`0e351348)
[3] : intelppm!MWaitIdle+0x18 (fffff805`0e351348)
…
Zie ook
Systeemeigen foutopsporingsprogrammaobjecten in JavaScript-extensies - Ontwerp- en testoverwegingen