Épisode

Outils de défragmentation #170 - Débogueur - Script JavaScript

Dans cet épisode de Defrag Tools, Andrew Richards parle à Andy Luhrs et Bill Messmer de l’équipe Débogage Tools pour Windows. Nous parlons des nouvelles capacités d’extensibilité et de script JavaScript dans WinDbg disponibles dans la build WDK et SDK 14951 et versions ultérieures.

Bill a utilisé le modèle objet du débogueur précédemment dans ces épisodes :

Chronologie :

[00 :00] Bienvenue et introductions
[00 :24] Nouvelle suppression du Kit de développement logiciel (SDK)
[00 :29] Pourquoi JavaScript
[02 :07] Nouvelles commandes
[03 :50] Visual Studio Code
Exemple [04 :00] - Hello World
[07 :15] Espaces de noms par défaut du débogueur
[09 :07] Exemple - Imprimer tous les threads
[10 :26] Exemple : point d’arrêt conditionnel
[18 :13] 'g' vs. 'gc' – Andrew a raison ! 'gc' reprend l’exécution de la même façon qu’elle a démarré. Par conséquent, si vous appuyez sur « p », puis appuyez sur un point d’arrêt conditionnel qui a « gc » dans celui-ci, le « gc » termine simplement votre « p » initial.
[20 :40] Exemple - Piles uniques
[34 :40] Exemple - Ajout

Questions/commentaires ? Envoyez-nous un e-mail à l’adresse defragtools@microsoft.com

Documentation MSDN JavaScript :

Exemple de piles uniques (exemple de pile unique) :

« utiliser strict » ;

classe __stackEntry { constructor(frameString) { this.threads = [] ; this.frameString = frameString ; this.children = new Map() ; }

display(indent) 
{
    for (var child of this.children.values())
    {
        host.diagnostics.debugLog(indent, child.frameString, " [Threads In Branch: ");
        for (var thread of child.threads)
        {
            host.diagnostics.debugLog(thread.Id, " ");
        }
        host.diagnostics.debugLog("]\n");
        child.display(indent + "    ");
    }
}

}

class __stackMap { constructor(process) { this.__process = process ; this.__root = new __stackEntry(«  ») ; this.build() ; }

build()
{
    for (var thread of this.__process.Threads)
    {
        var current = this.__root;
        var frameNum = 0;

        var frameCount = thread.Stack.Frames.Count();
        for (var frameNum = frameCount - 1; frameNum >= 0; --frameNum) {
            var frame = thread.Stack.Frames[frameNum];
            var frameString = frame.toString();
            if (current.children.has(frameString)) {
                current = current.children.get(frameString);
                current.threads.push(thread);
            }
            else {
                var newEntry = new __stackEntry(frameString);
                current.children.set(frameString, newEntry);
                current = newEntry;
                current.threads.push(thread);
            }
        }
    }
}

findEntry(thread)
{
    var current = this.__root;
    var frameCount = thread.Stack.Frames.Count();
    for (var frameNum = frameCount - 1; frameNum >= 0; --frameNum)
    {
        var frame = thread.Stack.Frames[frameNum];
        var frameString = frame.toString();
        if (!current.children.has(frameString))
        {
            return null;
        }
        current = current.children.get(frameString);
    }
    return current;
}

display()
{
    this.__root.display("");
}

}

classe __threadSameStacks { constructeur(thread) { this.__thread = thread ; }

getDimensionality()
{
    return 1;
}

getValueAt(idx)
{
    for (var idxVal of this)
    {
        var tid = idxVal[Symbol.indicies][0];
        if (idxVal[Symbol.indicies][0] == idx && tid != this.__thread.Id)
        {
            return idxVal.value;
        }
    }
    return undefined;
}

*[Symbol.iterator]()
{
    var context = this.__thread.hostContext;
    var session = host.namespace.Debugger.Sessions.getValueAt(context);
    var process = session.Processes.getValueAt(context);
    var map = new __stackMap(process);
    var entry = map.findEntry(this.__thread);
    if (entry != null)
    {
        for (var sharingThread of entry.threads)
        {
            if (sharingThread.Id != this.__thread.Id)
            {
                yield new host.indexedValue(sharingThread, [sharingThread.Id]);
            }
        }
    }
}

}

class __threadExtension { get IdenticalStacks() { return new __threadSameStacks(this) ; } }

function invokeScript() { var map = new __stackMap(host.currentProcess) ; map.display() ; }

function initializeScript() { return [new host.namedModelParent(__threadExtension, « Debugger.Models.Thread »)] ; }