bp, bu, bm (Set Breakpoint)
Die Befehle "bp", "bu" und "bm" legen einen oder mehrere Software-Haltepunkte fest. Sie können Standorte, Bedingungen und Optionen kombinieren, um verschiedene Arten von Software-Haltepunkten festzulegen.
Benutzermodus
[~Thread] bp[ID] [Options] [Address [Passes]] ["CommandString"]
[~Thread] bu[ID] [Options] [Address [Passes]] ["CommandString"]
[~Thread] bm [Options] SymbolPattern [Passes] ["CommandString"]
Kernelmodus
bp[ID] [Options] [Address [Passes]] ["CommandString"]
bu[ID] [Options] [Address [Passes]] ["CommandString"]
bm [Options] SymbolPattern [Passes] ["CommandString"]
Parameter
Faden
Gibt den Thread an, auf den der Haltepunkt angewendet wird. Weitere Informationen über die Syntax finden Sie unter Thread-Syntax. Sie können Threads nur im Benutzermodus angeben. Wenn Sie keinen Thread angeben, gilt der Haltepunkt für alle Threads.
ID
Gibt eine Dezimalzahl an, die einen Haltepunkt identifiziert.
Der Debugger weist die ID zu, wenn er den Haltepunkt erstellt, aber Sie können sie mithilfe des Befehls br (Breakpoint Renumber) ändern. Sie können die ID verwenden, um auf den Haltepunkt in späteren Debuggerbefehlen zu verweisen. Um die ID eines Haltepunkts anzuzeigen, verwenden Sie den Befehl bl (Haltepunktliste).
Wenn Sie die ID in einem Befehl verwenden, geben Sie kein Leerzeichen zwischen dem Befehl (bp oder bu) und der ID-Nummer ein.
Der ID-Parameter ist immer optional. Wenn Sie keine ID angeben, verwendet der Debugger die erste verfügbare Haltepunktnummer. Im Kernelmodus können Sie nur 32 Haltepunkte festlegen. Im Benutzermodus können Sie eine beliebige Anzahl von Haltepunkten festlegen. In beiden Fällen gibt es keine Einschränkung für den Wert der ID-Nummer . Wenn Sie die ID in eckige Klammern ([]) einschließen, kann die ID einen beliebigen Ausdruck enthalten. Weitere Informationen zur Syntax finden Sie unter Numerische Ausdruckssyntax.
Optionen Gibt die Haltepunktoptionen an. Sie können eine beliebige Anzahl der folgenden Optionen angeben, mit Ausnahme der angegebenen:
/1
Erstellt einen "einmaligen" Haltepunkt. Nachdem dieser Haltepunkt ausgelöst wurde, wird er aus der Haltepunktliste gelöscht.
/p EProcess
(Nur Kernelmodus) Gibt einen Prozess an, der diesem Haltepunkt zugeordnet ist. EProcess sollte die tatsächliche Adresse der EPROCESS-Struktur sein, nicht die PID. Der Haltepunkt wird nur ausgelöst, wenn er im Kontext dieses Prozesses auftritt.
/t EThread
(Nur Kernelmodus) Gibt einen Thread an, der diesem Haltepunkt zugeordnet ist. EThread sollte die tatsächliche Adresse der ETHREAD-Struktur sein, nicht die Thread-ID. Der Haltepunkt wird nur ausgelöst, wenn er im Kontext dieses Threads auftritt. Wenn Sie /p EProcess und /t EThread verwenden, können Sie sie in beliebiger Reihenfolge eingeben.
/c MaxCallStackDepth
Aktiviert den Haltepunkt nur, wenn die Aufrufstapeltiefe kleiner als MaxCallStackDepth ist. Sie können diese Option nicht zusammen mit /C verwenden.
/C MinCallStackDepth
Aktiviert den Haltepunkt nur, wenn die Aufrufstapeltiefe größer als MinCallStackDepth ist. Sie können diese Option nicht zusammen mit /c verwenden.
/a
(Nur für bm ) Legt Haltepunkte für alle angegebenen Speicherorte fest, unabhängig davon, ob sie sich im Datenbereich oder im Codebereich befinden. Da Haltepunkte für Daten zu Programmfehlern führen können, verwenden Sie diese Option nur für Speicherorte, die als sicher bekannt sind.
/d
(Nur für BM ) Wandelt die Haltepunktpositionen in Adressen um. Wenn der Code verschoben wird, bleiben die Haltepunkte daher an derselben Adresse, anstatt entsprechend SymbolPattern festgelegt zu werden. Verwenden Sie /d , um die Neubewertung von Änderungen an Haltepunkten zu vermeiden, wenn Module geladen oder entladen werden.
/(
(Nur für bm ) Enthält Parameterlisteninformationen in der Symbolzeichenfolge, die SymbolString definiert.
Mit diesem Feature können Sie Haltepunkte für überladene Funktionen festlegen, die denselben Namen haben, aber unterschiedliche Parameterlisten. Beispielsweise legt bm /( myFunc Haltepunkte sowohl auf myFunc(int a) als auch auf myFunc(char a). Ohne "/(", ein Haltepunkt, der für myFunc festgelegt ist, schlägt fehl, da er nicht angibt, für welche myFunc-Funktion der Haltepunkt vorgesehen ist.
/w dx-Objektausdruck Legt einen bedingten Haltepunkt basierend auf dem booleschen Wert fest, der von dx-Objektausdruck zurückgegeben wird. Bei dem Argument handelt es sich um einen Datenmodellausdruck (dx), der als wahr ausgewertet wird (Übereinstimmungsbedingung – Umbruch) oder falsch (nicht mit der Bedingung übereinstimmt – nicht umbrechen).
In diesem Beispiel wird ein bedingter Haltepunkt basierend auf dem Wert "localVariable" festgelegt.
bp /w "localVariable == 4" mymodule!myfunction
In diesem Beispiel wird gezeigt, wie Sie einen Haltepunkt mit JavaScript festlegen.
bp /w "@$scriptContents.myFunc(localVariable)" @rip
Weitere Informationen zu Debuggerobjekten finden Sie unter dx (Debugger-Objektmodellausdruck anzeigen).
Weitere Informationen zu bedingten Haltepunkten finden Sie unter Festlegen eines bedingten Haltepunkts.
Adresse
Gibt das erste Byte der Anweisung an, in dem der Haltepunkt festgelegt ist. Wenn Sie "Adresse" weglassen, wird der aktuelle Anweisungszeiger verwendet. Weitere Informationen zur Syntax finden Sie unter Address and Address Range Syntax.
Pässe
Gibt die Anzahl des Ausführungsdurchlaufs an, für den der Haltepunkt aktiviert ist. Der Debugger überspringt die Haltepunktposition, bis er den angegebenen Durchlauf erreicht. Der Wert von Pässen kann ein beliebiger 16-Bit- oder 32-Bit-Wert sein.
Standardmäßig ist der Haltepunkt aktiv, wenn die Anwendung den Code ausführt, der die Haltepunktposition enthält. Diese Standardsituation entspricht einem Wert von 1 für Pässe. Um den Haltepunkt nur zu aktivieren, nachdem die Anwendung den Code mindestens einmal ausgeführt hat, geben Sie einen Wert von 2 oder mehr ein. Beispielsweise aktiviert ein Wert von 2 den Haltepunkt beim zweiten Ausführen des Codes.
Dieser Parameter erstellt einen Zähler, der für jeden Durchlauf des Codes erhöht wird. Um die anfangs- und aktuellen Werte des Passzählers anzuzeigen, verwenden Sie bl (Haltepunktliste).
Der Passzähler wird nur erhöht, wenn die Anwendung als Reaktion auf einen G-Befehl (Gehe) über den Haltepunkt hinaus ausgeführt wird. Der Zähler wird nicht erhöht, wenn Sie den Code durchlaufen oder die Ablaufverfolgung eingefügt haben. Wenn der Passzähler 1 erreicht, können Sie ihn nur zurücksetzen, indem Sie den Haltepunkt löschen und zurücksetzen.
CommandString
Gibt eine Liste von Befehlen an, die jedes Mal ausgeführt werden, wenn der Haltepunkt die angegebene Anzahl von Malen gefunden wird. Sie müssen den CommandString-Parameter in Anführungszeichen setzen. Verwenden Sie Semikolons, um mehrere Befehle zu trennen.
Debuggerbefehle in CommandString können Parameter enthalten. Sie können standardmäßige C-Steuerzeichen (z . B. \n und \") verwenden. Semikolons, die in Anführungszeichen der zweiten Ebene (\") enthalten sind, werden als Teil der eingebetteten Zeichenfolge interpretiert.
Die CommandString-Befehle werden nur ausgeführt, wenn der Haltepunkt erreicht ist, während die Anwendung als Reaktion auf einen g (Go)-Befehl ausgeführt wird. Die Befehle werden nicht ausgeführt, wenn Sie den Code oder die Ablaufverfolgung über diesen Punkt durchlaufen.
Alle Befehle, die die Programmausführung fortsetzen, nachdem ein Haltepunkt (z . B. g oder t) die Ausführung der Befehlsliste beendet hat.
SymbolPattern
Gibt ein Muster an. Der Debugger versucht, dieses Muster mit vorhandenen Symbolen abzugleichen und Haltepunkte für alle Mustervergleiche festzulegen. SymbolPattern kann eine Vielzahl von Wildcardzeichen und Bezeichnern enthalten. Weitere Informationen zu dieser Syntax finden Sie unter String Wildcard Syntax. Da diese Zeichen mit Symbolen abgeglichen werden, wird die Groß-/Kleinschreibung nicht beachtet, und ein einzelner führender Unterstrich (_) stellt eine beliebige Menge führender Unterstriche dar.
Environment
Element | Beschreibung |
---|---|
Modi | Benutzermodus, Kernelmodus |
Targets | Nur Livedebugging |
Plattformen | Alle |
Zusätzliche Informationen
Weitere Informationen und Beispiele für die Verwendung von Haltepunkten, andere Haltepunktbefehle und Methoden zum Steuern von Haltepunkten sowie das Festlegen von Haltepunkten im Benutzerbereich aus einem Kerneldebugger finden Sie unter Verwenden von Haltepunkten. Weitere Informationen zu bedingten Haltepunkten finden Sie unter Festlegen eines bedingten Haltepunkts.
Hinweise
Die Befehle "bp", "bu" und "bm" legen neue Haltepunkte fest, weisen jedoch unterschiedliche Merkmale auf:
Der Befehl bp (Haltepunkt festlegen) legt einen neuen Haltepunkt an der Adresse der Haltepunktposition fest, die im Befehl angegeben ist. Wenn der Debugger den Adressausdruck der Haltepunktposition nicht auflösen kann, wenn der Haltepunkt festgelegt wird, wird der bp-Haltepunkt automatisch in einen Bu-Haltepunkt konvertiert. Verwenden Sie einen Bp-Befehl , um einen Haltepunkt zu erstellen, der nicht mehr aktiv ist, wenn das Modul entladen wird.
Der Befehl bu (Unresolved Breakpoint festlegen) legt einen verzögerten oder nicht aufgelösten Haltepunkt fest. Ein Bu-Haltepunkt wird auf einen symbolischen Verweis auf die Haltepunktposition festgelegt, die im Befehl angegeben ist (nicht an einer Adresse) und wird aktiviert, wenn das Modul mit dem Verweis aufgelöst wird. Weitere Informationen zu diesen Haltepunkten finden Sie unter "Unresolved Breakpoints" (bu Breakpoints).
Der Befehl bm (Set Symbol Breakpoint) legt einen neuen Haltepunkt für Symbole fest, die einem angegebenen Muster entsprechen. Dieser Befehl kann mehrere Haltepunkte erstellen. Standardmäßig sind BM-Haltepunkte nach der Übereinstimmung mit den Bu-Haltepunkten identisch. Das heißt, bm breakpoints are deferred breakpoints that are set on a symbolische reference. Ein bm /d-Befehl erstellt jedoch einen oder mehrere Bp-Haltepunkte . Jeder Haltepunkt wird für die Adresse eines übereinstimmenen Speicherorts festgelegt und verfolgt den Modulstatus nicht.
Wenn Sie nicht sicher sind, welcher Befehl zum Festlegen eines vorhandenen Haltepunkts verwendet wurde, verwenden Sie BPCMDS (Haltepunktbefehle anzeigen), um alle Haltepunkte zusammen mit den Befehlen aufzulisten, die zum Erstellen verwendet wurden.
Es gibt drei primäre Unterschiede zwischen bp-Haltepunkten und bu-Haltepunkten:
Ein bp-Haltepunkt wird immer in eine Adresse umgewandelt. Wenn eine Moduländerung den Code verschiebt, an dem ein bp-Haltepunkt festgelegt wurde, bleibt der Haltepunkt an der gleichen Adresse. Ein bu-Haltepunkt hingegen bleibt mit dem verwendeten symbolischen Wert (typischerweise ein Symbol plus ein Offset) verbunden und folgt diesem symbolischen Punkt, auch wenn sich seine Adresse ändert.
Wenn eine bp-Haltepunktadresse in einem geladenen Modul gefunden wird und dieses Modul später entladen wird, wird der Haltepunkt aus der Haltepunktliste entfernt. Andererseits bleiben bu-Haltepunkte auch nach wiederholtem Entladen und Laden bestehen.
Haltepunkte, die Sie mit bp festlegen, werden nicht in WinDbg-Arbeitsbereichen gespeichert. Haltepunkte, die mit bu festgelegt werden, werden in Arbeitsbereichen gespeichert.
Der Bm-Befehl ist nützlich, wenn Sie Im Symbolmuster für einen Haltepunkt Wildcardzeichen verwenden möchten. Die bm SymbolPattern-Syntax entspricht der Verwendung von x SymbolPattern und dann der Verwendung von bu für jedes Ergebnis. Wenn Sie beispielsweise Haltepunkte für alle Symbole im Modul "Myprogram " festlegen möchten, die mit der Zeichenfolge "mem" beginnen, verwenden Sie den folgenden Befehl.
Beispiel
0:000> bm myprogram!mem*
4: 0040d070 MyProgram!memcpy
5: 0040c560 MyProgram!memmove
6: 00408960 MyProgram!memset
Da der BM-Befehl Software-Haltepunkte (nicht Prozessor-Haltepunkte) festlegt, schließt er automatisch den Datenspeicherort aus, wenn er Haltepunkte festlegt, um zu verhindern, dass die Daten beschädigt werden.
Es ist möglich, eine Datenadresse anstelle einer Programmadresse anzugeben, wenn Sie die Befehle bp oder bm /a verwenden. Aber auch wenn eine Datenadresse angegeben wird, erstellen diese Befehle Software-Haltepunkte, keine Prozessor-Haltepunkte. Wenn ein Software-Haltepunkt in Programmdaten anstelle von ausführbarem Code platziert wird, kann er zu Datenbeschädigungen führen. Daher sollten Sie diese Befehle nur an einem Datenspeicherort verwenden, wenn Sie sicher sind, dass der in diesem Speicherort gespeicherte Speicher als ausführbarer Code und nicht als Programmdaten verwendet wird. Andernfalls sollten Sie stattdessen den Befehl ba (Break on Access) verwenden. Weitere Informationen finden Sie unter Processor Breakpoints (ba Breakpoints).For more details, see Processor Breakpoints (ba Breakpoints).
Ausführliche Informationen zum Festlegen eines Haltepunkts an einem Speicherort, der durch eine kompliziertere Syntax angegeben wird, z. B. ein Mitglied einer öffentlichen C++-Klasse, oder eine beliebige Textzeichenfolge, die andernfalls eingeschränkte Zeichen enthält, finden Sie unter Breakpoint-Syntax.
Wenn eine einzelne logische Quelllinie mehrere physische Zeilen umfasst, wird der Haltepunkt für die letzte physische Zeile der Anweisung oder des Aufrufs festgelegt. Wenn der Debugger an der angeforderten Position keinen Haltepunkt festlegen kann, wird der Haltepunkt an der nächsten zulässigen Position platziert.
Wenn Sie Thread angeben, werden Haltepunkte für die angegebenen Threads festgelegt. Beispielsweise legt der Befehl ~*bp Haltepunkte für alle Threads fest, ~#bp legt einen Haltepunkt für den Thread fest, der die aktuelle Ausnahme verursacht, und ~123bp legt einen Haltepunkt für Thread 123 fest. Die Befehle ~bp und ~.bp legen beide einen Haltepunkt für den aktuellen Thread fest.
Wenn Sie ein Multiprozessorsystem im Kernelmodus debuggen, gelten Haltepunkte, die Sie mithilfe von bp oder ba (Break on Access) für alle Prozessoren festlegen. Wenn der aktuelle Prozessor beispielsweise 3 ist und Sie bp MemoryAddress eingeben, um einen Haltepunkt an MemoryAddress zu setzen. Jeder Prozessor, der an dieser Adresse ausgeführt wird (nicht nur Prozessor 3), verursacht eine Haltepunktfalle.
Die Befehle bp, bu und bm legen Software-Haltepunkte fest, indem sie den Prozessor-Befehl durch einen Haltebefehl ersetzen. Um schreibgeschützten Code oder Code zu debuggen, der nicht geändert werden kann, verwenden Sie einen Ba e-Befehl, wobei e den schreibgeschützten Zugriff darstellt.
Mit dem folgenden Befehl wird ein Haltepunkt von 12 Bytes über den Anfang der Funktion MyTest festgelegt. Dieser Haltepunkt wird für die ersten sechs Durchläufe durch den Code ignoriert, aber die Ausführung wird beim siebten Durchlauf des Codes beendet.
0:000> bp MyTest+0xb 7
Der folgende Befehl legt einen Haltepunkt bei RtlRaiseException fest, zeigt das Eax-Register an, zeigt den Wert des Symbols MyVar an und setzt fort.
kd> bp ntdll!RtlRaiseException "r eax; dt MyVar; g"
Die folgenden beiden BM-Befehle legen drei Haltepunkte fest. Wenn die Befehle ausgeführt werden, unterscheidet das angezeigte Ergebnis nicht zwischen Haltepunkten, die mit dem Schalter /d erstellt wurden, und den erstellten. Die BPCMDS (Display Breakpoint Commands) können verwendet werden, um zwischen diesen beiden Typen zu unterscheiden. Wenn der Haltepunkt von BM ohne Schalter /d erstellt wurde, gibt die Bpcmds-Anzeige den Haltepunkttyp als bu an, gefolgt von dem ausgewerteten Symbol, das in das Token "@!"" eingeschlossen ist (was angibt, dass es sich um ein Literalsymbol handelt und kein numerischer Ausdruck oder Register). Wenn der Haltepunkt von bm mit dem Schalter "/d" erstellt wurde, gibt die Bpcmds-Anzeige den Haltepunkttyp als bp an.
0:000> bm myprog!openf*
0: 00421200 @!"myprog!openFile"
1: 00427800 @!"myprog!openFilter"
0:000> bm /d myprog!closef*
2: 00421600 @!"myprog!closeFile"
0:000> .bpcmds
bu0 @!"myprog!openFile";
bu1 @!"myprog!openFilter";
bp2 0x00421600 ;