Watchpoint — co to je, druhy a nastavení pozorovacích bodů v Xcode

Autor: IT Sectr Publikováno: 2026-05-07 Doba čtení: 8 min

Watchpoint (pozorovací bod) — mechanismus ladění, který pozastaví provádění programu při změně hodnoty zadané proměnné nebo oblasti paměti. Na rozdíl od breakpointu, který je vázán na řádek kódu, watchpoint sleduje změnu dat bez ohledu na to, ve které části programu k úpravě došlo. Podle Apple Developer Documentation jsou watchpointy nepostradatelné při ladění datových závitů, neočekávaných změn vlastností a sledování životního cyklu objektů.

Hlavní body

  • Watchpoint — pozorovací bod změny proměnné, který se aktivuje při každém zápisu do zadané oblasti paměti.
  • Xcode podporuje watchpointy přes GUI a konzoli LLDB, včetně podmíněných pozorovacích bodů.
  • Proměnné-vlastnosti objektů vyžadují watchpoint s adresou paměti, nikoli názvem proměnné.
  • Výkon s watchpointy výrazně klesá kvůli hardwarovému monitorování každé operace zápisu.
  • Watchpointy se neukládají mezi relacemi ladění — po každém spuštění je třeba je znovu nastavit.

Co je watchpoint a princip fungování

Watchpoint — mechanismus debuggeru, který pozastaví provádění programu, když se změní hodnota na zadané adrese paměti. Zatímco breakpoint reaguje na dosažení konkrétního řádku kódu, watchpoint reaguje na zápis do konkrétní paměťové buňky — bez ohledu na to, která část kódu zápis provedla. To jej činí nepostradatelným při hledání neočekávaných modifikací proměnných, zejména ve vícevláknových aplikacích.

Princip fungování je založen na hardwarové podpoře procesoru. Moderní čipy ARM (Apple Silicon, Qualcomm Snapdragon) poskytují 4 až 8 hardwarových registrů watchpoint. Když procesor provede instrukci zápisu na adresu shodující se s watchpointem, vznikne hardwarové přerušení, které debugger zachytí. Pokud hardwarové registry dojdou, LLDB přepne do softwarového režimu — kontroluje každou instrukci zápisu krok za krokem, což zpomalí provádění desetinásobně.

Podle ARM Architecture Reference Manual pracují hardwarové watchpointy na úrovni modulu Data Watchpoint and Trace (DWT) a nevyžadují úpravu spustitelného kódu. Doba reakce na aktivaci je v řádu nanosekund, což umožňuje sledovat i vysokofrekvenční změny proměnných ve smyčkách zpracování dat, jako jsou audio buffery nebo video snímky.

Kdy je watchpoint účinnější než breakpoint

Watchpoint je nepostradatelný, když víte, která proměnná se mění, ale nevíte odkud. Typické scénáře: hodnota vlastnosti frame v UIView se mění bez zjevného důvodu; čítač v backendovém vlákně se resetuje nepředvídatelně; příznak isLoading se přepne dříve, než dokončí síťový požadavek. V každém z těchto případů je nepraktické umisťovat breakpointy na všechna místa, kde může dojít k zápisu. Watchpoint řeší problém jedním příkazem.

Typy watchpointů a způsoby nastavení

Xcode a LLDB podporují tři typy watchpointů: watchpoint set variable — pro pozorování lokální proměnné; watchpoint set expression — pro pozorování výrazu vracejícího adresu; watchpoint set — pro pozorování surové adresy paměti. Každý typ má svou oblast použití.

Typ watchpointuPříkaz LLDBPoužití
Proměnnáwatchpoint set variable -w write self.countLokální a globální proměnné, vlastnosti struktur
Výrazwatchpoint set expression -w write -- &self->mutex.lockPole struktur přes ukazatel, prvky polí podle indexu
Adresawatchpoint set -w write 0x600000c4b80Konkrétní adresa paměti z předchozího výstupu LLDB

Nastavení přes GUI Xcode

V Xcode lze watchpoint nastavit přes Debug Area: zastavte se na breakpointu, najděte požadovanou proměnnou v panelu Variables View, klikněte pravým tlačítkem a vyberte Watch Variable. Xcode automaticky provede příkaz watchpoint set variable se správným názvem proměnné a kontextem. Poté se debugger zastaví při každé změně hodnoty — vhodné pro rychlé ladění bez přepínání do konzole. Tato metoda však funguje pouze dokud je proměnná v rozsahu viditelnosti aktuálního rámce.

swift
func processItems(_ items: [String]) {
    var index = 0
    // Nastavte watchpoint na index přes GUI:
    // zastavte se zde, klikněte pravým tlačítkem → Watch Variable
    for item in items {
        index += 1
        print("Item \(index): \(item)")
    }
}

Správa watchpointů přes LLDB

LLDB poskytuje kompletní sadu příkazů pro správu watchpointů z konzole. To poskytuje větší kontrolu než GUI: můžete určit velikost oblasti pozorování, nastavit podmínku aktivace, vytvářet watchpointy na adresy získané z vypočítaných výrazů a automaticky provádět akce při aktivaci. Rozhraní příkazového řádku je užitečné zejména při ladění složitých scénářů, kde je třeba rychle měnit parametry pozorování.

Základní příkazy watchpoint

Příkaz watchpoint set variable přijímá název proměnné s ohledem na rozsah viditelnosti: pro self vlastnosti v Objective-C použijte self->_property, pro Swift — self.property. Parametr -w write nastavuje sledování zápisu, -w read — čtení (režim dostupný pouze na některých architekturách), -s size — velikost oblasti v bajtech. Po nastavení watchpointu lze seznam zobrazit příkazem watchpoint list.

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'

Podmíněné watchpointy

Stejně jako breakpointy, i watchpointy podporují podmíněnou aktivaci. Parametr -c nastavuje podmínku ve Swift nebo Objective-C. Například watchpoint s podmínkou newValue > 1000 se zastaví pouze když zapsaná hodnota překročí tisíc. To je kritické při ladění smyček nebo senzorů generujících tisíce změn za sekundu — jinak by se debugger zastavoval při každé změně, což by znemožnilo práci.

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
// Automaticky logovat hodnotu a pokračovat v provádění

Watchpointy pro vlastnosti objektů a kolekcí

Zvláštnost watchpointů pro vlastnosti objektů Objective-C a Swift — watchpoint se nastavuje nikoli na název vlastnosti, ale na adresu pole ivar (instance variable) v paměti objektu. To znamená, že při každém novém přidělení objektu (například při znovuvytvoření ViewControlleru) se watchpoint stává neplatným, protože adresa paměti se změnila. Pro trvalé pozorování vlastnosti napříč restarty je třeba watchpoint znovu nastavit v okamžiku inicializace objektu.

Watchpoint na prvky kolekcí

Pozorování prvků polí a slovníků vyžaduje výpočet adresy konkrétního prvku. Například pro pozorování třetího prvku pole použijte watchpoint set expression -- &array[2]. Pokud pole přerozdělí svůj interní buffer (při přidávání prvků nad kapacitu), watchpoint se stane neplatným — LLDB ohlásí chybu Watchpoint 1 has an invalid address. V takových případech je třeba watchpoint znovu nastavit po změně velikosti kolekce.

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

Sledování retain count přes watchpoint

V Objective-C lze sledovat retain count objektu nastavením watchpointu na pole retainCount ve struktuře objc_object. LLDB to provádí přes watchpoint set expression -w write -- (int*)[object retainCount]. U Swift objektů s ARC (Automatic Reference Counting) však retain count není přímo dostupný — místo toho použijte Instruments nebo Memory Graph Debugger pro analýzu úniků paměti. Podle Apple fungují watchpointy na retain count pouze v Debug sestaveních s vypnutou optimalizací ARC.

Omezení a výkon watchpointů

Watchpointy mají řadu omezení, která je třeba zohlednit. Hlavní — počet hardwarových watchpointů je omezen na 4–8 registrů na architektuře ARM a až 4 na x86. Když jsou všechny hardwarové registry obsazeny, LLDB přepne do režimu softwarového watchpointu: upraví každou instrukci zápisu ve sledovaném rozsahu pro vygenerování výjimky. To zpomalí provádění 10–50krát, proto se v praxi doporučuje používat nejvýše 2–3 aktivní watchpointy současně.

Druhé omezení — neplatnost watchpointů při přerozdělení paměti. Při činnosti garbage collectoru nebo ARC, když je objekt přesouván v paměti (v jazycích s kompaktizací haldy), adresa watchpointu se stává nesprávnou. Ve Swift a Objective-C ARC objekty nepřesouvá, ale realokace polí a řetězců vede ke stejnému efektu. LLDB na to upozorňuje zprávou Watchpoint N address (0x...) doesn't contain a valid allocation.

Třetí omezení — viditelnost proměnných. Watchpoint na lokální proměnnou funguje pouze dokud je tato proměnná v rozsahu viditelnosti aktuálního rámce zásobníku. Jakmile funkce skončí, watchpoint je automaticky odstraněn. Pro pozorování globálních proměnných nebo polí dlouho žijících objektů zůstává watchpoint zachován až do explicitního odstranění přes watchpoint delete nebo do ukončení procesu.

lldb
(lldb) watchpoint delete 1
1 watchpoints deleted.
(lldb) watchpoint delete               # Smazat všechny watchpointy
2 watchpoints deleted.
(lldb) watchpoint disable 1             # Dočasně zakázat
(lldb) watchpoint enable 1              # Znovu povolit

Podle ARM podporují watchpointy na Apple Silicon (M1–M4) velikost sledované oblasti od 1 do 8 bajtů. Pro pozorování struktur větších než 8 bajtů je třeba nastavit několik watchpointů na každé pole. To je důležité při ladění složitých datových struktur, jako jsou CGRect (16 bajtů) nebo UIEdgeInsets (16 bajtů).

Často kladené otázky

Jaký je rozdíl mezi watchpointem a breakpointem?

Breakpoint je vázán na řádek kódu — zastaví se při jeho dosažení. Watchpoint je vázán na adresu paměti — zastaví se při zápisu na tuto adresu z libovolného místa programu. Watchpoint hledá „kdo mění hodnotu“, breakpoint — „co se děje na tomto řádku“.

Kolik watchpointů lze nastavit současně?

4–8 hardwarových na ARM (včetně Apple Silicon). Překročení přepne watchpoint do softwarového režimu, což zpomalí provádění 10–50krát. Doporučuje se nejvýše 2–3 aktivní watchpointy současně.

Proč watchpoint přestal fungovat po restartu aplikace?

Watchpointy se neukládají mezi relacemi ladění. Při každém novém spuštění se adresy paměti mění a watchpoint je třeba nastavit znovu. Výjimka — watchpointy na globální proměnné s pevnou adresou.

Lze nastavit watchpoint na vlastnost Swift?

Ano, ale watchpoint se nastavuje na ivar (podpůrné úložiště) vlastnosti, nikoli na vlastnost samotnou. Ve Swift použijte watchpoint set variable self.property — LLDB automaticky najde odpovídající ivar podle názvu vlastnosti.

Jak watchpoint ovlivňuje výkon aplikace?

Hardwarový watchpoint neovlivňuje výkon — přerušení probíhá na úrovni procesoru. Softwarový (při vyčerpání hardwarových registrů) zpomalí provádění 10–50krát, protože LLDB kontroluje každou instrukci zápisu.

Shrnutí

  • Watchpoint — pozorovací bod změny paměti, který se aktivuje při každém zápisu na zadanou adresu z libovolného vlákna.
  • Hardwarové watchpointy používají registry DWT procesoru a nezpomalují provádění, ale jsou omezeny na 4–8 registrů.
  • LLDB podporuje tři typy watchpointů: na proměnnou, na výraz a na surovou adresu paměti.
  • Podmíněné watchpointy se aktivují pouze při splnění zadaného výrazu — nezbytné pro ladění vysokofrekvenčních změn.
  • Watchpointy na vlastnosti objektů a prvky kolekcí se stávají neplatnými při přerozdělení paměti.
  • Watchpointy se neukládají mezi relacemi a jsou odstraněny při opuštění proměnné z rozsahu viditelnosti.
  • Watchpoint — nejlepší volba, když je proměnná známá, ale místo její úpravy neznámé, zejména ve vícevláknovém kódu.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také