Watchpoint — was es ist, Arten und Konfiguration von Beobachtungspunkten in Xcode

Autor: IT Sectr Veröffentlicht: 2026-05-07 Lesezeit: 8 Min.

Watchpoint (Beobachtungspunkt) — ein Debugging-Mechanismus, der die Programmausführung anhält, wenn sich der Wert einer angegebenen Variablen oder eines Speicherbereichs ändert. Im Gegensatz zu einem Breakpoint, der an eine Codezeile gebunden ist, verfolgt ein Watchpoint Datenänderungen unabhängig davon, an welcher Stelle im Programm die Änderung erfolgt. Laut Apple Developer Documentation sind Watchpoints unverzichtbar zum Debuggen von Datenrennen, unerwarteten Eigenschaftsänderungen und zur Verfolgung von Objektlebenszyklen.

Wichtige Punkte

  • Watchpoint — ein Punkt, der eine Variable auf Änderungen überwacht und bei jedem Schreibzugriff auf den angegebenen Speicherbereich auslöst.
  • Xcode unterstützt Watchpoints über GUI und LLDB-Konsole, einschließlich bedingter Watchpoints.
  • Eigenschaftsvariablen von Objekten erfordern einen Watchpoint mit der Speicheradresse anstelle des Variablennamens.
  • Die Leistung mit Watchpoints nimmt aufgrund der Hardware-Überwachung jedes Schreibvorgangs erheblich ab.
  • Watchpoints bleiben nicht zwischen Debugging-Sitzungen erhalten — sie müssen nach jedem Start neu gesetzt werden.

Was ist ein Watchpoint und wie funktioniert er

Watchpoint — ist ein Debugger-Mechanismus, der die Programmausführung anhält, wenn sich der Wert an einer angegebenen Speicheradresse ändert. Wenn ein Breakpoint auf das Erreichen einer bestimmten Codezeile reagiert, reagiert ein Watchpoint auf das Schreiben in eine bestimmte Speicherzelle — unabhängig davon, welcher Teil des Codes den Schreibvorgang ausgeführt hat. Dies macht ihn unverzichtbar zum Auffinden unerwarteter Variablenänderungen, insbesondere in Multithread-Anwendungen.

Das Funktionsprinzip basiert auf der Hardware-Unterstützung des Prozessors. Moderne ARM-Chips (Apple Silicon, Qualcomm Snapdragon) bieten 4 bis 8 Hardware-Watchpoint-Register. Wenn der Prozessor eine Schreibanweisung an eine Adresse ausführt, die mit einem Watchpoint übereinstimmt, tritt ein Hardware-Interrupt auf, den der Debugger abfängt. Wenn die Hardware-Register erschöpft sind, wechselt LLDB in den Software-Modus — es überprüft jede Schreibanweisung schrittweise, was die Ausführung um ein Vielfaches verlangsamt.

Laut dem ARM Architecture Reference Manual arbeiten Hardware-Watchpoints auf der Ebene des Data Watchpoint and Trace (DWT)-Moduls und erfordern keine Änderung des ausführbaren Codes. Die Reaktionszeit liegt im Nanosekundenbereich, sodass auch hochfrequente Variablenänderungen in Datenverarbeitungsschleifen wie Audio- oder Videoframe-Puffern verfolgt werden können.

Wann ein Watchpoint effektiver ist als ein Breakpoint

Watchpoint ist unverzichtbar, wenn Sie wissen, welche Variable sich ändert, aber nicht wissen, woher. Typische Szenarien: Eine frame-Eigenschaft von UIView ändert sich ohne ersichtlichen Grund; ein Zähler in einem Hintergrund-Thread setzt sich unvorhersehbar zurück; ein isLoading-Flag wechselt, bevor eine Netzwerkanfrage abgeschlossen ist. In jedem dieser Fälle ist es unpraktisch, Breakpoints an allen Stellen zu setzen, an denen ein Schreibvorgang auftreten könnte. Ein Watchpoint löst das Problem mit einem einzigen Befehl.

Arten von Watchpoints und Einrichtungsmethoden

Xcode und LLDB unterstützen drei Arten von Watchpoints: watchpoint set variable — zur Überwachung einer lokalen Variablen; watchpoint set expression — zur Überwachung eines Ausdrucks, der eine Adresse zurückgibt; watchpoint set — zur Überwachung einer rohen Speicheradresse. Jeder Typ hat seinen eigenen Anwendungsbereich.

Watchpoint-TypLLDB-BefehlVerwendung
Variablewatchpoint set variable -w write self.countLokale und globale Variablen, Struktur-Eigenschaften
Ausdruckwatchpoint set expression -w write -- &self->mutex.lockStrukturfelder per Zeiger, Array-Elemente per Index
Adressewatchpoint set -w write 0x600000c4b80Spezifische Speicheradresse aus vorheriger LLDB-Ausgabe

Einrichtung über Xcode-GUI

In Xcode können Sie einen Watchpoint über den Debug-Bereich einrichten: Halten Sie an einem Breakpoint an, finden Sie die gewünschte Variable im Variablenansichtsfenster, klicken Sie mit der rechten Maustaste und wählen Sie Watch Variable. Xcode führt automatisch den Befehl watchpoint set variable mit dem richtigen Variablennamen und Kontext aus. Danach hält der Debugger bei jeder Wertänderung an — praktisch für schnelles Debuggen ohne Umschalten auf die Konsole. Diese Methode funktioniert jedoch nur, solange die Variable im Gültigkeitsbereich des aktuellen Frames liegt.

swift
func processItems(_ items: [String]) {
    var index = 0
    // Watchpoint auf index via GUI setzen:
    // hier anhalten, Rechtsklick → Watch Variable
    for item in items {
        index += 1
        print("Element \(index): \(item)")
    }
}

Verwaltung von Watchpoints über LLDB

LLDB bietet einen vollständigen Satz von Befehlen zur Verwaltung von Watchpoints über die Konsole. Dies gibt mehr Kontrolle als die GUI: Sie können die Größe des Überwachungsbereichs festlegen, Auslösebedingungen angeben, Watchpoints auf Adressen erstellen, die aus berechneten Ausdrücken stammen, und bei Auslösung automatisch Aktionen ausführen. Die Befehlsschnittstelle ist besonders nützlich beim Debuggen komplexer Szenarien, die ein schnelles Ändern der Überwachungsparameter erfordern.

Grundlegende Watchpoint-Befehle

Der Befehl watchpoint set variable nimmt einen Variablennamen unter Berücksichtigung des Gültigkeitsbereichs entgegen: Für Objective-C-self-Eigenschaften verwenden Sie self->_property, für Swift verwenden Sie self.property. Der Parameter -w write legt die Schreibverfolgung fest, -w read — die Lese-Verfolgung (ein Modus, der nur auf einigen Architekturen verfügbar ist), -s size — die Größe des Bereichs in Bytes. Nach dem Setzen eines Watchpoints können Sie die Liste mit dem Befehl watchpoint list anzeigen.

lldb
(lldb) watchpoint set variable -w write -s 8 self.balance
Watchpoint 1: addr = 0x600000c4b80 size = 8 state = enabled  type = w
    watchpoint spec: 'self.balance'
(lldb) watchpoint set expression -w write -- self->items._storage
Watchpoint 2: addr = 0x600003a4c00 size = 8
(lldb) watchpoint list
1: location = 0x600000c4b80, type = write, variable = '_balance'
2: location = 0x600003a4c00, type = write, expression = 'self->items._storage'

Bedingte Watchpoints

Wie Breakpoints unterstützen auch Watchpoints bedingte Auslösung. Der Parameter -c legt eine Bedingung in Swift oder Objective-C fest. Zum Beispiel hält ein Watchpoint mit der Bedingung newValue > 1000 nur an, wenn der geschriebene Wert tausend überschreitet. Dies ist entscheidend beim Debuggen von Schleifen oder Sensoren, die Tausende von Änderungen pro Sekunde erzeugen — andernfalls würde der Debugger bei jeder Änderung anhalten und die Arbeit unmöglich machen.

lldb
(lldb) watchpoint set variable -w write self.temperature -c "(int)$newValue > 100"
Watchpoint 3: addr = 0x600000e4a20, condition = '(int)$newValue > 100'
(lldb) watchpoint modify 3 -C "po self.temperature" -G true
// Wert automatisch protokollieren und Ausführung fortsetzen

Watchpoints für Objekteigenschaften und Sammlungen

Eine Besonderheit von Watchpoints für Objective-C- und Swift-Objekteigenschaften — ein Watchpoint wird nicht auf den Eigenschaftsnamen gesetzt, sondern auf die Adresse des ivar-Feldes (Instanzvariable) im Speicher des Objekts. Das bedeutet, dass bei jeder neuen Objektzuweisung (z.B. beim Neuerstellen eines ViewControllers) der Watchpoint ungültig wird, weil sich die Speicheradresse geändert hat. Für eine dauerhafte Überwachung einer Eigenschaft über Neustarts hinweg müssen Sie den Watchpoint zum Zeitpunkt der Objektinitialisierung neu setzen.

Watchpoint auf Sammlungselementen

Die Überwachung von Elementen von Arrays und Wörterbüchern erfordert die Berechnung der Adresse eines bestimmten Elements. Um zum Beispiel das dritte Element eines Arrays zu überwachen, verwenden Sie watchpoint set expression -- &array[2]. Wenn das Array seinen internen Puffer neu zuweist (beim Hinzufügen von Elementen über die Kapazität hinaus), wird der Watchpoint ungültig — LLDB meldet einen Fehler Watchpoint 1 has an invalid address. In solchen Fällen müssen Sie den Watchpoint nach der Größenänderung der Sammlung neu setzen.

lldb
(lldb) expr var $arr = [10, 20, 30, 40, 50]
(lldb) watchpoint set expression -w write -- &$arr[2]
Watchpoint 4: addr = 0x1000a4b20, size = 8
(lldb) expr $arr[2] = 99
Watchpoint 4 hit: old value: 30, new value: 99

Verfolgung des Retain Counts über Watchpoint

In Objective-C können Sie den Retain Count eines Objekts verfolgen, indem Sie einen Watchpoint auf das Feld retainCount in der Struktur objc_object setzen. LLDB führt dies über watchpoint set expression -w write -- (int*)[object retainCount] durch. Für Swift-Objekte mit ARC (Automatic Reference Counting) ist der Retain Count jedoch nicht direkt zugänglich — verwenden Sie stattdessen Instruments oder den Memory Graph Debugger zur Leckanalyse. Laut Apple funktionieren Watchpoints auf Retain Count nur in Debug-Builds mit deaktivierter ARC-Optimierung.

Einschränkungen und Leistung von Watchpoints

Watchpoints haben mehrere wichtige Einschränkungen, die zu beachten sind. Die wichtigste — die Anzahl der Hardware-Watchpoints ist auf 4–8 Register auf ARM-Architektur und bis zu 4 auf x86 begrenzt. Wenn alle Hardware-Register belegt sind, wechselt LLDB in den Software-Watchpoint-Modus: Es modifiziert jede Schreibanweisung im verfolgten Bereich, um eine Ausnahme zu erzeugen. Dies verlangsamt die Ausführung um das 10- bis 50-fache, daher wird in der Praxis empfohlen, nicht mehr als 2–3 aktive Watchpoints gleichzeitig zu verwenden.

Die zweite Einschränkung — Ungültigwerden von Watchpoints bei Speicher-Neuallokation. Wenn die Garbage Collection oder ARC ausgelöst wird und ein Objekt im Speicher verschoben wird (in Sprachen mit Heap-Kompaktierung), wird die Watchpoint-Adresse ungültig. In Swift und Objective-C verschiebt ARC keine Objekte, aber die Neuallokation von Arrays und Strings verursacht denselben Effekt. LLDB warnt davor mit der Meldung Watchpoint N address (0x...) doesn’t contain a valid allocation.

Die dritte Einschränkung — Variablensichtbarkeit. Ein Watchpoint auf eine lokale Variable funktioniert nur, solange diese Variable im Gültigkeitsbereich des aktuellen Stack-Frames liegt. Sobald die Funktion beendet wird, wird der Watchpoint automatisch entfernt. Zur Überwachung globaler Variablen oder Felder langlebiger Objekte bleibt ein Watchpoint bestehen, bis er explizit über watchpoint delete gelöscht wird oder der Prozess endet.

lldb
(lldb) watchpoint delete 1
1 watchpoints deleted.
(lldb) watchpoint delete               # Alle Watchpoints löschen
2 watchpoints deleted.
(lldb) watchpoint disable 1             # Vorübergehend deaktivieren
(lldb) watchpoint enable 1              # Wieder aktivieren

Laut ARM unterstützen Watchpoints auf Apple Silicon (M1–M4) eine überwachte Bereichsgröße von 1 bis 8 Bytes. Zur Überwachung von Strukturen, die größer als 8 Bytes sind, müssen Sie mehrere Watchpoints auf jedes Feld setzen. Dies ist wichtig beim Debuggen komplexer Datenstrukturen wie CGRect (16 Bytes) oder UIEdgeInsets (16 Bytes).

Häufig gestellte Fragen

Was ist der Unterschied zwischen einem Watchpoint und einem Breakpoint?

Breakpoint ist an eine Codezeile gebunden — er hält an, wenn diese Zeile erreicht wird. Watchpoint ist an eine Speicheradresse gebunden — er hält an, wenn ein Schreibzugriff auf diese Adresse von irgendwo im Programm erfolgt. Ein Watchpoint sucht „wer den Wert ändert“, ein Breakpoint sucht „was in dieser Zeile passiert“.

Wie viele Watchpoints können gleichzeitig gesetzt werden?

4–8 Hardware-Watchpoints auf ARM (einschließlich Apple Silicon). Eine Überschreitung schaltet den Watchpoint in den Software-Modus, was die Ausführung um das 10- bis 50-fache verlangsamt. Es wird empfohlen, nicht mehr als 2–3 aktive Watchpoints gleichzeitig zu verwenden.

Warum funktioniert ein Watchpoint nach einem Neustart der Anwendung nicht mehr?

Watchpoints bleiben nicht zwischen Debugging-Sitzungen erhalten. Bei jedem neuen Start ändern sich die Speicheradressen und der Watchpoint muss neu gesetzt werden. Die Ausnahme sind Watchpoints auf globale Variablen mit fester Adresse.

Kann ich einen Watchpoint auf eine Swift-Eigenschaft setzen?

Ja, aber der Watchpoint wird auf den ivar (Backing Storage) der Eigenschaft gesetzt, nicht auf die Eigenschaft selbst. In Swift verwenden Sie watchpoint set variable self.property — LLDB findet automatisch den entsprechenden ivar anhand des Eigenschaftsnamens.

Wie wirkt sich ein Watchpoint auf die Anwendungsleistung aus?

Hardware-Watchpoints beeinträchtigen die Leistung nicht — der Interrupt erfolgt auf Prozessorebene. Software-Watchpoints (bei Erschöpfung der Hardware-Register) verlangsamen die Ausführung um das 10- bis 50-fache, da LLDB jede Schreibanweisung überprüft.

Zusammenfassung

  • Watchpoint — ein Punkt, der Speicheränderungen überwacht und bei jedem Schreibzugriff auf die angegebene Adresse von jedem Thread aus auslöst.
  • Hardware-Watchpoints verwenden Prozessor-DWT-Register und verlangsamen die Ausführung nicht, sind aber auf 4–8 Register begrenzt.
  • LLDB unterstützt drei Arten von Watchpoints: auf eine Variable, auf einen Ausdruck und auf eine rohe Speicheradresse.
  • Bedingte Watchpoints lösen nur aus, wenn ein angegebener Ausdruck als wahr evaluiert wird — unerlässlich zum Debuggen hochfrequenter Änderungen.
  • Watchpoints auf Objekteigenschaften und Sammlungselementen werden bei Speicher-Neuallokation ungültig.
  • Watchpoints bleiben nicht zwischen Sitzungen erhalten und werden entfernt, wenn eine Variable den Gültigkeitsbereich verlässt.
  • Watchpoint ist die beste Wahl, wenn die Variable bekannt ist, aber der Ort ihrer Änderung nicht, insbesondere in Multithread-Code.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch