bp, bu, bm (Breakpoint festlegen)

Die Befehle bp, bu und bm legen einen oder mehrere Softwarehaltepunkte fest. Sie können Standorte, Bedingungen und Optionen kombinieren, um verschiedene Arten von Softwarehaltepunkten festzulegen.

User-Mode

[~Thread] bp[ID] [Options] [Address [Passes]] ["CommandString"] 
[~Thread] bu[ID] [Options] [Address [Passes]] ["CommandString"] 
[~Thread] bm [Options] SymbolPattern [Passes] ["CommandString"]

Kernel-Mode

bp[ID] [Options] [Address [Passes]] ["CommandString"] 
bu[ID] [Options] [Address [Passes]] ["CommandString"] 
bm [Options] SymbolPattern [Passes] ["CommandString"]

Parameter

Thread
Gibt den Thread an, für den der Haltepunkt gilt. Weitere Informationen zur Syntax finden Sie unter Threadsyntax. 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 ihn mit dem Befehl br (Breakpoint Renumber) ändern. Sie können die ID verwenden, um in späteren Debuggerbefehlen auf den Haltepunkt zu verweisen. Verwenden Sie den Befehl bl (Haltepunktliste), um die ID eines Haltepunkts anzuzeigen.

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 ID einen beliebigen Ausdruck enthalten. Weitere Informationen zur Syntax finden Sie unter Syntax für numerische Ausdrücke.

Optionen Gibt Haltepunktoptionen an. Sie können eine beliebige Anzahl der folgenden Optionen angeben, außer wie angegeben:

/1
Erstellt einen One-Shot-Haltepunkt. Nachdem dieser Haltepunkt ausgelöst wurde, wird er aus der Haltepunktliste gelöscht.

/pEProcess
(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 gefunden wird.

/tEThread
(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 gefunden wird. Wenn Sie /pEProcess und /tEThread verwenden, können Sie sie in beliebiger Reihenfolge eingeben.

/cMaxCallStackDepth
Aktiviert den Haltepunkt nur, wenn die Aufruflistentiefe kleiner als MaxCallStackDepth ist. Sie können diese Option nicht zusammen mit /C verwenden.

/CMinCallStackDepth
Aktiviert den Haltepunkt nur, wenn die Aufruflistentiefe größer als MinCallStackDepth ist. Sie können diese Option nicht zusammen mit /c verwenden.

/Eine
(Nur für BM ) Legt Haltepunkte an allen angegebenen Speicherorten fest, unabhängig davon, ob sie sich im Daten- oder Codebereich befinden. Da Haltepunkte für Daten zu Programmfehlern führen können, verwenden Sie diese Option nur an Speicherorten, die als sicher gelten.

/d
(Nur für BM ) Konvertiert die Haltepunktspeicherorte in Adressen. Wenn der Code verschoben wird, verbleiben die Haltepunkte daher an derselben Adresse, anstatt gemäß SymbolPattern festgelegt zu werden. Verwenden Sie /d , um zu vermeiden, dass Änderungen an Haltepunkten neu ausgewertet werden, 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, aber unterschiedliche Parameterlisten haben. Beispielsweise legt bm /( myFunc Haltepunkte sowohl für myFunc(int a) als auch für myFunc(char a)fest. Ohne "/(" schlägt ein Haltepunkt, der auf myFunc festgelegt ist, 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 vom dx-Objektausdruck zurückgegeben wird. Das Argument ist ein Datenmodellausdruck (dx), der zu true (entspricht bedingung – break) oder false (nicht mit Bedingung übereinstimmt – nicht unterbrechen) ausgewertet wird.

In diesem Beispiel wird ein bedingter Haltepunkt basierend auf dem Wert von localVariable festgelegt.

bp /w "localVariable == 4" mymodule!myfunction

In diesem Beispiel wird gezeigt, wie Sie einen Haltepunkt mithilfe von 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 wird. Wenn Sie Adresse weglassen, wird der aktuelle Anweisungszeiger verwendet. Weitere Informationen zur Syntax finden Sie unter Adress- und Adressbereichssyntax.

Übergibt
Gibt die Anzahl des Ausführungsdurchlaufs an, für den der Haltepunkt aktiviert wird. Der Debugger überspringt die Haltepunktposition, bis er den angegebenen Durchlauf erreicht. Der Wert von Passes kann ein beliebiger 16-Bit- oder 32-Bit-Wert sein.

Standardmäßig ist der Haltepunkt aktiv, wenn die Anwendung zum ersten Mal den Code ausführt, der den Haltepunktspeicherort enthält. Diese Standardsituation entspricht dem Wert 1 für Pässe. Um den Haltepunkt nur zu aktivieren, nachdem die Anwendung den Code mindestens einmal ausgeführt hat, geben Sie den Wert 2 oder mehr ein. Beispielsweise aktiviert der Wert 2 den Haltepunkt bei der zweiten Ausführung des Codes.

Dieser Parameter erstellt einen Zähler, der bei jeder Durchlaufung des Codes dekrementiert wird. Verwenden Sie bl (Breakpoint List), um die anfangs und aktuellen Werte des Passzählers anzuzeigen.

Der Passzähler wird nur dekrementiert, wenn die Anwendung als Reaktion auf einen g-Befehl (Go) über den Haltepunkt hinaus ausgeführt wird. Der Indikator wird nicht dekrementiert, wenn Sie den Code schrittweise durchlaufen oder die Ablaufverfolgung daran vorbei verfolgen. Wenn der Pass-Zähler1 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 in der angegebenen Anzahl von Malen gefunden wird. Sie müssen den CommandString-Parameter in Anführungszeichen einschließen. Verwenden Sie Semikolons, um mehrere Befehle zu trennen.

Debuggerbefehle in CommandString können Parameter enthalten. Sie können C-Steuerelement-Standardzeichen (z. B.\n und \") verwenden. Semikolons, die in Anführungszeichen der zweiten Ebene (\") enthalten sind, werden als Teil der eingebetteten Zeichenfolge in Anführungszeichen interpretiert.

Die CommandString-Befehle werden nur ausgeführt, wenn der Haltepunkt erreicht wird, während die Anwendung als Reaktion auf einen g (Go)-Befehl ausgeführt wird. Die Befehle werden nicht ausgeführt, wenn Sie den Code durchlaufen oder die Ablaufverfolgung nach diesem Punkt durchlaufen.

Alle Befehle, die die Programmausführung nach einem Haltepunkt (z. B. g oder t) fortsetzen, beenden die Ausführung der Befehlsliste.

SymbolPattern
Gibt ein Muster an. Der Debugger versucht, dieses Muster vorhandenen Symbolen zuzuordnen und Haltepunkte für alle Mustervergleiche festzulegen. SymbolPattern kann eine Vielzahl von Wildcardzeichen und Spezifizierern enthalten. Weitere Informationen zu dieser Syntax finden Sie unter Zeichenfolgenplatzhaltersyntax. Da diese Zeichen mit Symbolen abgeglichen werden, wird bei der Übereinstimmung 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 Livedebuggen
Plattformen alle

Zusätzliche Informationen

Weitere Informationen und Beispiele für die Verwendung von Haltepunkten, anderen Haltepunktbefehlen und Methoden zum Steuern von Haltepunkten sowie zum Festlegen von Haltepunkten im Benutzerbereich über einen 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 (Breakpoint festlegen) legt einen neuen Haltepunkt an der Adresse der Haltepunktposition fest, die im Befehl angegeben ist. Wenn der Debugger den Adressausdruck der Haltepunktposition beim Festlegen des Haltepunkts nicht auflösen kann, wird der 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 (Nicht aufgelösten Haltepunkt festlegen) legt einen verzögerten oder nicht aufgelösten Haltepunkt fest. Ein bu-Haltepunkt wird für einen symbolischen Verweis auf die im Befehl angegebene Haltepunktposition (nicht für eine Adresse) festgelegt und aktiviert, wenn das Modul mit dem Verweis aufgelöst wird. Weitere Informationen zu diesen Haltepunkten finden Sie unter Nicht aufgelöste Haltepunkte (bu Breakpoints).

  • Der Befehl bm (Set Symbol Breakpoint) legt einen neuen Haltepunkt für Symbole fest, die einem angegebenen Muster entsprechen. Mit diesem Befehl können mehrere Haltepunkte erstellt werden. Standardmäßig sind bm-Haltepunkte nach dem Abgleich des Musters mit bu-Haltepunkten identisch. Das heißt, bm-Haltepunkte sind verzögerte Haltepunkte, die für einen symbolischen Verweis festgelegt werden. Ein Befehl bm /d erstellt jedoch einen oder mehrere Bp-Haltepunkte . Jeder Haltepunkt wird für die Adresse eines abgeglichenen Standorts festgelegt und verfolgt den Modulstatus nicht.

Wenn Sie nicht sicher sind, welcher Befehl zum Festlegen eines vorhandenen Haltepunkts verwendet wurde, verwenden Sie .bpcmds (Anzeigehaltepunktbefehle), um alle Haltepunkte zusammen mit den Befehlen aufzulisten, die zum Erstellen verwendet wurden.

Es gibt drei Hauptunterschiede zwischen bp-Haltepunkten und Bu-Haltepunkten :

  • Eine Bp-Haltepunktposition wird immer in eine Adresse konvertiert. Wenn eine Moduländerung den Code verschiebt, an dem ein Bp-Haltepunkt festgelegt wurde, verbleibt der Haltepunkt an derselben Adresse. Andererseits bleibt ein bu-Haltepunkt dem symbolischen Wert (in der Regel ein Symbol plus Offset) zugeordnet, der verwendet wurde, und verfolgt diesen symbolischen Ort nach, 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. Auf der anderen Seite bleiben bu-Haltepunkte nach wiederholten Ent- und Ladevorgängen erhalten.

  • Haltepunkte, die Sie mit bp festlegen, werden nicht in WinDbg-Arbeitsbereichen gespeichert. Haltepunkte, die mit bu festgelegt werden, werden in Arbeitsbereichen gespeichert.

Der Befehl bm ist nützlich, wenn Sie Im Symbolmuster für einen Haltepunkt Wildcardzeichen verwenden möchten. Die Syntax bmSymbolPattern entspricht der Verwendung von x SymbolPattern und der anschließenden Verwendung von bu für jedes Ergebnis. Um beispielsweise Haltepunkte für alle Symbole im Modul Myprogram festzulegen, 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 Befehl bm Softwarehaltepunkte (keine Prozessorhaltepunkte) festlegt, schließt er automatisch den Speicherort der Daten aus, wenn breakpoints festgelegt werden, um eine Beschädigung der Daten zu vermeiden.

Es ist möglich, eine Datenadresse anstelle einer Programmadresse anzugeben, wenn Sie die Befehle bp oder bm /a verwenden. Selbst wenn ein Datenspeicherort angegeben wird, erstellen diese Befehle jedoch Softwarehaltepunkte und keine Prozessor breakpoints. Wenn ein Softwarehaltepunkt in Programmdaten anstelle von ausführbarem Code platziert wird, kann dies zu Datenbeschädigungen führen. Daher sollten Sie diese Befehle nur an einem Speicherort verwenden, wenn Sie sicher sind, dass der an 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 Prozessor breakpoints (ba Breakpoints).

Ausführliche Informationen zum Festlegen eines Haltepunkts an einem Speicherort, der durch eine komplexere Syntax angegeben wird, z. B. ein Member einer öffentlichen C++-Klasse oder eine beliebige Textzeichenfolge, die ansonsten eingeschränkte Zeichen enthält, finden Sie unter Breakpoint Syntax.

Wenn sich eine einzelne logische Quellzeile über mehrere physische Zeilen erstreckt, 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, platziert er den Haltepunkt an der nächsten zulässigen Position.

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) festlegen, für alle Prozessoren. Wenn der aktuelle Prozessor beispielsweise 3 ist und Sie bp MemoryAddress eingeben, um einen Haltepunkt bei MemoryAddress zu setzen. Jeder Prozessor, der an dieser Adresse (nicht nur Prozessor 3) ausgeführt wird, verursacht eine Haltepunktfalle.

Die Befehle bp, bu und bm legen Softwarehaltepunkte fest, indem die Prozessoranweisung durch eine Breakanweisung ersetzt wird. Verwenden Sie zum Debuggen von schreibgeschütztem Code oder Code, der nicht geändert werden kann, einen Ba e-Befehl, wobei e den reinen Ausführungszugriff darstellt.

Der folgende Befehl legt einen Haltepunkt 12 Byte nach dem Anfang der Funktion MyTest fest. Dieser Haltepunkt wird für die ersten sechs Durchläufe des Codes 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 fährt 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 solchen, die ohne ihn erstellt wurden. Die BPCMDS (Anzeigehaltepunktbefehle) können verwendet werden, um zwischen diesen beiden Typen zu unterscheiden. Wenn der Haltepunkt von bm ohne den Schalter /d erstellt wurde, gibt die BPCMDS-Anzeige den Haltepunkttyp als bu an, gefolgt von dem ausgewerteten Symbol, das im @!"- Token eingeschlossen ist (was angibt, dass es sich um ein Literalsymbol und nicht um einen numerischen Ausdruck oder ein Register handelt). 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 ;