Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Gli alias di funzione sono un nome breve univoco in base al quale un utente del debugger può accedere alle funzionalità definite in un'estensione del debugger (scritte in C++ o in un ambiente di scripting, ad esempio JavaScript). Questo nome breve viene associato a un oggetto funzione del modello di dati (oggetto che implementa IModelMethod). Tale funzione accetta un numero arbitrario di argomenti e restituisce un singolo valore. L'effetto della chiamata di un alias di funzione e delle operazioni eseguite con tale valore dipende dal modo in cui viene richiamato l'alias della funzione e dal debugger host in cui viene richiamato.
In questo argomento si presuppone che il lettore abbia familiarità con il modello a oggetti del debugger e JavaScript. Per informazioni sull'uso di oggetti debugger con JavaScript, vedere oggetti debugger nativi nelle estensioni JavaScript.
Alcuni degli esempi illustrati di seguito usano il comando dx, per altre informazioni sull'uso del comando dx, vedere dx (Display Debugger Object Model Expression). Viene inoltre usato LINQ, descritto in Using LINQ With the debugger objects.
Uso dell'alias di funzione come comandi di estensione
Tutti gli alias di funzione creati in WinDbg possono essere richiamati come se fossero estensioni di debug ! comandi "bang". Se la funzione non accetta argomenti, richiamando semplicemente !aliasName, la funzione verrà chiamata e verrà visualizzato il valore del risultato. Ad esempio (creato con estendibilità JavaScript)
Ad esempio, questa funzione fornisce due valori costanti, pi e e.
function __constants()
{
return { math_constants : { pi : 3.1415926535 , e : 2.7182818284}, description : "Archimedes' pi and Euler's number e" };
}
function initializeScript()
{
return [new host.functionAlias(__constants, "constants")];
}
I risultati della chiamata dell'alias della funzione sono visualizzati qui.
0:000> !constants
@$constants() : [object Object]
math_constants : [object Object]
description : Archimedes' pi and Euler's number e
I collegamenti DML a oggetti complessi verranno generati automaticamente. Facendo clic sul math_constants illustrato in precedenza, verrà restituito l'output seguente.
0:000> dx -r1 @$constants().math_constants
@$constants().math_constants : [object Object]
pi : 3.141593
e : 2.718282
Se la funzione ha argomenti, possono essere forniti dopo il comando alias della funzione stessa. Si noti che ciò che accade dopo il comando alias della funzione viene considerato un'espressione e viene valutato come tale. La stringa di testo non viene passata direttamente alla funzione. Per un'espressione di argomento singolo, può venire dopo il comando alias della funzione stesso. Per più argomenti, devono essere racchiusi tra parentesi come se fosse una chiamata di funzione, come illustrato in questo esempio successivo.
function __oneArgument(x)
{
return -x;
}
function __twoArguments(x, y)
{
return x + y;
}
function initializeScript()
{
return [new host.functionAlias(__oneArgument, "neg"),
new host.functionAlias(__twoArguments, "add")];
}
Queste due funzioni possono essere chiamate come illustrato di seguito.
0:000> !neg 42
@$neg(42) : -42
0:000> !add (5, 7)
@$add(5, 7) : 0xc
Uso dell'alias di funzione con l'analizzatore di espressioni dx
Oltre all'estensione di debug ! sintassi del comando "bang" per richiamare una funzione con alias, tutti i nomi associati agli alias di funzione sono direttamente disponibili nell'analizzatore di espressioni dx quando è preceduto da @$ come illustrato di seguito.
0:000> dx @$neg(42)
@$neg(42) : -42
0:000> dx @$add(99, 77)
@$add(99, 77) : 0xb0
Considerazioni sulla progettazione degli alias di funzione
Un alias di funzione non deve mai essere l'unico modo in cui viene esposta la funzionalità nella maggior parte delle estensioni del modello di dati. Un'estensione del modello di dati (sia in C++ o JavaScript) deve includere quasi sempre i dati esposti associato a un tipo o a un altro concetto di debugger. Gli elementi associati ai processi devono trovarsi in Debugger.Models.Process o in uno spazio dei nomi secondario di tale oggetto. Un alias di funzione può essere un modo pratico per ottenere (o trasformare) dati che potrebbero richiedere una query significativamente più lunga.
Come esempio di modalità kernel, la query seguente accetta l'albero dei dispositivi PnP e lo appiattisce in un semplice elenco semplice di dispositivi:
0: kd> dx @$cursession.Devices.DeviceTree.Flatten(n => n.Children),5
@$cursession.Devices.DeviceTree.Flatten(n => n.Children),5
[0x0] : HTREE\ROOT\0
[0x1] : ROOT\volmgr\0000 (volmgr)
[0x2] : ROOT\BasicDisplay\0000 (BasicDisplay)
[0x3] : ROOT\CompositeBus\0000 (CompositeBus)
[0x4] : ROOT\vdrvroot\0000 (vdrvroot)
[...]
Questo codice JavaScript mostra come può essere implementato come alias di funzione.
function __flatDevices()
{
return host.currentSession.Devices.DeviceTree.Flatten(n => n.Children);
}
function initializeScript()
{
return [new host.functionAlias(__flatDevices, "devices")];
}
L'alias della funzione può quindi essere richiamato come comando di estensione di debug.
0: kd> !devices
@$devices()
[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)
...
Uno dei vantaggi dell'uso di un alias di funzione è che può essere ulteriormente perfezionato usando la sintassi dx. In questo esempio viene aggiunta una clausola where per cercare i nodi del dispositivo che contengono "Harddisk".
0: kd> dx @$devices().Where(n => n.InstancePath.Contains("Harddisk"))
@$devices().Where(n => n.InstancePath.Contains("Harddisk"))
[0x0] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot1
[0x1] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot2
[0x2] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot3
[0x3] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot4
[0x4] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot5
[0x5] : STORAGE\VolumeSnapshot\HarddiskVolumeSnapshot6
I comandi LINQ, ad esempio i seguenti, possono essere usati con alias funzionali - . Tutto. Qualunque. Contare. Primo. Appiattire. GroupBy, . Ultimo. OrderBy, . OrderByDescending, . Selezionare e . Dove. Questi metodi seguono (il più possibile) il modulo del metodo LINQ C#. Per altre informazioni, vedere Using LINQ With the debugger objects.
visualizzazione griglia
Come con altri comandi dx, è possibile fare clic con il pulsante destro del mouse su un comando dopo l'esecuzione e fare clic su "Visualizza come griglia" o aggiungere "-g" al comando per ottenere una visualizzazione griglia dei risultati. È quindi possibile fare clic su qualsiasi colonna da ordinare, ad esempio su InstancePath.
0: kd> dx -g @$devices().OrderBy(obj => obj.@"InstancePath")
Esempio di thread di elaborazione
Gli oggetti debugger vengono proiettati in uno spazio dei nomi rooted in "Debugger". I processi, i moduli, i thread, gli stack, gli stack frame e le variabili locali sono tutti disponibili per l'uso in una query LINQ.
In questo esempio JavaScript viene illustrato come visualizzare il numero di thread per i processi delle sessioni correnti:
function __Processes()
{
return host.currentSession.Processes.Select(p => ({Name: p.Name, ThreadCount: p.Threads.Count()}));
}
function initializeScript()
{
return [new host.functionAlias(__Processes, "Processes")];
}
Viene illustrato l'output di esempio con ! Elabora l'alias della funzione.
0: kd> !Processes
@$Processes()
[0x0] : [object Object]
[0x4] : [object Object]
[0x1b4] : [object Object]
[0x248] : [object Object]
[0x2c4] : [object Object]
[0x340] : [object Object]
[0x350] : [object Object]
[0x3d4] : [object Object]
[0x3e8] : [object Object]
[0x4c] : [object Object]
[0x214] : [object Object]
[0x41c] : [object Object]
[0x494] : [object Object]
...
In questo esempio vengono visualizzati i primi 5 processi con il numero massimo di thread.
0: kd> dx -r1 @$Processes().OrderByDescending(p =>p.ThreadCount),5
@$Processes().OrderByDescending(p =>p.ThreadCount),5
[0x4] : [object Object]
[0x180] : [object Object]
[0x978] : [object Object]
[0xda4] : [object Object]
[0x3e8] : [object Object]
[...]
Vedere anche
dx (Display Debugger Object Model Expression)
Uso di LINQ con gli oggetti del debugger
oggetti debugger nativi in NatVis
oggetti debugger nativi nelle estensioni JavaScript