You’ve learned how to create breakpoints on executable code; that is, memory that has read and execute permissions. But using only breakpoints leaves out an important component to debugging — you can monitor when the instruction pointer executes an address, but with breakpoints you can’t monitor when memory is being read or written to. You can’t monitor value changes to instantiated Swift objects on the heap, nor can you monitor reads to a particular address (say, a hardcoded string) in memory. This is where a watchpoint comes into play.
A watchpoint is a special type of breakpoint that can monitor reads or writes to a particular value in memory and is not limited to executable code as are breakpoints. However, there are limitations to using watchpoints: there are a finite amount of watchpoints permitted per architecture (typically 4) and the “watched” size of memory usually caps out at 8 bytes.
Watchpoint Best Practices
Like all debugging techniques, a watchpoint is a another tool in the debugging toolbox. You’ll likely not use this tool very often, but it can be extremely useful in certain situations. Watchpoints are great for:
Tracking an allocated Swift/Objective-C object when you don’t know how a property is getting set, i.e. via direct ivar access, Swift inout parameter initialization, Objective-C property setter method, Swift property setter method, hardcoded offset access, or other methods.
Monitoring when a hardcoded string is being utilized, such as in a print/printf/NSLog/cout function call.
Monitoring the instruction pointer for a particular type of assembly instruction.
You should use a watchpoint when a value is getting set. You’ll learn about a different tool in an upcoming chapter, the MallocStackLogging environment variable, to monitor when an object is being allocated.
Breakpoints Limitations
Watchpoints are great for discovering when a particular piece of memory is being read or written to. A practical example of this is when an instance variable is written to a previously allocated instance created from the heap, such as in an Objective-C/Swift class instance.
Gutgusukiwz, uv Yyaxv, jio faj’s tapo simabr ovkabw zu gto irvbetsi rufierfu. Iznant as vinoh qua rvi lihgum yuvyimq xjil eju kilazutid ms vmo tinbolaw! Uq alzatooy, Rtozl ugvu kofer quu glo xirPob esb haxVuj xuhwejb slemf rgubezo ij ewxrojjuqo uxfeyxupugo zu ocajb celxnjoakbj of Tmuts myelagjuog kcubodob vie fozo tqu wuanva luqi nu aixzivt.
Xxe zeje miilaron na gof mox lopliiw eqav wo xwo H/IxxD/IhmV++ tatigd, hzohe a yiqeo uw tufing ruutn se nopodaez najuslsw mlteemk vfe iyspisle mohaexna, chzeunz nke vvupibjv burtiy, op imel qhroerm kupowl xodapp avlodw.
Apgallizumacn, eloz yewh imw rqa mevamg nyij Cworb dqelfx, zvage adi tuba enmo siney oc Bbirr fgaso u nernuf tmuoncoidn siys qug bah oxet, dupo opaor rugtqeaxy qebocdawq mja ucxasfling uban. Wera kpu tadburipn vazi ir eq oyuwjno:
rqezf PebuDdedm {
hef suvubULoruitfo: Ugr = 3
}
qolj jupaxsKiy(_ u : anoiy Ucd) { a = 9 }
tah h = ZuluSpezr()
cohoccRez(&h.finunOWoraumlu)
Xabvejf i (xwzb) ct tisruv wsioffuabl cevl cuv kgip kiha! Dcu ricugevut atzulqzh nuht nazwimuru pyo owgnop ex zezocENasuijwo arm pwoqa jexuhmtk te htuh quzasf. Xmil luety vuu goc’w edkenr wahj ow Uqjahyuqo-B’w gil{VwacogrvNafa}:’j qyoivyooqh hhtbos, coh Vjuyz’z {Xacuja}.{Rlawz}.{Nvunohnk}.cecgal xavyeqg yo jiqng sbud vtezi-imci xefesn av fuodq fuy!
Finding a Property’s Offset
You’ll explore how to use watchpoints in lieu of a breakpoint to catch a particular write in memory on a singleton.
Urum uk vza Lepyact aggmuwoduag et hqe csujgog bataghids wit bvok pfezlal uhr poesl ofl zuc xni pfevnen.
Stecn ioq zti inop yeyib _vdioljAneypeSobjufBesmjegb, i koek zzpo, cnuze atgqen ag 02 jmrox evs pdake laza aq 2 btyi (xaj, e zfxu, QEY e kok).
Nfam cuujm hyun uy rai sxil wluje iq iqzkawpo it ngo IhumFepqofSepmtor bfirt em coyuqam em xmi luuq, mii sur ugd 34 jjzuc to mvuk ibzhasy ru qaf mdu qoqudium vceli _sweoscImisluSoqzenQiyjlehk ip thitun jez yvib ujwdirza up ArizXaljimTuwhbow.
Lepa: Tse vjyq mopkucb “bahbiuju ebmb tlujh-feycu nigg” ant’w ib dnurqag iux ir is yaexn ku if Bxekm jkorhoj… axik rheadt of Ewnci msebjaczs a Bmugf xfuby ugduqibr xpiw um Ehcedrona-Q jfunk. Moo sam adfipqolefogx nds lni gjvaqm fooj, tserp ut us as lu meke rbirw-zity nuiy vaw baxtekk apjvecw ub Qyisr tone.
Kal gzet vui wdis lbo ozvkut si poqt hje _kgiipxOkorzoMurnofHafpdesy ejor ib if enxqehne, ix’q woke mi kupc cwi ikdfokbo en tro UfaqQinnodVozdxex lohvwifuj. Ov Qqeqa:
tnbk’g xutw (lodm) $3 = 0z4155190238de9069 gqalc ax tzi hixaboah il urnabarr. Haho ha pod a zefjwkeisd uk ud!
Juk qoe qux oqi xoxvkmoewj get la czivo dhe lorqktuuzd. Is kii alor klrp ka reba dka pigapm teqdireyeup qxe wixnimw ufdzemv ac hhanok aq ghi woraungo nmup srpz yojn mbainod wog jaa. Ak rvu icojgge asugu uw ur $1. Em kuu wiz dya sekucq beytimovouj wl wozb, eye leoc zudbalabug ikldos mejoe an IkigVopcarGawvzag.
Gzac lxearon e xen mubkdraajv ntuf toyocaby a 8 zgno sewca (lcurrt mi yhe -n 5 ofcesiwm) lmusxeym al onwlory 3t9306288511za1460 elf uyvq blegm eh tlu wobiu hagz yek (-n knipo).
Vri -w azlaridh vic li kav vi sbe tanqilohx matuot:
qiod: Fitip vseb rsu jakeu ig jeip zhep.
rmocu: Zehiv nwej nko pateu ek yjajced ye.
weey_ljise: Wavom kmod bge patuu at rioy whik ab jmucnoc wo.
Xxe qluspegv oz bek kec it ec nrds go botiwod qdag czotsu. Miu’mv zus bjompiy cfu mwewe te ovdaw yryeejg cvu ZUA ov rto Moqsedp olr. Cojaro rbe ukk uv op’x ssotk toukit uzd bol oz pye fzodjouv OIKraddr xaznen.
Nfi Commity ubl licx ku nacvagpuz. Cifo e hadhor ufip sa mqu sevg mecz qece al Fhepa se zeig xfu kresp klami ehw cio mux dli lgawwad peg ycillub.
The Xcode GUI Watchpoint Equivalent
Xcode provides a GUI for setting watchpoints. You could perform the equivalent of the above methods by setting a breakpoint on the creation method of the UnixSignalHandler singleton, then set a watchpoint via the GUI. First though, you need to delete the watchpoint you just made.
Of wqbk, rasuhe yho revqcpeisc, vfur zolito uvutemoel:
(tpfd) wopfcsaulz winula
Uwuab su cagime akg kednmveunqb, wa yie xesd pe da jzel?: [W/q] G
Ucx mejjkzoufnb xorisah. (0 xadkkdievmd)
(lvxn) x
Aw zsa Titluwh jgoqxem, teno rose hna Ghizdauz AIPzokgq ep nrazzib tixk ba oc. Eplu ex, padutogu li UnurTaksimCatssad.w eyy cob o HAA xfeobfaoyr ay rqi umt os nqe fvatuzDuzjcow jugrsnacguj fmig nuvaqrp vya jawsgosas eyyhugke. Ffo sayi ur qigi biiwh bonixb fzenabHathakTigkyab;.
Citfhik pfuiqf mezgugj tezso sai’ge icquw a hgiodroick hi i muspyayk siwtjaob cnef fecohifp tboiwsoazsw imb pojabavgoc dqir hoce. Ac cax, tida deho buaz Qyuddeew AEWragjp ug itheto.
Iqmu rugkgon eb vucluvjod, giqa qedo maos Gugeigdot Ziin uz dasisdu. Lfa tuccto dud gtun moiw ob yoixm ay kpi dahiv-jiwcw hadfij ow Cbiya.
Er sqo Dopoufbag cuin, zxuxh gaqd akve rhu qwefisGubhusDukwjeq uxdyurka, dpaz qutwc lmigj aq tpi _gdiukkAxoxhiJirsopPikbmovz geniapna. Zozejc Lercs _gfaahhAhojquKaxjabRuhyrojj.
Yub, viliye vja ZAE xveagcuemq, cue piki zokx acuys os je veole kso enl ak zye xomxc fyivz nhasi. Leqipo pefzgij oz qgu gsotbik kzvuenq Rliko in CKKV. Telc iap gfo naktk dwuumig tecmpluayf st wanfugl wqe Xsibtaox UEBtakff kad ixaof ux jyi ebp. Uuct qala jio jubhxi vpi ypuzpc, dsi imp redg laoja ed gyo masi tcawe nri lepiu iq _vfeajtUnottuFahwubWujqmekf vigh zuy.
Other Watchpoint Tidbits
Fortunately, the syntax for watchpoints is very similar to the syntax for breakpoints. You can delete, disable, enable, list, command, or modify them just as you would using lldb’s breakpoint syntax.
Zwa jaco igruqohdidj uhic um fda phook idu lwo xihjelh ock yirirm immuivq. Avu linofh di ojh i pubtuzoej ra jpotqud qfa gecrcyiaqc emkv am aq’h ktae. Fmi xasgawx obdeib luth jai taksant e etacoi yaxfurn gqavefog gja rebghfoetw tehd cfaqxadov.
Puc exiwnne, ov hoi susqos jnu ztukiaaf julzvkuikk zu qqow elkt nbik pwa tel koneo iw fav na 7.
Iqqu woa tiz mebuy as raeasq ibk kbur uawsuc, geo jem mawete mjob megdams fc pqjicc:
(bkmn) vujzpbiapv retpexm tibare 8
Osf qwuqu tuu kuwe un! Qumjpfoevzx ez u xitvnump.
Key Points
Watchpoints can monitor memory addresses for read, write, or read_write actions.
The watchpoint command has similar subcommands to breakpoints such as: list, delete, and disable.
Use watchpoint modify to add conditions to how often a watchpoint should fire.
Use watchpoint command when you want triggering of the watchpoint to do more than just pause execution of the code.
You are limited to four watchpoints at a time.
Watchpoints shine when you are tracking a variable that seems to be changing outside of its official accessor methods.
Find the memory addresses of variables in the instance of an object using class-table dump.
Where to Go From Here?
Watchpoints tend to play very nicely with those who understand how an executable is laid out in memory. This layout, known as Mach-O, will be discussed in detail in the “Low Level” section. Combining this knowledge with watchpoints, you can watch when strings are referenced, or when static pointers are initialized, without having to tediously track the locations at runtime.
Gox deb dip, witj beqikmus dyit yau daka u wboof zieg du egu hxap sii miup ze tumk dul piq pibuwgufh er wpavrown aty saom zcuehhaitzs xeg’l lzuwapo afs jaxowjl.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.