
Verwende Prolog, um Speicherabbilder und angehaltene Live-Prozesse in WinDbg zu analysieren.
Eine native WinDbg-Erweiterung für x64 und ARM64 mit einem persistenten SWI-Prolog-Worker. Sie stellt Threads, Stackframes, Symbole, geladene Module und Speicher aus einem User-Mode-Dump oder einem angehaltenen nativen x64- oder ARM64-Prozess bereit. Laden Sie Ihre eigenen Prolog-Dateien und führen Sie Abfragen aus dem Debugger-Befehlsfenster aus.
Version: 0.2.0 (experimentell; native ARM64-Unterstützung).
Verwenden Sie die DLL, die für die Architektur Ihres Debuggers erstellt wurde. Debugger, DLL und natives Ziel müssen übereinstimmen: x64/AMD64 zusammen oder ARM64 zusammen. Architekturübergreifende Scope-Kontexte, WOW64, ARM32 und ARM64EC-Ziele liegen außerhalb des Umfangs dieser Version. Die nativen x64- und ARM64-Builds haben alle 99 portablen Prüfungen sowie CDB-Dump-/Live-Smoke-Tests bestanden. Siehe docs/VALIDATION.md für den Lauf, die Protokolle und verbleibende manuelle Prüfungen.
Das Quell-Repository enthält keine kompilierten Binärdateien. Erstellen Sie es mit den untenstehenden Windows-Anweisungen, um dist/x64/ oder dist/arm64/ zu befüllen. Release-Archive heißen PrologWinDbg-v0.2.0-win-x64.zip und PrologWinDbg-v0.2.0-win-arm64.zip; jedes legt seine ausgewählten Binärdateien in dist/ ab. Die folgenden Beispiele verwenden dieses Layout des Release-Archivs. Ersetzen Sie bei einem Quell-Build in den Pfaden dist/arm64 oder dist/x64.
Installieren Sie die Windows-Konsolenversion von SWI-Prolog. Native ARM64-Installer sind über die Entwicklungs-Downloads verfügbar. Die CI-Matrix verwendet natives SWI-Prolog 10.1.18-1 auf beiden Architekturen. SWI läuft als separater Prozess; es ist nicht in die DLL eingebunden oder mit ihr gebündelt.
Halten Sie dist/prolog.dll zusammen
mit den Verzeichnissen dist/prolog und dist/examples.
Öffnen Sie einen nativen User-Mode-Dump im passenden x64- oder ARM64-WinDbg, oder hängen Sie sich an einen nativen Prozess dieser Architektur an und unterbrechen Sie ihn. Für einen reproduzierbaren Dump führen Sie dies in PowerShell aus:
.\dist\prologdbg_target.exe --dump C:\Temp\prologdbg-sample.dmp
Ersetzen Sie in WinDbg diese Pfade durch Ihr tatsächliches Projektverzeichnis. Verwenden Sie Schrägstriche in Pfaden in Anführungszeichen: Der Debugger behandelt Backslashes als Escape-Zeichen.
.load C:/PrologWinDbg/dist/prolog.dll
!prolog.runtime "C:/Program Files/swipl/bin/swipl.exe"
!prolog.info
!prolog.consult "C:/PrologWinDbg/dist/examples/patterns.pl"
!prolog.query wd:current_snapshot(S), wd:architecture(S,Architecture).
!prolog.query wd:current_snapshot(S), wd:thread_id(S,T,WindowsTid).
!prolog.query wd:current_snapshot(S), wd:stack_frame(S,T,Depth,IP).
!prolog.query wd:current_snapshot(S), patterns:stack_contains(S,T,Module,Function).
Die Erweiterung verwendet den expliziten Laufzeitpfad, die Umgebungsvariable PROLOGDBG_SWIPL oder die Standardinstallation Program Files\swipl\bin\swipl.exe. Sie startet den Worker, sobald er erstmals benötigt wird. Die gesamte Kommunikation erfolgt über lokale Pipes.
Für das bereitgestellte Ziel den bekannten Acht-Byte-Marker untersuchen:
!prolog.query wd:current_snapshot(S), wd:lookup(S,'prologdbg_target!g_magic',ok(A)), patterns:inspect_magic(S,A,Verdict).
Erwartetes Ergebnis: matched(prologdb, Address). Die Marker-Bytes ergeben
PROLOGDB. Das Ziel exportiert diese Namen, daher benötigt dieses Beispiel kein
PDB. Private PDBs sind für andere Funktionen und Anwendungen nützlich.
Starten Sie prologdbg_target.exe --live unter WinDbg. Fahren Sie über den
anfänglichen Loader-Breakpoint hinaus fort. Das Ziel bricht dann bei
CapturePoint ab, nachdem zwei Worker-Threads gestartet wurden. Verwenden Sie
dieselben Abfragen wie für einen Dump.
Alternativ können Sie prologdbg_target.exe --wait ausführen, sich an die
ausgegebene PID anhängen und einbrechen. Dieser Modus beendet sich nach zehn
Minuten, wenn er nicht vorher gestoppt wird.
Verwenden Sie die normalen WinDbg-Befehle bp, g, p und t, um die
Ausführung zu steuern. Jede !prolog.query sammelt einen frischen Snapshot.
Registrierte Prolog-Breakpoint-Aktionen und automatische Fortsetzung sind für
eine spätere Version geplant.
| Befehl | Zweck |
|---|---|
!prolog.help | Befehls Hilfe anzeigen |
!prolog.runtime "absolute path to swipl.exe" | Laufzeit auswählen und einen vorhandenen Worker stoppen |
!prolog.info | Den Worker starten und seine Version melden |
!prolog.consult "absolute path to rules.pl" | Prolog-Quellcode laden oder neu laden |
!prolog.query Goal. | Beweise sammeln und Lösungen aufzählen |
!prolog.queryfile "absolute path to goal.txt" | Ein einzelnes UTF-8-Ziel aus einer Datei lesen und dann abfragen |
!prolog.eval Goal. | Prolog ohne Debugger-Beweise auswerten |
!prolog.limits | Aktuelle Limits anzeigen |
!prolog.limits 5000 100 128 10000000 | Millisekunden, Antwortanzahl, Frames pro Thread und Inferenzlimit festlegen |
!prolog.reset | Den Worker stoppen; geladene Regeln und benutzerdefinierter Laufzeitzustand gehen verloren |
Einfache Ziele werden direkt nach dem Befehl übergeben. Standard-Prolog-
einfache Anführungszeichen begrenzen Atome. Sie können den abschließenden Punkt
weglassen. Verwenden Sie ein Ziel pro Befehl und verbinden Sie Unterziele mit
Kommas. Für die Prolog-Disjunktion (;) schließen Sie das gesamte Ziel in
doppelte Anführungszeichen ein, um es vor dem Befehlstrennzeichen von WinDbg zu
schützen:
!prolog.eval "(X=a;X=b), writeln(X)."
Für komplexe Quotierung, Unicode-Text oder mehrzeilige Ziele legen Sie das Ziel in einer UTF-8-Textdatei ab und verwenden Sie !prolog.queryfile "C:/rules/goal.txt". Deren Inhalt geht direkt an Prolog und umgeht die Befehls-Textanalyse von WinDbg. Das Dateilimit beträgt 1 MiB. Für wiederverwendbare Logik definieren Sie Prädikate in einer konsultierten .pl-Datei.
Beispiel ohne Ziel:
!prolog.eval member(X,[1,2,3]), Y is X*X.
Antworten werden als bindings([Name=Value, ...], ResidualGoals) ausgegeben. Die zweite
Liste bewahrt verbleibende Einschränkungen. Ein abschließender Status unterscheidet
erschöpfte Suche, Fehlschlag, Antwortlimits, Inferenzlimits, Timeouts und Ausnahmen.
Das Erreichen eines Antwortlimits bedeutet nicht, dass weitere Lösungen existieren.
Das Konsultieren einer Datei führt zum normalen Prolog-Laden und zur Initialisierung. Ladefehler werden gemeldet, aber das Prolog-Laden ist nicht transaktional: Einige Klauseln können vor einem Fehler geladen worden sein. Korrigieren und laden Sie die Datei neu, oder setzen Sie den Worker zurück.
:- module(my_rules, [in_function/4]).
:- use_module('C:/PrologWinDbg/dist/prolog/wd.pl').
in_function(S, T, Module, Function) :-
wd:stack_frame(S, T, _, IP),
wd:symbol(S, IP, Module, Function, _).
Dann:
!prolog.consult "C:/rules/my_rules.pl"
!prolog.query wd:current_snapshot(S), my_rules:in_function(S,T,myapp,'ProcessRequest').
Siehe docs/API.md für Prädikatmodi und Evidenzsemantik. Die anfänglichen
Regeln bieten Stack-Matching, gemeinsam genutzte Funktionen über Threads hinweg, explizite Stack-
Evidenz, nicht lesbare Adressen und eine Speichersignatur-Diagnose mit einem
unschlüssigen Ergebnis.
Das Standard-Abfragebudget beträgt 5 Sekunden, 100 Antworten, 128 Frames pro Thread und
10 Millionen Inferenzen. Die Snapshot-Erfassung erhält ihr eigenes Zeitbudget derselben
Größe. Das anfängliche Laden von Symbolen kann langsam sein: Wärmen Sie den Symbol-Cache vor oder erhöhen Sie
den ersten Wert mit !prolog.limits.