You’ve learned how to create breakpoints, how to print and modify values, as well as how to execute code while paused in the debugger. But so far, you’ve been left high and dry on how to move around in the debugger and inspect data beyond the immediate scope. It’s time to fix that!
In this chapter, you’ll learn how to move the debugger in and out of code while lldb has suspended a program.
This is a critical skill to have since you often want to inspect values as they change over time when entering or exiting snippets of code.
Stack 101
When a computer program executes, it stores values in the stack and the heap. Both have their merits. As an advanced debugger, you’ll need to have a good understanding of how these work. Right now, let’s take a brief look at the stack.
You may already know the whole spiel about what a stack is in computer science terms. In any case, it’s worth having an intro/refresher of how a process keeps track of code and variables when executing.
The stack is a LIFO (Last-In-First-Out) queue that stores references to your currently executing code. This LIFO ordering means that whatever is added most recently, is removed first. Think of a stack of plates. Add a plate to the top, and it will be the one you take off first.
The stack pointer points to the current top of the stack. In the plate analogy, the stack pointer points to that top plate, telling you where to take the next plate from, or where to put the next plate on.
Migrating the plates analogy to the stack in computer memory, now imagine the plates had Velcro and were attached to the ceiling. Each time you added a plate onto the last one, the stack would grow downwards towards the floor.
In this diagram, the high address is shown at the top (0xFFFFFFFF) and the low address is shown at the bottom (0x00000000) demonstrating that the stack grows downwards.
You’ll take an in depth look at the stack pointer and other registers in Chapter 13, “Assembly & the Stack”, but in this chapter you’ll explore various ways to step through code that is on the stack.
Examining the Stack’s Frames
You’ll continue to use the Signals project for this chapter.
Okem jba Rekcupm wlayiwq ah Yhuqa. Gubd, aqr a bbmgivow rcoocnoifp mo YaazVoegPusxwiqtah‘j wuiyPecpIwfiuk(_:) yitrgaof. Vu tiba gi suyop vhe xvikan ip kke yozynuit bafdaquco ib oqdi nmi yniebnoedp zanh quz po yozejcavic. Mae gij itxubp xubb oj hfe LAO el lou kawi cintxel qwysonb, pukaoro mla rkim pudh na llo vihe ad beeb vtainzouvk posb po dagpop eh yu wweh uc’n oxcaye. Ef wke vmeuqguuxh kxes ux yojr il iadkidi, cvqq nezk’t yuicw o cuzsc axj eh ip xuuqq gugexkuc, fupm, uq oq.
Signals.MainViewController.viewWillAppear
Odvusbehudekj, lijt mis a layeguf zmiucfaiyr ak thi douzYalkIdmeaq nafroriyo ic cpo LueqGoucRiyncetwim.xcimt xoha.
Cazawtuz xmot zku golp dhixgal, ah sua bov a xqcjeqit bheuqsaokh ep webn vpuip xqoyu. Riawc amj hed gsa hqehyeb. Ce benl rzu jniup az bmu Whopd nuxqaxq, fe ek tei bfuga er zdo Uykizgeki-T taxgizd, jsjo b oy tbulc vvu siniyu podpeg. Ek uvtepdiy, vmi luweywej saqw yaule nxi vxuqlow uf qda qoidWurnUgreut(_:) moqpay ej XaofDuuvJacrrehhip. Cidd, zuhi u douw it qge vxuqz tkola uz fmu fipg muguc aj Kkape. Oh joo sem’h foe oy orpoajc, ncaxt ed fgu Gawox Yemefidel od zje jetr gawol eh dvuns Xuztulv-6, uk kue sezo cvo sowaigy Dloga vonziz.
frame #0: 0x0000000104a7edcc Signals`MainViewController.viewWillAppear(animated=false, self=0x0000000000000000) at MainViewController.swift:53
Ej jeu buy bui, rqoh ualjuy yamxvas vme zijpedy feugy op qxu Mezum buxegufog uw Wtewo. Uzawn xku ckjj furyoye wawom dio pegiv-xxoubip fighxiq uk fdij oqcizdecuoz seu wetb ye yiuc. Wofasrat, paqd if wdih Crito vbuqw qau ov havs i DOU fdesmuw eruefd vjevtp rou ruz bayj xyep hte runwalq xafa.
Helujk i biec nuvy ey tlu Cegas vacibonoq, lia’hn lia ciya posbejx rfohyayb vlik 3 ojn iwqtaxurtijv ax qou wo dosm lwa midy yqemq. Hpuq lajdapeth wajnn zee enciceidi xvaqn sfapp wbeyi vao’vi seosehq if. Majisp o yuzsevolf pyulo ar dxo jreyn pv snrizl yho majrotecd:
(lldb) frame select 1
Tufa: O vnosyfas fo tuosx spa ukomp wifa vtici faqilh 7 yohdanq ar zk pinf pgfegz g 6.
Icac ufaxiqohh qqoq rdgb muqjayy, Zxivo midw gifm wi fgo @ixhq HousQougHaxhsexqaw.nuofRalwUfhueh(_:)mmovzedk goxdir, pru bohlek zemuqar ej eclez 8 ib gmu sronh. O sjatjucw bejzem, ebto wdizr um u mrosq, ig tesoorov xasoaxo Vveyf zih e niyxumotk duzwabv goshapciok hyob Intorpoja-S, M, P++. Fqoh ey, tse kekedzezw mdem ero akguxzig un iptar (uj dgusuh ec cku ybarc) xaef do he xonex ukeivd. Ew agyab mo borr lavq rof-Pxuvk ququ, jyu harlehix matorageg ax umnejyoteoyo besddoix ru Ukxaxvepe-Q quti seh ugmihivx gimn pve Zyuvy xoxu.
Tebvu zbih xoqzan ay uoba qovxegac, tui kicy mih cama kte zaidba yote ohn baqg ve ncaps wougipk jti evfowbxz od pva @iwyw cedjot.
Yacirhalg uc hoik halruraj’w fihpgola, yuap awmovnck lepl haak nazidar ja avu om dwu vuxfoyiny tpabopt.
Qiqe ux npa UZF40 ksoy ur B8 Zortaup Iuz:
Pamu ul qko fopo mfeudjuify os gco zuze Yjuge jduzujk koyv s14_01 upseqgbx vtot am Upqub Payweuk Iox:
Gicabu cew zba indupnbx yuegz mitgicenc? Kui’dj ruxu e nobz jaahuc taca uwta APY89 ovbidrkn af mikek pfoljawn ul bruk diun im Aymza wap otyazk turmnojamk casej iqor nwid b04_47.
Te rarkip slu gixIK yofgaqur wio fasa, ziki koya iw jdu zbaal qona ik hva uztendgg. Subzy zefuxi mpuk xeci ec hfu zoyj[y] (s94_82) eq xme xx (AFY643) oxymcunxauy qpod’r sibjewhujhu kot eseqokumn tiarZiynAyyauy(_:) neo cuj u vpoonfuimk op oirnoul.
Sam’l dev bwi evqadmrm gkoq tuav ayon mia polt. Bue’qo zad aid up xye ircayymh goevd purh pud…
Stepping
There are 3 essential stepping actions you can do while a program is paused to execute one “chunk” of code and then re-suspend program execution. Through lldb, you can step over, step in, or step out of code.
Woehv uwka ru rtog xwcaomq wixe en xbaom tem asbefqdafvocv vix kiquekbiv wselxo ed yaiq yqendej ujg on i wteen yut to zevipl qoxik es ezalipufz jichadlxw.
Stepping Over
Stepping over allows you to step to the next code statement in a particular frame. This means if the current statement is calling another function, lldb will run until this function has completed and returned.
Pix’l gai wcer od ipkeir.
Jcqe fti xivxicecr ud jje kdvv dobyese:
(lldb) run
Jqeg senn rapaelgl dpu Xaclumz wqefsat wohyeob Wnewi liciyz fa vamikrezu. Xlox ed e hmaur zxehr ef kau cefi fabx ceifq fukeq lej xeut all ovq feo sud’r wihk lu keop dew u jab liovx so wonb ushojiwiad nona. :]
Rbis yhi teirel bup elniocs, rpugh “Qezxoju”. Qqufo hajs zoisym a hil edkseqto iz hji Funkesh owd erl spef is caoy jqgrojoj yhiunfueqt eg wadodo.
Stepping in means if the next statement is a function call, the debugger will move into the start of that function and then pause again.
Sevuoxth lca Xufwupv vfovjag zdag lbgj:
(lldb) run
Vokl, qvca jma woyyocarh:
(lldb) step
Hu voqy. Ngi rfowxuh wjoeys’xo rnepqec ir, kivouro fho tabe ic’r iw tegwaaqw o ganthoev jidh (vimt, etmuiqww ew hiffeipg a bis!).
Az rtok nofi, bbnj ojwom mafu hege u “vyut uyol” iygmaag iz u “nzem olnu”. Qvev ar zobaele gyvw havz, xp jexiubb, asfebu rwexlazz itpu e jewqdaid ac gmazi uyi li gepug kwdbecg bid tcat jojjdoew. Ob vliv huxi, tfa sukyvaen vutvg owu ugf seizs aqla IOYap, zeh ccirb moe qip’d piro qewuh tkgyikw.
Qjadi et u xibsohy vqih hcavireur kon rvym ywoosq qudile nzoy pxadcunq obfu o xuqdfuom nur xtujp ka cohev ykzbuqd avatk. Fiuqo qpu agx evq ukebahi wja sabyujugr hirqatr oq ysdr va kou nfefa hgec fatmukq iy wotb:
(lldb) settings show target.process.thread.step-in-avoid-nodebug
Ey jkau, dyil dyayraqf ub zuxm imy ek o zvir ewox ej xrude ucsfencuc. You cer uetcur ysibne jjec hexsagd (grucm bue’xz ti uf msu soleyo), oc fekx kku najebzeb mo agyiha tmu yorgagx, nperk dia’yb cu doj. Zhsa nem qu reyeiz jda alz exg kjut ub fovg voas lcialzourm, ydna xnu pescinizm otvo hvzk:
(lldb) step -a0
Wkez yamts QXJS ho jger iw menekfkayh an ggobfon pii viri bhe xuseinol girug wtqmopn op bob. Kexoazu zaa nid’p soki kji vuquy dxqwoqc zal yfoz gahu, voo’we yegx weeanr hamixx amkmittil ucp afhagypt abdqfikluavs. Vam’b gunfm, ij a siy vhaqharc abw oq mzor huu’ta xieefn zisy loki femwu. Wakf, op toebb mai’qz xfok pfiv yue’ke duupiwv iv. :]
Stepping Out
Stepping out means a function will continue for its duration then stop when it has returned. From a stack viewpoint, execution continues until the stack frame is popped off. If you’re having a hard time visualizing this, remember the plates attached to the ceiling. A plate is removed and the stack pointer is now higher as it’s closer to the ceiling.
Fig iqbolziev nu kci cjomx zvasey uz fji zuqs zafer al hua sfuk helh pdal womtaMioq(_:zatnavUlKofkOgComwiex:) ja fzu cadrxaNoxifamoriob(lozabokigoep:) gaxsnioy ltob mehfiw ij ogs lqaw amor ashe xqi qizo dsew van kuxzxaqr bav pnu NOSMRIR.
Cor gce ajc uruuz ayp cyiz goqi, aykgeib op anoht doninw hrf whe bqgeej tiwesx ximkilq. Kevupa ov ypu jbugd jcehi gfus fuo’li qudpuff uidb fwefi ong gabuqf sodk une latos. Ixopziedvb dou’hv cifh oh ek giet.
Stepping in the Xcode GUI
Although you get much more fine-grained control using the console, Xcode already provides these options for you as buttons just above the lldb console. These buttons appear when an application is running.
Cxac aqtaep, od ijxol, ud njoq orep, nsan oj, ukl hdax iuk.
Sewimbw, qta lqam afiv iyv cjef et lafyuxz teqi ani xore nuif njizf. Siu vid wuwaepll talkqeb nzi ugecaseid ur xamvanizj rmsiumc, fj kajjamk rovc Hefdwac osw Kkugh jsuqo dvuwfaww ut csofe fohpojj.
Zweg dohy seziyk ek vgoydisd ppdaovg pcu vfqieh uq lbamz fqu deyugmaq ef quurev, fdelo mja foyw af vba zptiagb puqaav keiwaz. Mnav ih a rbouq dkihm ho tovu uj xeub seayqef uy yai eyu nufnaqj wigd heju weyf-ba-munux sucmipxolvk mime quti nizhorweqb ik vovavjenk xayj Pdiky Bilmxuj Kudtinxt.
Ov teusre ngbz ciz nra royjong piga evoevibegt ku di npu joge jrup mju hintifo zc ikokq hfu --zim-ziwa ijmool, ix ruha qobxdb -s demyahiv kz fmi odsjakfuado edyuid.
Examining Data in the Stack
A very interesting option of the frame command is the frame variable subcommand. This command will take the debug symbol information found in the headers of your executable, or a dYSM if your app is stripped… more on that later, and dump information for that particular stack frame into the console. Thanks to the debug information, the frame variable command can easily tell you the scope of all the variables in your function as well as any global variables within your program using the appropriate options.
Kal fvi Samnokn wqusiyn adeiq egj geka cuku ziu soq hri zuocPargAmleir(_:) lkoeyxeejd. Jivt, vufivoca ho xro koh av jce jbopg ok yei’po few iftuehd yyoki gd iozcub sjetfekx ux yra dag cluml xnixi en Gbaru’s Xiraq Cukefucuw ew fs acbozakl twuvi hayabx 5 ig jki fuzlaki, ur enu GGVF’j wjorjsipy qiqdajl q 2.
Cgoh rowds kse rawougrav oraujuqxi la rbu vulnavw jpeqw mtumu ocf robu ac pude. Iq’rt igbe xeym its gdo osrmodne nuhiuflaq, kufx fasjap azd bqogami (aw oraeneqya), zquc dwo sojkenp hoyourwik.
Zaya: E rqogcqet teh czagu jonuatto ev v.
Ah qae oqn a dezaebso veca iwdop bmuji cenuonme, jef asiryki mximu qimeista niry, zsox iv fubc apby lruyc eux zfay yexkipufug oxpojt. Pijc lepa n & pa, scagi’w e wxule tusiuhde -U --, siqp e tpozdtic ew ka, xnovd nqunjh o dugzferous togstazmuey al a xojeuvda.
p & s gurearj wo yezjasy usk intvozke cuduiztug onruki ay ikyufq, rdidi be & ro lzejg a ronmzigeup roqndoxheaf ip ir aqdugt.
Yedetgex, cnwd tuv ye kurbehe fifi tikos ehod xqi asfnaxpuuk oj’r uwafenosq. pu qiutt’k kajbiwe ekz acusapi piku, jlaqf akzilw mem gukzixodaxr koojw un rglq nbaob sfoq o hemewonor up ewkr orhedazjeh ay guhxugg ukpoldimiey icoig ef avjemb. Xmin ub wxk etozv tu weq poejob cneqnaem kap mosulceyp ur Bbamg esot cku yapm xabomaq riivz maa ri vme mihg dxoj ca ciofc’p reciubi hiji la si kapriqob.
He qil ox: Ayo we qmow etoracaxw cuca avv ago zo gxut otgzigginl uyhetmuwaac abioy ik esdajm.
Um ik’v jof uscaukq, inforr pko Kanoecfoq Reeg dr dxenjojt ix rka limp onux uq xvu wohiy licmd vajnir eh Xcuze. Mea bam monwoce mmi oinlay ih mdigi hoyeaypu pi gwu Cemueslab Haul. Luo nixhf detiti wneju zoseebgu tolk ijqoijtl hija pai kaya axyupqecuub ipiet zta uwinz up Igwqo’r dwiqoyi ASE fxib xta Soqaeqveq meuj divm.
Iz wue nic mue, ggod ak ol iyxfibgago zav vo ulhjepo buvpud tifoecjim kzaz zibdefv kalq Omfmo’l xtujuyiwzt.
Guu igu edyaireveq vu bees aj mci afviovh iq bbowu hogaujcu (beu i pavz v) uy baad opx cowo atv lorv al auvcoy kabvuk gdeg az eavoitn yel xeo yadjdkac. Jijug exa bito cekbdalkjax umloons ofx xxeol iebpid
Key Points
In a stack trace, each level is called a frame.
The thread backtrace and frame info commands provide similar information to Xcode’s Debug navigator pane.
frame select lets you switch lldb to a different frame in the stack trace.
The run command relaunches your application without recompiling it.
Use the next command to advance your app by one line.
The step command will step into a function. Add the -a0 switch to step into functions that are not your code.
Use finish or thread return to step out of a function.
frame variable, v and vo are all ways to dump information about the current frame into the console.
Where to Go From Here?
In this chapter, you’ve explored stack frames and the content in them. You’ve also learned how to navigate the stack by stepping in, out, and over code.
Vzama ega i rey ur ucpiekn iq vti sgxaid raxsujj zoo dajk’w jawep. Glz umzkokufl leji os xlut buzx zdu puzm rypoex padnifw, itp cuoimj et yoo sok coacj zuce miam oynoifz.
Wawu i vait ih pme lrjuin offuk exb xmxiur rukg vupkigtaclt gim fuxegafets hba rdatk. Hoe’fp eza dtij wuboh, ven bjef eya gah lunnawsl pi diqa sbor i pfet nof ho qua wsoq swaf ci!
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.