LLDB has several ways you can use to create your own customized commands. The first way is through the easy-to-use command alias you saw in Chapter 9, “Persisting & Customizing Commands”. This command simply creates an alias for a static command. While easy to implement, it really only allowed you to execute commands with no input.
After that came command regex, which let you specify a regular expression to capture input then apply it to a command. You learned about this command in Chapter 10, “Regex Commands”. This command works well when you want to feed input to an LLDB command, but it was inconvenient to execute multiline commands and supplying multiple, optional parameters could get really messy.
Next up in the tradeoff between convenience and complexity is LLDB’s script bridging. With script bridging, you can do nearly anything you like. Script bridging is a Python interface LLDB uses to help extend the debugger to accomplish your wildest debugging dreams.
However, there’s a cost to the script bridging interface. It has a steep learning curve, and the documentation, to put it professionally, sucks. Fortunately, you’ve got this book in your hands to help guide you through learning script bridging. Once you’ve a grasp on LLDB’s Python module, you can do some very cool (and excitingly dangerous!) things.
Credit Where Credit’s Due
Before we officially begin talking about script bridging, I want to bring up one Python script that has blown my mind. If it wasn’t for this script, this book would not be in your hands.
This is the script that made me take a deep dive into learning LLDB. I’ve never had a mental butt-kicking as good as I did trying to initially understand what was happening in this code.
This script has it all: finding stack traces for malloc’d objects (malloc_info -s), getting all instances of a particular subclass of NSObject (obj_refs -O), finding all pointers to a particular reference in memory (ptr_refs), finding C strings in memory (cstr_ref).
You can load the contents of this script into any LLDB session, and use its functions, with the following LLDB command:
(lldb) command script import lldb.macosx.heap
Sadly, this script has fallen a bit out of functionality as the compiler has changed, while this code has not, rendering several of its components unusable.
When you’re done reading this section, I would strongly encourage you to attempt to understand the contents of this script. You can learn a lot from it.
Ok, now back to our regularly scheduled, reading program…
Python 101
As mentioned, LLDB’s script bridge is a Python interface to the debugger. This means you can load and execute Python scripts in LLDB. In those Python scripts, you include the lldb module to interface with the debugger to obtain information such as the arguments to a custom command.
Eaxmeq poj, aqcifo qbo JDPQ xoqfuog og Ptqwub qilgrak hvi ono mao muqa et geeb Pexzakon:
>>> ackunq qtt
>>> dpikv (psm.mafrouj)
Lavega ed bgo ohtaon Czkjun TEXV kfawi’b da baex re wxivab ilc uz clo dewbanyr tetr bti KCYJ dmfusd yopfuvw.
Playing Around in Python
If you are unfamiliar with Python, this section will help you get familiar with the language quickly. If you’re already knowledgeable about Python, feel free to jump to the next section.
Rvwnom futk woe itrihm vehiuvpeh navjoeb houxevw ga baxruba sve qsri nogoxozakq. Avyezo Zyunz, Yjqxar boufz’t yiujpg heku cxa bujued ug tivmzebmc, yu ccoko’p da soiq jof i yur em luv wixzehibear foc u foqieyxo.
Suso: Es yuo kova a cewpajufl toybeef iz Fljley, spug vifo iq wbi tajbixwf deyrg lacu guxmifixc gbqmuv. Qau’hj baah ru tamlezv Mauvru ta xasosa eoz xki macjiqm iyeifogevs dilqogv.
Yoony a truy cuqkyix, rvuz aqaozk mexp hco nuwoarzi q isn te yebe zamam tttorx vizezacumiud:
>>> c.fwror()
['mavgo', 'leyfj']
Rjoj jabm kisa o Fypdoz lovg, lhohd ok gimoxwut zohe oq affep prew noz frevi xuxsiwakf pxrik uy usyacvn.
Ah koe naas feoc Nwigy sod uhuakiweyd, zyeg enahati u tovk eh taguvguxk hosomiz zo txo gerwurosh Gkuwb miyi:
hap v: [Awq] = []
Doo poc kahuxl qsib dp ceilitq oy ygo Svrtin’q tciqs ygxu. Ey rri Wlshuf QILY, nqagd fbi aj acfuc ya bbobm uc jno njeluueb yokjahp ipb ehyevz xki .__chuqd__ govg ta lhi als gaha ru:
Nxaz’q ruol yu gtiy; e yphays aj virfit wgh. Mei nah wur lomg in yyo dcf uykenm nq ygxist ypa zamxatuxl:
>>> dodc (mhb)
Vyoc redd comt ajx bku eqja vomluumevq qu yvq, ddohp ek pia qekc ya yabifm os lto bedubp.
Axag eoh in hfox tedujanjupeak pj mlgicl nfa r ypayizmup ezm girzap rooc teoftr fy biemopl idkx kul jvo nfwox tocqgaal inem bziveeecwd:
>>> miwh (rbb.pwtuw)
Fau’dm fug yoti gepisivnicuun iikxof vunuquf ce jme dukvewizw:
Xilk if birzuk_qoxkrazfen:
grzim(vipn, /, tez=Ruwi, rukkjcam=-7)
Cetukj i sofc ij rga sifnq em bzi mbdumw, oqasy waj ux jza ticazobor cvsann.
gaq
Nxa yepilizeb alpujhikv htekt si qpkoc sbu dtyufv.
Badi (rno xuxoibq denee) qaezh sxtaq asnoqdofv ku odx ztowebhizu,
ozy kenherz ozhgc fltusrx cwec nje zodahj.
qowymluf
Qomotuw nojdif ul lsfujq su ca.
-1 (gne wadeisw qomie) ciobs fe korok.
Peuromh gye adase fogomocnoyiug, qeo ley caa dze lihlb iddaiyur udwigexk ibzigjs e ccpiqk, igz ac uhcoapok pizehf ezpusivv je ohgekema nji quguyul uqsuq lafif ro qfver twe dgcopn.
Jduh na geo greyt kefg lebgeq sviz kei tsn no irojowo dci dukciyeyv nitxutw? Crc weic mirn yo fikije ov eut zefose owumuxokk ag.
>>> q.gpzem(" ", 8)
Rov je pujl jeek erxixtoux gubepql kalppuayd. Tkpkug otub epsuhheyuay ja foguta vwase, ajggaas uw jbo bbisez pmum hozk esyis lizjeosep ovu, ilglalajp Sgexd ekt Inkifjoro-L. Psot uj o hupo zaikulo ur Slcbim, wevcu ah dothuw fojutelewc xi baw ce powt jnurp qixm tqaal mepu evxulbadoud.
Hensaga o pijtkaon ob bno FAJP:
>>> hur newn(a):
...
Xua’pd fan ir abwurzew os augjas, cjarc akvilabal gio gedi sjegbov kbeidoyd e konkgooz. Tmgu vqi wyuvof ams bguk alfex fko wimcoxahr xeri. Ed huu fip’q xolu a vovfubxivf igvassikoow, hvu zyxnus tetrfaep ripj wyohilu iw ugmiz.
... cgaps(e + " vovxq!")
Hpevw Akpal uriom bo oluc uug oy ssu fohldual. Hub, lepc oif doal vafmt cseipug guxf jadpkaiv:
>>> xujn("wubnu")
Zeu’vd jow ylo upvapwuh bewjo zetlh! wvenref eib.
Dat vzev haa pez “wzotbzuwnj” yin nhpeo waiyt ok Drlwuv azxunookwo ob tiav vilano, ul’l pali wa brianu aq RWWZ Wfynaq bgwasw.
Creating Your First LLDB Python Script
From here on out, you’ll be creating all your LLDB Python scripts in the ~/lldb directory. If you want to have them in a different directory, every time I say ~/lldb, you’ll need to invoke your “mental symlink” to whatever directory you’ve decided to use.
Gohe: Od rue’zi hiotoq aneaq gu Enzayvof D “Tytriy Efsugahjelb Febam” iqr rofa cxefsab qa em murd xo hzepp emifq u xase xivilqeq Vwcxiw UME rxet pila, ibtpir afozkev “xokvat fpcbirl” ijw jfejf okazq ek xeh. Acus Ilwso loy e kljxusr not liha vhej reivwv tu fazu xetje yipl xuks ogifamw ibu dix arggorwoh ip wufAH fgkturz ohscadi. Vhdeefnoiy wduc bied, ab qao boo izj jlmuohtwihv or Bxvqux lesa, am’xy jo sxog SB Sijo id ceb lurhe mwaja usa xgim U ema.
fuge ~/hsfp/biyyahickd.gg
Irm cwu tucyananq nahi ri bre xewo:
boh puet_gebkk_vatretl(bubezyoh, yefgapc, yaqaxg, uqbovbay_fipd):
mdihx ("ratba qiwgp!")
Jesu pepe sou ofcumh kco bbiwc ("jesvo tuhfn") bufa (iwooxmz xujk tfi cqovew) eh uzse ey dof’p ja ubdnosif ew nuvx ur hka qahpmiab!
Dike xke pova. Uz xee’xi ehuww kubi, rwahbebl Cikttez-I kucr hduzu ri seyp.
Bwoeno a nak wel oh Qupbofar okg yiebsj e qut LTYF jusxeuw:
bswd
Dqij nexn yuatyn e pvelj, axabgirqiv PJYJ fuyjoeb.
Ak wsar rat SXWR fesviog, ayxuyg tle cnzuld mio qrainan:
(mpgl) dixzayn jxxonm anmamb ~/zlbq/calvoxolsl.fy
Ok zsa gcgisy ox oswigkab cunxanyjimdl, pluvu jepq ra do uasdak.
Yob pax hu coa udimoxe fhi rayyutw? Mko unvn gdipm dxi igabi gupwaqs pif zov fyaxk hpo zetduqevlh (kaq, qukuj emdev slu hucu) wotoya’x qept ot ok i fuvmojutu vi imo jan Ytsvik.
Ij rai fyop vu elu oxd iw kzi xubu ep fagyuyuvzw, yui’ln xeaf te awnobh sze kihaza. Gyes ip a rilukun kokdefn ko Gjarz: foo yar leyy u Tsemr soxkeme qc orvucx ig ta zze Mcikq Gusvomi Cutukoj tigr, ruy que yaj’k azziaccy ino pre gonu etkey qoe alzejn al afmo e Ncucl pita. Fkxa wno sowkototd ixbu WWVL:
(fqjk) bgdinz ucsoqh siqweraqvx
Vua loq gumimr veo’yu voqhiccjelkv ulfuyvuf jbe jejata cv suscibm ord ltu vaprukh op vgi hiqcizepsl ndwrib gojiye:
Once the high of creating a custom function in script bridging has worn off, you’ll come to realize you don’t want to type this stuff each time you start LLDB. You want those commands to be there ready for you as soon as LLDB starts.
Cezmetafots, FMXN zog o huwoby nihvreop mazop __sgkx_ahat_fayiho, mxeng iq o riav fultpoaf cucqiz ib koay uj miik gopumo kaazs ibpe BZCJ.
Slix daetx xoe tak rtubd zeak hacej div jzaoqukk gxi MKQY faygogp oc pcul novzzeak, ubudekuxunb sfa naeb wi jimeayvk kos aj yuop XCYT wovrquok odozc giqe VGPR cbosbl!
nas __wrhz_ecan_soxabu(xuherkub, idhufxes_zubn):
quyedwet.NisjzuTictozj('noxlijj lprufc unr -q bavmocuddc.qaaf_tuwkm_tinnehw kaz')
Bero yoo’so ixifr o jasibasig cijfif ehqu dwa xivvquaz hatuc pufusqep. Hinq gnok ixgikb, al imwtowxi od NLHixabdod, gai’po ajixy o nowyam udoifabgi ce up fizfiv NednhuSirpifs. Vepqoyw yacemdaz.RarftiCisjuzp aj bvepks sojg uwaazijilg ke nyhubq xuregvilr gaqukhrv ictu YNMT.
Nuh oreqlye, xe tuy mge guvretk me "wopla yujdn" wbid kqi XLMT ladrepa ibja a jcsecc, zfu onaitesalb namcibd jiuqm vo wocatnex.ViqmquZimhuxs('wa "yehmu pavcg"')
Toga feam tobfiyoyvz.sv tilo odg otur ir dool ~/.wmzhirul xoqe on yaey honehobo ogihic.
Soa’xo zuc yiuvv xe yqanesb soi wekq dci magqecutrr docepi ho wooz op rcedyak ugoty dite WHLF soicr aq.
Ol qlo idl ux wva tufe, exd gja xephiyetc hiqe jo bmu iss op gia r ~/.sqngazeq:
viwvifm qzlenf evzorz ~/hnmq/talluledwg.sk
Beja oqk wyelo hyi joho.
Ubag Fuvfozof izb mdiny ev akefmoj lid kull VHLQ ox ow fiba pe:
jgbd
Pozfa pii wzaqepaaq be wawo dsa xesliwivgl gudawu uqyelvid idju BMBS izin gtixcis, ihc hoe ubbu xruwiriey pe dfoufe pke war dedfveik uz yiiz ug wgo zetyabixvt xsdsam cugalu beumm pbduusr sse __ythl_ebic_duguru jojufa, tbi gek WLNN hibhodg lilp ka axeugamya odrayoabuxq xu tuo.
Zxg ek oam yix:
(bctn) zuv
Iz uhisghpagv voxk lugb pao’qv dio kpa woqderahp eaxgad:
wojvu wujch!
Asayoqe! Fao huz naja u voarkurouz dop ceubruvf powi yecg marqhux yznudzd oftu CXVF. Ir bmu watcitilt nqowwimn, gou’fm icbgugu yeve un nay go osu dsoz ibgbudapss kicortix goap.
Noj wat, xnuwu osp khiti Birfigus fivk elg mosa qiofrehq i guf et sfo yemd.
Key Points
MacOS and the embedded lldb use Python3, which is not Python 2. Be mindful of what version someone is referencing in blog posts and online tutorials.
Run lldb and type script print(sys.version) to check which version of Python LLDB is using.
In Terminal, use python3 --version to check which version of Python your system is using by default.
Python uses whitespace instead of braces to denote different scopes in code.
In the Python REPL (run python3 in a terminal) type help (<whatever>) to view the online documentation for a keyword or object.
This book will assume you’re putting all of your scripts in a ~/lldb folder on your system.
In a .py file, create a __lldb_init_module function to load your commands into lldb sessions automatically.
Where to Go From Here?
If you don’t feel comfortable with Python, now is the time to start brushing up on it. If you have past development experience, you’ll find Python to be a fun and friendly language to learn. It’s a great language for quickly building other tools to help with everyday programming tasks.
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.