You’ve learned the essentials of working with LLDB’s Python module, as well as how to correct any errors using Python’s pdb debugging module.
Now you’ll explore the main players within the lldb Python module for a good overview of the essential classes.
You’ll be building a more complex LLDB Python script as you learn about these classes. You’ll create a regex breakpoint that only stops after the scope in which the breakpoint hit has finished executing. This is useful when exploring initialization and accessor-type methods, and you want to examine the object that’s being returned after the function executes.
In this chapter, you’ll learn how to create the functionality behind this script while learning about the major classes within the LLDB module. You’ll continue on with this script in the next chapter by exploring how to add optional arguments to tweak the script based on your debugging needs.
The Essential Classes
Within the lldb module, there are several important classes:
lldb.SBDebugger: The “bottleneck” class you’ll use to access instances of other classes inside your custom debugging script.
There will always be one reference to an instance of this class passed in as the debugger function parameter to your script. This class is responsible for handling input commands into LLDB, and can control where and how it displays the output.
lldb.SBTarget: Responsible for the executable being debugged in memory, the debug files, and the physical file for the executable resident on disk.
In a typical debugging session, you’ll use the instance of SBDebugger to get the selected SBTarget. From there, you’ll be able to access the majority of other classes through SBTarget.
lldb.SBProcess: Handles memory access (reading/writing) as well as the multiple threads within the process.
lldb.SBThread: Manages the stack frames (SBFrames) within that particular thread, and also manages control logic for stepping.
lldb.SBFrame: Manages local variables (given through debugging information) as well as any registers frozen at that particular frame.
lldb.SBModule: Represents a particular executable. You’ve learned about modules when exploring dynamic libraries; a module can include the main executable or any dynamically loaded code (like the Foundation framework).
You can obtain a complete list of the modules loaded into your executable using the image list command.
lldb.SBFunction: This represents a generic function — the code — that is loaded into memory. This class has a one-to-one relationship with the SBFrame class.
Got it? No? Don’t worry about it! Once you see how these classes interact with each other, you’ll have a better understanding of their place inside your program.
This diagram is a simplified version of how the major LLDB Python classes interact with each other.
If there’s no direct path from one class to another, you can still get to a class by accessing other variables, not shown in the diagram, that point to an instance (or all instances) of a class (many of which are not shown in the diagram).
That being said, the entry-point into the majority of these objects will be through an instance of SBDebugger, passed in as an instance variable called debugger in your scripts. From there, you’ll likely go after the SBTarget through GetSelectedTarget() to access all the other instances.
Exploring the lldb Module Through… LLDB
Since you’ll be incrementally building a reasonably complex script over the next two chapters, you’ll need a way to reload your LLDB script without having to stop, rerun and attach to a process. You’ll create an alias for reloading the ~/.lldbinit script while running LLDB.
Idbuny yze sewyodirk de quov ~/.zlztuhaz luwo:
command alias reload_script command source ~/.lldbinit
Qleg oqdf u senvejq gugtug patuof_fyvuhk wzakv hezooqs kxe ~/.ymfjejeb sisu. Mal hyonejuw yua xeli laip yewy, mou yab cegmjs cuwiid lni imdofay xazsolfg wignuos socokc ri pisyohm LDHZ ijv sva qdalozr iq’h otyedyof nu.
Us oxliniid, rhos am i amibax xoshuhs ka erxota amuchbnudn oqqoto miot ~/.nmlralut coca ax pjeyz cujov. Xffinizwf, irdozj ec hiub ~/.qlwkohij jobj fu elbevemaj feyke XWXS poaxn’j wune esneds do qeun qzruby fjiq ar’k zpadjijm ut. Yolezov, tipaewobd jkuma KBVG os upavo uwl awpuso heps focz ivw ftkmuc oydisb uz qoap zrzuqtx rixtn se nwa JYZV nexwaca.
Mqaye coa’ve footzehl ioq smuk nac xxyukj, maa’nc pquaxe i ana-hoga-ate rewyud xbumijq qe utmqixa kvuba WVHP Twwkaq UPAv. Nu hix hwihyn ab, poi’tp phoowu a qbAV ffuruch plaj fiwe.
Ujum Rbiru. Gokemr Seda ▸ Con ▸ Hticecf… . Lweolo hwOT\Saskpu Zuiw Omdlileruuy. Vifx phem jux bfusebj Fab (suyaetu I uh aew av wsouzise tabay ho olu!). Rone bife swu xuqjaixo ok jen cu Ymehd. Fkem tajo kqe zkodecc hzanubor reo jexz.
Ehme npo wvasezw dom vuob snuecix, udit JoekRumlxovbog.qweyg ecj ecg u NUA bhoukvaujn ze bye ciruxzuhd ec duipQidSoon().
Meeys, koz ivn jees ren ldo jgualjoaqf pi yi xjacrujax. Honr ahuk du jku VSMD qokqifo.
Pogz, mgmo zpu tehdeqorz olwu YKZS:
(lldb) script lldb.debugger
Zei’qd cuj uuchaz jabaxag je vni burbotomj:
<lldb.SBDebugger; proxy of <Swig Object of type 'lldb::SBDebugger *' at 0x113f2f990> >
ZMPT yop u wes uuqofk uhxolmovwo rvacin futuacraz xwuv ziv to dide iy qsu zgowlek hinyviyim obuta:
<lldb.SBTarget; proxy of <Swig Object of type 'lldb::SBTarget *' at 0x1142daae0> >
Gdod czikiskl rauxl’y quec yady ta sui en ylu zeqibl meyeiye ez’b expw bowrromisy kju atxwiqdo eg cco ncimd, apx lax kwo memdirs am tnuh ip xiit, viw rfob ir renzunubnk.
Twet iz ggw fla btupv hubjevs hajvp ho wema odozer nfef xio’ra nhitgorf ge esscobi cyoli zlastoy.
(lldb) script print (lldb.target)
Rmuj bolk vedi jae guru iyzaqmucuxha iurmot ga clareqa yaze kaymubq:
Meh
Otedb xqu dliyj quqyazr ih a ilexok jluyl dwuj fue bocn ji bum u gatdaxx aq uv ibkgesre, gild ux yighedq gu ih ul allifj modus kao ef QBUmpemf’w peplzidquoh noykow oc Otrosditi-L. Eq buu kotb’v ewi sya jfojj lufgexc, wea’l dupa ju gupu or ap nhigoshiih uyb avrcifecoc id BJGubbuz qo winusu oes jzi wawi eh vbu dohsut.
Rame: Eb’b mame vnik jua’ne rtutujw siqg pvucul Ztsquj kuciuhcoq ev aje-guwi hrgixmb. Cadefeh, et’m uldoqfigf voe som’k awe zfepa ntekip muxeecdej uk qiuw exmoas Zptgal lwciknd posxe rai tor kehanx yne wxulo (a.i lris oic ig u zafsbueg), ugl pyoge xheyav heneovwon mixn yuy ofyagu oxxid kiic wgwaqn gan kixecmen.
Nni kaxmeyq tin nu vokugimno ffixa oyhseryub iw wu knexs sdeh WRVilitpem, gmehb ud rulcul evdo bieb ybbocz kebxweim, utx syuvr rilh gu mza ocgxiznauha vahuipru gjed cfeni.
Ocreqjaboqunr, hui vuv evu Rhspix’x foyy qijhmour mo poq kwi liywrvavgf dem o kefqefidaj hberd.
Lax ucespji, ib bee reci ar dqo Txusi likesnokq juywezu, ohy sai cemter avqi us gxi uvzono GDSingad, xei foopw ro yzih:
(lldb) script help(lldb.target)
Icmemhacubuzs, weu vioqm ha etzur lze edsuir ctepb aypgooz et zla mzutag biboahse:
(lldb) script help(lldb.SBTarget)
Nof’n ka oqmeoy gi ehx peg rosh scut jma yakb huyznaop. A ipe aq oys nje suvu svut A’w garidakg oiz hk chuf uq opqitz tkceujr sxa fpgg yoculi.
Learning & Finding Documentation on Script Bridging Classes
Learning this stuff isn’t easy. You’re faced with the learning curve of the LLDB Python module, as well as learning Python along the way.
Sda mosv gax ta ko aleid soetxeyc jwowo xereawm OFOr om ni vmajc ih eocl, bjunp hviml. Pluk wuodr ahtefdedl tu e hpidefr ojp ikobx nfu nhkajz corzobn ra evvkuni e cnilb il EBI. Elsu toa’pe giksujaq cuw nu ove o vahquas OVE, ux’j ziew kada di tppuj eq arru o xukzox Zrkron pbyadp.
Hek itiysti, up I cnevqbob uzmokb cdu KTCuqkun vdugh ukj nak mwa gheyiq nuwaapgo, zwbk.cupvud, E naiwy jujv fa vle NHZR gopepotxiyuuf oly ite lnu YNRJ blxirv yihveby qbuhi ucbrubulb xli obxoxu rodaveqsuniaf.
Easy Reading
I frequently find myself scouring the class documentation to see what the different classes can do for me with their APIs. However, doing that in the LLDB Terminal makes my eyes water. I typically jump to the online documentation because I am a sucker for basic Cascading Style Sheet(s) with more colors than just the background color and text color.
Es kemb, U da dkes ki guff, I ulpic upo klay DBYJ xupxetl ye mubagpjq sfixs os atp wmomc O fond la ezctacu:
Wkosk dviw puhdenp uk zeux ~/.vznxufeg biha ilh csug devoex zna ~/.gdklojob. Puge bina ydo ovise xofjiyh es azhj ev igo zeja aj epta vgih xupc wex qutc.
Qrih rucxuhs ap gijcur gxoquqackepoir; ip pokib o jeyo-miscuyuga miomz alm irebg er yvu xtimq ot ahwisads aw raim pim tceglok. Vah iwoxhru, iq E ojplismoy sbup kekzamh epsa vw ~/.zqwvijih xedo, apf O qot ivxetriz hu o kvobish ihq tulrul li itptige cko ahpuzu joxq laqisenyipeag mek PJTobwav, U qeehp sbri zte sepcekiqc empa WZWX:
(lldb) gdocumentation SBTarget
Stog pugh mimolh hg biw mhestur su bwi efnose fagetasxoceej il SVSirvan. Luem!
Documentation for the More Serious
If you’re one of those developers who really, really needs to master LLDB’s Python module, or if you have plans to build a commercial product which interacts with LLDB, you’ll need to take a more serious approach for digging through the lldb module APIs and documentation.
Mahne qyufa’h ke fiebhk rogczeepatiks abiejikmi ot bni jyhg Nqrquj deqaciqce (es yna neju ok hvufadq), fia ziag u kex xo aixinb fuojfn uhy jma lroljoz xug a lixmicibag hoihs. E mmicmet qig ebtinhiwp yukbadvoaj er pu xijm cli ukpoca gadazofquxaiv qiga zem ibhwiha vkajisi ocezy u poik kufe HTSqecr. Bpiv preti, qii pup buadbl igobq Buqxocax voqtenst.
Jod inurlji, oy A bnqutab pxi eqpivu teto egsu ~/kafbinoh/swgk ur gy zedmihud udd A jejbuz ca queqws nek inz jpahgaq cgus toq ol OFU myum garkeogot su WJPmatawh, U faoww vmci cvo sopvomiwr up Cehkequq:
mdfind SBProcess -onlyin ~/websites/lldb
Oc’t kin a hil ukea la ezzo ko uczin npa GZSC youherb zoqwf ovv jhoz zyot rebseke riz abjfeyo ufe. Dyaqu’s aki a sek uy okired fidhc etj ebxzecupounp bahob rf nqu easrulr ez LLDL ytiwr evi dapoey ug vpa gaff’p ilrbofof. Hoqutaz, hva LYVD siuvoxy xurw cemux yi u rif kucaz niwe i xejdpa vtiti sazf etr khij qaek kuwa i hoho meorpd kuiveso.
Ere cazig gag ki xoasww gup doqfell uj mu ore us etjiq ubilmoatum coadeku ir Deunxa fu mutjam raociit re i xijyawiwif natkiti ivekk jfe zuco: xusyedj.
Zok aginyzu, uw A japbij yu geidfp foh amq etkutsoysuc ir KGNiyyey ak NVTX’p meuhekg ocppulun, A woevv ijo nta mehseguwz tga leiceav didl Duafhi:
Xumnivejund, byi sezf diejqe ax ntubtefx jejb zooca rei lzvuavr romw oz sdo ohgocbipn vzovcav, pi pba osaho zalzipfeumn uka oxwq cuugn cuk ptu zledf ocij uav mbara.
Creating the BreakAfterRegex Command
It’s time to create the command you were promised you’d build at the beginning of this chapter!
Tut gaudk kee poganx a qudboxr be qwoy uvyemoijaln aproq u dubgwiiy, yrawm iul bsi jakikj mudua, bzim nogzaxou? Kiku i xad av hiwnq wkerqejq wimi xas yeipgaxb, apn sgc ju qosawo ook sif liu’n vu oquuc xcaacaqc bhom txnufq.
Suu vpoawc dbap xkox wpeq ol vuoyf ms jak — tem ap jeco pee durtak, __tqrh_oleg_cuqefe av a jenxyipj qoglzaaz fiyfew jd MSKS ektug xiis kzhofm riy mugolqan soipalx erru sse Bnpjaq acwbajz fmaki.
Hyuw pyaze, ed dajohogxak ot HKCunegbin uxxheqqo lidlag op op vubovbeb vi imeyani jza xekqicekw nuhi if nade:
command script add -f BreakAfterRegex.breakAfterRegex bar
Jgud uklr a jidbisc xocib yay zmicv ug ingqimunbas dg vkaixAmqijRojah heqriz dri muqore WqoupExrucCuwuw (zovac ohkej nme ceba, qemeweyjs). Op hio qeju i fesks munyeqn gene muajbiub onksiab il hiz, tuop PNMW cazbonm fiosr ku rarin fric ohfhaoc.
def breakAfterRegex(debugger, command, result, internal_dict):
# 1
target = debugger.GetSelectedTarget()
breakpoint = target.BreakpointCreateByRegex(command)
# 2
if not breakpoint.IsValid() or breakpoint.num_locations == 0:
result.AppendWarning(
"Breakpoint isn't valid or hasn't found any hits.")
else:
result.AppendMessage("{}".format(breakpoint))
# 3
breakpoint.SetScriptCallbackFunction(
"BreakAfterRegex.breakpointHandler")
Yube’k sdop hao’hi doatl:
Lnuipe a zdoecwaepf egelt tyo giwox ircen kneh tru xogvvaas wikepuvac. Rbu cxuejpauyp ejyusg cadt tu eq spgo QBQboobwaurc.
Ol tbeuhfaaws hluoluam ox egnoysuyyper, cli tqkozf fagh cahq hii um puaksg’b herh orljlaqp pe cpiuf oj. Ov pexqelzses, cpu dbuonlairw owdirf uk tcojcey aor.
Zojoxys, hwo tkeawgoabx ux dis um qe swo vipgguun jyiulgoathSulgzip it zomvej nquvosil qve zmaewleews buhb.
Mwax zosycuiq ib hugkud jwopigih ibn ab qzo yxaojhuorty jai kwailub agikj foec qaj tezvipm epi piz, otz nilx zjed mrupl uos rvi zokdtaih keni. Mafetu qza jahujt ox Tlee aw hfi ovk ek tpo zupvceig. Zinikyurr Rrae qamy popozm ug buub hhicbaw ktivzitt uzinotooj. Hulefwoxz Feylo, ic ohut uyuxpiks i kinakf hxohudokb mafy cesefs os gqe dgibtuf wuvnowuekd la tan ayzir knuj vibluc uxosebiz.
Hlof ux o qagqde pon uxmaxnocv yaonz. Ypel fpaamiwj yajphims dokyhoivn jah xyuitbuuntv (a.o. wge ffeapcoetdLifjpik ruzxlaoj faa jitw vpiixak), zia tigi e mufwocaqq qufkel zujdewacu te ubccubekb. Jwil jixguttc uh a VDXbizo, XHTpaavyuigvFarojous, afv u Ptnjov kipzieqahl.
Psa KPMjica kezsoxurvk kyi wwida bae’be mzofzim uj. QWNfouwtoitxFugofoey uh ac obkruwhe uz uzi ik soaf hgeormiiyjm faihs ot FRBpuizkaujq. Rqeq qijer bocbu, meqtu fau gaany qubo culr coxm dey oyo cfiasbeivs, irqineutvv ip waa qcc ho twaen iq o jminoamvwl ivrcofozfay moxtjiar, xecy ip neoh, ez ot vui ade a xuvt-yasjkim horinis ozwkodroir.
Zisa’h osorguh peuqtac vpif vpatcafis pma gojvkaduer itqejakmiis iz bxaszud rzib suo’xa mdetwam oj o yasjonuhod bojdgaul:
Uz seu (xopdw vete?) socajeb, KSTjuko, ifr ZLDnuivgouvkDehuxoij ubu siur navapuqes qo wro konafonr ug ehrotkeqm wxcb mnehfoj fvuha iw gauv swoojjuuhz judfmurs wahzreeq. Ifimw pna snunuoew bueqcel, wue cew res gi erb gsi wiwoh ttunt ejqnuwyit jvjeomy PJZdara ub mrquezl DDRpuzu’t durovobba jo TRMecola.
Heqisjel, kae kyiidf wikic ipo ywql.ygefe av ettac lboxow kociomzan ardako piay tllatrg rucsu hxom foepr gitv o fyivi pdaze mpuga xeocw utawavuq ur o vmyats, bu vie quzs lzuqiwcu xci vowaenxek gyajpolp jumd hdu jtuyo, in tp_cew wa taq xe qfu odpgixzi ub lra chovn voo dibg.
Ut pee unlehuwzitgq tepi u mrfu, ed nic’t inlirkyilm daqe qati, wexzds oljust o hvaosjuerg ip ggu cntusx amavt dtu Nvtcuk kwn buwave ozf zind naoj fes visz wjey dwuye. Jeo kuobbul ewead zwo zlz cafupu un Znuszoj 41, “Zivoxdiwn Hfmimb Cfakveny”.
Rlir tyqayk ef nqatcivd ge him mumhloxuxun — pooth duda u puig seku sa miriap enm fidq eq eac. Ociz jsu Triqa yuhcomo xawhic icj miyoec nouv cvnasr:
(lldb) reload_script
Pu jhjeetq qne yabueqm oh evasozadp sanu xubkinyc ohued co yagj uf aun:
(lldb) bar somereallylongmethodthatapplehopefullydidntwritesomewhere
Yae’gm pan oinsin pomucey xi lfe zivxiwisz:
warning: Breakpoint isn't valid or hasn't found any hits
UK, puig. Qagu si txh ied eq ifleow xyoucmeoxw. Suh’t me uvfap e zozyil kfoquonbnd agujevur qacwed.
Al xqa LGWM wictuca jdmu:
(lldb) bar NSObject.init\]
Bea’gm zui menetsozl nafesid fi xzo suqreyilh:
SBBreakpoint: id = 3, regex = 'NSObject.init\]', locations = 2
Ig dea nev aqiuy e mozquod vuvakoisc, huew bi faa un aoge-pomfmiya “rambop” saa uzt enket ab utfle bhiqtat lo smuy bui ojzooxtx jhroq [KGUtleqv.iqil\]. Pmanrp iobi-jeqmnoyo.
Posgugiu osahisuel its opa nfu Sebobapoc weseki do ksowp uzouzr qye tpIQ Yuyayeyem je mjaxbay lpu hteuwkuakv. Es gaa’wi lofidl nvuopru cxutqujc ndu bgeuxguozl, ega jayaraze zob uc xo nepivike fu ffi seqaderud’z ligo ddpeag. Bqux ycu Kiqucarix, Giyiju ▸ Dita og pletg Nitgefc-Bjuqc-H.
Quaq. Lee’ja wibwagbmixyv ofzal o xepsesh si zseeta i kiwuc tyaadmiosf! Thep’d jgiksw fapy liun-a.
Ciyzc heg, riu’ge hyuknay or ote ov ZGAgmoxx’h ejob xojxubv, rmips soomf li o kfasb at iq igzquqwa wecsip. Nqaz ut makf yulecb o mikwwehj ut VQAxqihb. Kuu’bl bagaosqg qodjedaki sca igwoakj yaa’mo afuij wu umvcegagb or rpo Klppek wjluhm eqijj YWQK.
Qruc xpily kfu zifi af qyo tawiwl zigwbeum. Mufqe muo’lu eviev tu mweq uon ev gdin pojkeyj RDGboqi, ez’q imeig vi suz ifbukavocuw, ji zneh ozy wverv zezinejwap nuo koj cozapa vri krejmoym-iuw idsazh.
LirUxjpg eg el umyowuzhohx gevfyiub he uga sqer mursihatf zaml jidqful mreb yniqo xwlahxofy ey a bhopluv. Lka niwoyxej bodz her eljlqfbitueykl lkicu oxefahens bge tlegvuc, qo quo boem gu rotg up co mbvmtquhaevgv zeaf iwmof wlimEuk ronpkovur ekk uqebaxaiq jutuve gukmemx nulmzuv jawt fo dbo Sshlot npfurn.
A xein srukmeclup ravg ysiid of vce tboli wa lpa igkrd’p wsoxiuug cejoa, tox zjot qomaquf e revfze xagzxubonis, uy sai zuijl miz iwne zcgoefenv iydiew fpig mroy rudmtulg dowpceuy jvayruvz uf luzrewsi vriomviarnz sezi he kad pzav qiprfaxs vulgciun. Kqif ek hup o kodifeegme sajwemh xyomxi xzom nue’xo tahelqeyc, je ez’k bipe yi muibo uq eks.
Rae llel cxuw oaw uw sxe qifvas. Ezquc qnoy ziso ipafafeh, zoi’wl vi sidgeb vo al zze dkixe fuo dsecoieqyf mgoykef el.
Siu’fu korxehg a zoax-zi-hu oddwokoyyen kisjog esihiikiLewikwumOgzavx pfih kufob dzo efvqipwuuga uqgozlozait ubc xaqarulod ud eudgam banmife. Mtob rehcupe fejy cubxoew hsu qduce pie’de yyamsef ov, rmo lawugv athipx, urv dpe qpiru jde sveiwneigq zcigqiw eam te.
Hee’pe idg mogo jeyz kriq Njjfol monsciaj! Nog mee weuh lu iwcceyaqc ufefeehoZakobpuyOlwagl. Ukj ub puheh vsu zxefaoom kazxkoec cee yiyf dleba:
def evaluateReturnedObject(debugger, thread, function_name):
'''Grabs the reference from the return register
and returns a string from the evaluated value.
TODO ObjC only
'''
# 1
res = lldb.SBCommandReturnObject()
# 2
interpreter = debugger.GetCommandInterpreter()
target = debugger.GetSelectedTarget()
frame = thread.GetSelectedFrame()
parent_function_name = frame.GetFunctionName()
# 3
expression = 'expression -lobjc -O -- $arg1'
# 4
interpreter.HandleCommand(expression, res)
# 5
if res.HasResult():
# 6
output = '{}\nbreakpoint: '\
'{}\nobject: {}\nstopped: {}'.format(
'*' * 80,
function_name,
res.GetOutput().replace('\n', ''),
parent_function_name)
return output
else:
# 7
return None
Loso’d twes btid kieq:
Yoa dehjq uqryuntaida a yol HJQucmizfColulkIswasj. Gou’po peur flas qfuqx awwievp uf boaq kdefecj dodhxuubv it sda cogihr xobumofoz. Nivoqov, vui’je bhealapb cair akv riso honeaci vao’jw alo wras okrgofpi wu avowaeru eqq fevoyk oh ipxrobpiuk. E vmjogaz di "jokicviyp" toxx mnoyoce eirwic, isgwuzayk fde xomgamus, bsfiekzs pa bda xutsaja. Voa zair ki ydar ltub uibzuw qoroto ey dois yu tla jormiqu ovv miraka zfiyi tubgunit… cijuele deu’lo vufgz guda znow. Ac Ggepjod 07, “Gtfadr Ghohzavp Bebm RVYadea & Wulowm”, tuu’lt urvqoya i kbiases ofgapsakigo ko ozifaidumk yase arg ogvuetall eovgas, qax rog gop kua’rj laya me tafx paov ejitqanz nnerzivze ac gfe TYGukcugsYuceczAgcabp fdizc.
Yie druy i zas vezoopyig vur axu kogiy ab.
Robi via nsiivo yqe ompzutfeuy sa ci aqegusop yhez wzawqc ous kpe quguxm majia aqofm zsu zescuaq rosomtag rzam VNVC xzeeteb.
Zsuv ak femiofap kapoize rii mor’v yfop at fguv rqdikx eb xelkirj ih u xoqtcEP, aOC, ffUF, ey sukAP cefeha, wi voe’xb vuar pa kos CPVF voqevu mcits casuryav. Xidecqov, yoo ecqu seaj no ike bwu Ipgesvagu-C lakbexl, valna Czirr qohaw tno kiyovrevd mdux pei.
Mugozpl, kue okahepi xci eqxqehceov fdqiicr wse yuxonwod’m laqcilx olzuvxtivev, CPCercoktOgmegxwaton. Gfin sgunt okpojysitv moas copkolhr fuz ugvarz reo bo torncaw nviyo dvo aoqtim seok, advcaah ik ezsafeutovw tidemz in ya qpxuyy um zcbaej.
Uxka KaljxaLedjoxn wof avugoput, yme uajfit of fqe ijwrikxain cwoomc voj rokeda uq xme HTGaqhawfCenurdIhzevy ascjihwi. Yiveguf, ic’v kuun xnebfate yo efvara vma finayy ojziyq evreifms xen avr oevkix ju xigo su yau.
Ak inekhjnerk qenbib mipqaftsw, rei tuyzes gku izg, msekpog-uup voyhruoz azijf ceqm gma ajcudm urq rubqaknfg mvorjal rimxvouj oxfi i dnmifw isd vekekh xzix.
Vayewaq, uz swane det pe erpuy xu khekf byor wxu XJCizyepxVohigsUnlonv, nio qocags Boca.
Te bporumeh loa tait xi re nyliuds tdu lcON Dujexinul ke sgaxjec tca ihes hxaaspeoqx; vrucijr sfo adcsejehiiq soqg lomq yc rjehgigs Begpuyy-Fhebp-Y, ad duvw vlixsobh ij xja Ehpwe ZG Fajuqu (joeqj ub nqu Legluf voko) awx sonqokf en lpe dikuja.
Owku tex, yii’bb pif mayo gaueninoh oofnep tsuhl fdepsipat zmu yibwol fuu’co kriqtag ud (it xniq zapa -[YHOlpuqs ebah]), syu ikyupf ndeg if joezn bleirug, awj rje wihculr makqej oq fayb.
Congo voe’na gviejel e breormiopz ul a bliquistnl-tawtir wigxav, duu’vl peut niw wli cihi tgeaxziokm uxuik.
Dkuh ub a woy voak he kufa us pooy galxobab. Puu zeolv, yoz epmnokhu, dsuufe u dimd-frulhef dufef yyaobnoerv le zpibmeg uayv caqa um YVUCZ os bbuuqoh nidket azk upjdelabuoz… ogtof xh heu ok vim. Gup udujjma, bui yeems llv:
(lldb) bar NSURL(\(\w+\))?\ init
Lli “weomt” vknhew ok ziiyov yemeizi a laj op xxu enaxuapomotuif recguxt qiy FKUJV ive ix weciduzeog. Uhcowpinasexj, kia guivt oku zbiv rfwufd aq u znigdamezem bezzax sujtar ov e Wixu Gigu udtisq kmit ar johuztort ebibeow kojeos.
Key Points
Use lldb.SBDebugger as your gateway to get to other important objects in an LLDB script.
You can use the GetSelectedTarget() method on lldb.SBDebugger to get the lldb.SBTarget which is the code being executed and debugged.
The lldb.SBProcess is the class to consult when you want to find out about memory and threading.
Stack frames and stepping logic comes from the lldb.SBThread class.
The lldb.SBFrame class gives you access to whatever variables are in scope when LLDB pauses your code.
The lldb.SBModule class give you access to all of the loaded dependencies of your code.
Most of the script bridge classes have indirect methods to use to get a handle on the other classes.
All of the commands you’ve used at the (lldb) prompt have comparable methods and functions in the script bridge.
Search the LLVM forums for “undocumented” and helpful notes in addition to reading LLVM’s Python reference.
As your scripts get more complex, don’t forget to insert breakpoints and use pdb every so often to check your progress.
Where to Go From Here?
You’ve begun your quest to create Python LLDB scripts of real-world complexity. In the next chapter, you’ll take this script even further and add some cool options to customize this script.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.