Watchpoint (observation point) — isang debugging mechanism na nagpapahinto sa pagpapatakbo ng programa kapag nagbago ang halaga ng isang tinukoy na variable o lugar ng memorya. Hindi tulad ng breakpoint na nakatali sa isang linya ng code, sinusubaybayan ng watchpoint ang pagbabago ng data anuman ang bahagi ng programa kung saan naganap ang pagbabago. Ayon sa Apple Developer Documentation, ang mga watchpoint ay kailangang-kailangan sa pag-debug ng data races, hindi inaasahang pagbabago ng properties, at pagsubaybay sa lifecycle ng mga object.
Mga Pangunahing Punto
Watchpoint — isang mekanismo ng debugger na nagpapahinto sa pagpapatakbo ng programa kapag nagbago ang halaga sa tinukoy na address ng memorya. Kung ang breakpoint ay tumutugon sa pag-abot sa isang partikular na linya ng code, ang watchpoint ay tumutugon sa pagsulat sa isang partikular na cell ng memorya — anuman ang bahagi ng code na nagsagawa ng pagsulat na iyon. Ginagawa nitong kailangang-kailangan sa paghahanap ng hindi inaasahang pagbabago ng variable, lalo na sa mga multi-threaded na application.
Ang prinsipyo ng paggana ay batay sa hardware support ng processor. Ang mga modernong ARM chip (Apple Silicon, Qualcomm Snapdragon) ay nagbibigay ng 4 hanggang 8 hardware watchpoint registers. Kapag ang processor ay nagsagawa ng write instruction sa address na tumutugma sa watchpoint, nagkakaroon ng hardware interrupt na nahaharang ng debugger. Kung maubos ang hardware registers, ang LLDB ay lumipat sa software mode — sinusuri nito ang bawat write instruction nang paisa-isa, na nagpapabagal sa pagpapatakbo nang sampung beses.
Ayon sa ARM Architecture Reference Manual, ang hardware watchpoints ay gumagana sa antas ng Data Watchpoint and Trace (DWT) module at hindi nangangailangan ng pagbabago ng executable code. Ang oras ng reaksyon sa pag-activate ay nasa nanosecond range, na nagpapahintulot sa pagsubaybay kahit na sa high-frequency na pagbabago ng variable sa data processing loops tulad ng audio buffers o video frames.
Watchpoint ay kailangang-kailangan kapag alam mo kung aling variable ang nagbabago, ngunit hindi mo alam kung saan. Mga tipikal na senaryo: ang halaga ng property na frame sa UIView ay nagbabago nang walang maliwanag na dahilan; ang counter sa background thread ay nagre-reset nang hindi inaasahan; ang flag na isLoading ay nagbabago bago matapos ang network request. Sa bawat isa sa mga kasong ito, ang paglalagay ng breakpoints sa lahat ng lugar kung saan maaaring maganap ang pagsulat ay hindi praktikal. Ang watchpoint ay lumulutas ng problema sa isang utos.
Ang Xcode at LLDB ay sumusuporta sa tatlong uri ng watchpoints: watchpoint set variable — para sa pag-obserba ng lokal na variable; watchpoint set expression — para sa pag-obserba ng expression na nagbabalik ng address; watchpoint set — para sa pag-obserba ng raw memory address. Bawat uri ay may sariling lugar ng aplikasyon.
| Uri ng watchpoint | LLDB command | Aplikasyon |
|---|---|---|
| Variable | watchpoint set variable -w write self.count | Lokal at global variables, properties ng structures |
| Expression | watchpoint set expression -w write -- &self->mutex.lock | Fields ng structures sa pamamagitan ng pointer, array elements ayon sa index |
| Address | watchpoint set -w write 0x600000c4b80 | Specific memory address mula sa nakaraang LLDB output |
Sa Xcode, ang watchpoint ay maaaring i-install sa pamamagitan ng Debug Area: huminto sa breakpoint, hanapin ang gustong variable sa Variables View panel, right-click at piliin ang Watch Variable. Awtomatikong isasagawa ng Xcode ang command na watchpoint set variable na may tamang pangalan ng variable at konteksto. Pagkatapos nito, ang debugger ay hihinto sa bawat pagbabago ng halaga — maginhawa para sa mabilis na pag-debug nang hindi lumilipat sa console. Gayunpaman, ang pamamaraang ito ay gumagana lamang habang ang variable ay nasa visibility scope ng kasalukuyang frame.
func processItems(_ items: [String]) {
var index = 0
// I-set ang watchpoint sa index sa pamamagitan ng GUI:
// hinto dito, right-click → Watch Variable
for item in items {
index += 1
print("Item \(index): \(item)")
}
}
LLDB ay nagbibigay ng kumpletong set ng mga command para sa pamamahala ng watchpoints mula sa console. Ito ay nagbibigay ng mas malaking kontrol kaysa sa GUI: maaari mong tukuyin ang laki ng observation area, magtakda ng activation condition, lumikha ng watchpoints sa mga address na nakuha mula sa computed expression, at awtomatikong magsagawa ng mga aksyon kapag na-activate. Ang command line interface ay lalong kapaki-pakinabang sa pag-debug ng mga kumplikadong senaryo kung saan kailangan ang mabilis na pagbabago ng observation parameter.
Ang command na watchpoint set variable ay tumatanggap ng pangalan ng variable na isinasaalang-alang ang visibility scope: para sa self properties sa Objective-C gamitin ang self->_property, para sa Swift — self.property. Ang parameter na -w write ay nagtatakda ng pagsubaybay sa pagsulat, -w read — pagbasa (mode na available lang sa ilang architecture), -s size — laki ng area sa bytes. Pagkatapos i-install ang watchpoint, ang listahan ay makikita gamit ang command na watchpoint list.
(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'
Tulad ng breakpoints, ang watchpoints ay sumusuporta sa conditional activation. Ang parameter na -c ay nagtatakda ng condition sa Swift o Objective-C. Halimbawa, ang watchpoint na may condition na newValue > 1000 ay hihinto lamang kapag ang isinulat na halaga ay lumampas sa isang libo. Ito ay kritikal sa pag-debug ng mga loop o sensor na gumagawa ng libu-libong pagbabago bawat segundo — kung hindi, ang debugger ay hihinto sa bawat pagbabago, na ginagawang imposible ang trabaho.
(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
// Awtomatikong i-log ang halaga at ipagpatuloy ang pagpapatakbo
Ang kakaiba ng watchpoints para sa Objective-C at Swift object properties — ang watchpoint ay naka-install hindi sa pangalan ng property, kundi sa address ng ivar (instance variable) field sa memorya ng object. Ito ay nangangahulugan na sa bawat bagong alokasyon ng object (halimbawa, kapag muling ginawa ang ViewController), ang watchpoint ay nagiging invalid dahil nagbago ang memory address. Para sa patuloy na pag-obserba ng property sa pamamagitan ng mga restart, ang watchpoint ay kailangang muling i-install sa sandali ng initialization ng object.
Ang pag-obserba ng mga elemento ng array at dictionary ay nangangailangan ng pagkalkula ng address ng specific element. Halimbawa, para obserbahan ang ikatlong elemento ng array, gamitin ang watchpoint set expression -- &array[2]. Kung ang array ay mag-reallocate ng internal buffer nito (kapag nagdagdag ng elemento na lampas sa capacity), ang watchpoint ay magiging invalid — mag-uulat ang LLDB ng error na Watchpoint 1 has an invalid address. Sa mga ganitong kaso, ang watchpoint ay kailangang muling i-install pagkatapos magbago ang laki ng collection.
(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
Sa Objective-C, maaari mong subaybayan ang retain count ng isang object sa pamamagitan ng pag-install ng watchpoint sa field na retainCount sa structure na objc_object. Isinasagawa ito ng LLDB sa pamamagitan ng watchpoint set expression -w write -- (int*)[object retainCount]. Gayunpaman, para sa Swift objects na may ARC (Automatic Reference Counting), ang retain count ay hindi direktang accessible — sa halip, gamitin ang Instruments o Memory Graph Debugger para sa pagsusuri ng memory leaks. Ayon sa Apple, ang watchpoints sa retain count ay gumagana lamang sa Debug builds na naka-off ang ARC optimization.
Mga watchpoint ay may ilang mga limitasyon na dapat isaalang-alang. Ang pangunahing — ang bilang ng hardware watchpoints ay limitado sa 4–8 registers sa ARM architecture at hanggang 4 sa x86. Kapag ang lahat ng hardware registers ay occupied, ang LLDB ay lumipat sa software watchpoint mode: binabago nito ang bawat write instruction sa sinusubaybayang range upang makabuo ng exception. Ito ay nagpapabagal sa pagpapatakbo ng 10–50 beses, kaya sa praktika ay inirerekomenda na gumamit ng hindi hihigit sa 2–3 aktibong watchpoints nang sabay-sabay.
Ang pangalawang limitasyon — pagiging invalid ng watchpoints sa memory reallocation. Sa paggana ng garbage collector o ARC, kapag ang object ay inilipat sa memorya (sa mga wikang may heap compaction), ang watchpoint address ay nagiging hindi tama. Sa Swift at Objective-C, ang ARC ay hindi naglilipat ng mga object, ngunit ang reallocation ng arrays at strings ay nagdudulot ng parehong epekto. Ang LLDB ay nagbabala tungkol dito gamit ang mensaheng Watchpoint N address (0x...) doesn't contain a valid allocation.
Ang ikatlong limitasyon — visibility ng mga variable. Ang watchpoint sa isang lokal na variable ay gumagana lamang habang ang variable na iyon ay nasa visibility scope ng kasalukuyang stack frame. Kapag natapos na ang function, ang watchpoint ay awtomatikong tatanggalin. Para sa pag-obserba ng global variables o fields ng long-lived objects, ang watchpoint ay pinanatili hanggang sa explicit deletion sa pamamagitan ng watchpoint delete o hanggang sa pagtatapos ng process.
(lldb) watchpoint delete 1
1 watchpoints deleted.
(lldb) watchpoint delete # Tanggalin ang lahat ng watchpoints
2 watchpoints deleted.
(lldb) watchpoint disable 1 # Pansamantalang i-disable
(lldb) watchpoint enable 1 # I-enable muli
Ayon sa ARM, ang watchpoints sa Apple Silicon (M1–M4) ay sumusuporta sa laki ng sinusubaybayang area mula 1 hanggang 8 bytes. Para sa pag-obserba ng structures na mas malaki sa 8 bytes, kinakailangan ang pag-install ng maraming watchpoints sa bawat field. Ito ay mahalaga sa pag-debug ng kumplikadong data structures tulad ng CGRect (16 bytes) o UIEdgeInsets (16 bytes).
Mga Madalas Itanong
Breakpoint ay nakatali sa isang linya ng code — humihinto kapag naabot ito. Watchpoint ay nakatali sa isang memory address — humihinto kapag may pagsulat sa address na iyon mula sa anumang bahagi ng programa. Ang watchpoint ay naghahanap kung “sino ang nagbabago ng halaga”, ang breakpoint ay naghahanap ng “kung ano ang nangyayari sa linyang ito”.
4–8 hardware sa ARM (kabilang ang Apple Silicon). Ang paglampas ay naglilipat ng watchpoint sa software mode, na nagpapabagal ng pagpapatakbo ng 10–50 beses. Inirerekomenda ang hindi hihigit sa 2–3 aktibong watchpoints nang sabay-sabay.
Mga watchpoint ay hindi nai-save sa pagitan ng debugging sessions. Sa bawat bagong paglunsad, nagbabago ang memory addresses at ang watchpoint ay kailangang muling i-install. Exception — watchpoints sa global variables na may fixed address.
Oo, ngunit ang watchpoint ay naka-install sa ivar (backing storage) ng property, hindi sa property mismo. Sa Swift, gamitin ang watchpoint set variable self.property — awtomatikong mahahanap ng LLDB ang kaukulang ivar batay sa pangalan ng property.
Hardware watchpoint ay hindi naaapektuhan ang performance — ang interrupt ay nangyayari sa antas ng processor. Software (kapag naubos ang hardware registers) ay nagpapabagal ng pagpapatakbo ng 10–50 beses dahil sinusuri ng LLDB ang bawat write instruction.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din