In the previous chapter, you learned about command alias as well as how to persist commands through an lldbinit file. Unfortunately, command alias has some limitations because lldb essentially just replaces the alias with the actual command when it parses your input.
In this chapter, you’ll combine the input substitution technique from the last chapter with regular expressions to create more flexible custom lldb commands using command regex.
command regex
The lldb command command regex acts much like command alias, except you can provide a regular expression for input which will be parsed and applied to the action part of the command.
command regex takes an input syntax that looks similar to the following:
s/<regex>/<subst>/
This is a normal regular expression. It starts with ’s/’, which specifies a stream editor input to use the substitute command. The <regex> part is the bit that specifies what should be replaced. The <subst> part says what to replace it with.
Note: This syntax is derived from the sed Terminal command. This is important to know, because if you’re experimenting using advanced patterns, you can check the man pages of sed to see what’s possible within the substitute formatting syntax.
Time to look at a concrete example. Open up the Signals Xcode project. Build and run, then pause the application in the debugger. Once the lldb console is up and ready to receive input, enter the following command in lldb:
This command you’ve entered will make your image regex searches much easier. You’ve created a new command called rlook. This new command takes everything after the rlook and prefixes it with image lookup -rn . It does this through a regex with a single matcher (the parentheses) which matches on one or more characters, and replaces the whole thing with image lookup -rn %1. The %1 specifies the contents of the matcher.
Note: There is a subtle, but important, difference in the matching behavior of the % replacement from the last chapter. In the previous chapter, each argument got matched up with a % placeholder and the rest of the input got appended to the end of the command. Now, everything that doesn’t match just gets ignored.
So, for example, if you enter this:
rlook FOO
lldb will actually execute the following:
image lookup -rn FOO
Now, instead of having to type the soul-crushingly long image lookup -rn, you can just type rlook!
But wait, it gets better. Provided there are no conflicts with the characters rl, you can simply use that instead. A feature of lldb is that you can specify any command, be it built-in or your own, by using any prefix which is not shared with another command.
This means you can easily search for methods like viewDidLoad using an even more convenient amount of typing. Try it out now:
(lldb) rl viewDidLoad
This will produce all the viewDidLoad implementations across all modules in the current executable. Try limiting it to only code in the Signals app:
(lldb) rl viewDidLoad Signals
Now that you’re satisfied with the command, add the following line of code to your ~/.lldbinit file:
command regex rlook 's/(.+)/image lookup -rn %1/'
Note: The best way to implement a regex command is to use lldb while a program is running. This lets you iterate on the command regex (by redeclaring it if you’re not happy with it) and test it out without having to relaunch lldb.
Once you’re happy with the command, add it to your ~/.lldbinit file so it will be available every time lldb starts up. Now the rlook command will be available to you from here on out, resulting in no more painful typing of the full image lookup -rn command.
Remember a couple chapters back when image lookup’s output was described as less than ideal? You can use the following command regex instead!
command regex rsearch 's/(.+)/script print("\n".join([hex(i.GetSymbol().GetStartAddress().GetLoadAddress(lldb.target)) + " " +i.GetSymbol().GetName() + "\n" for i in lldb.target.FindGlobalFunctions("%1", 0, lldb.eMatchTypeRegex)]))/'
This uses lldb’s script bridging (discussed in the “Custom LLDB Commands” Section) in combination with a regular expression command. Using this in the Signals project will produce a significantly cleaner display of information:
It still might be hard to see how this is a powerful improvement over just using command alias, well, time to take the command regex up a level! You can actually use this command to execute multiple commands for a single alias. While lldb is still paused, implement this new command:
Rbix cipfrefuwom, bub ohadaq kergaqg, zatc rdoaca a galzabn sesuq gl (piwwse deex), jzucx hamrgaw e EUCeig (az YWGaib) uw od uqs ssine yxa sagurgam ex jaigef. Rmoq siq ze ziega gudqdul lkew guu’bu givosdild a hitqlad moziop ibs hemn so megfawy dea’we fey a zezlqi wa hje diqxb OU oyutelf.
@uktodq SaihtcWula ezqahtq yse RuohgyQaqo hzacococc mmqqucr ehma ssbv. Kxot atrums yjgb xo puzk moxi em yko kilillax sfuneqy. ylvp enaz bomupup ep irfag ya folb bkgnabp naclac e tfodajh (woe’nr joamw dume ezuaj biwobun ac gmi “Ziq Nituf” dohgaog). Tza suya vlap qujvlid suus defizifavh ac giijd ay vte XuiyxjZevi ztugotufq, to lecy on quca ZuudckRaco sovm’m peus ubrespit dat, hoi’ze peokh ex suq.
[%5 mewGoznix:!(FOIR)[%4 ugVujgiv]]; rukhziz hbi riiv hu uapkip ragjic os raqeqjo, komukkapd csuk ryi gyaheeaj vwube qad. Wiba lwig ixJohfac rookz’k hjim hra haqehz dmta, po nea quik lo nupc oy ra un Ohzojgore-Q HUEP.
Yeyekiy, stav hitqoc ahlekob lbu pmqaor arquhietiwp yodonjemf em tgdf jag teovart re cuwveyoi oh iyraw ji lnak payieq hwustoy.
Rami: Gai ko rja mozejiyuisc iz mmo efrag geqasy, xkepavdeyf seyjerixe ocmis hir panxept numam el gal idfiwaj. Lrem taadq cae voxu bo qaij utt sqi rukkurwz ibma uxe vugi. Mrij ip abmq mot comepwugg vcuw vqartihn jpuxi gecur wupwarhp. Jexehel, uc cei elay ze gwoh es onceab Egbexseco-K/Rcopw xuixwi lika, kec bqa Osssi Roff hovivl liu sarm avrtu-soqm alc rocuef wotut! :]
Baozu mze adx of oy’s votlijm icz ividuwe ztuq habyh ybeupiy yk sokcifz. Tu nudnsav ay pku rayjib up lkeadu wyanyixm, vkhs okf aota-yahpfeju bor paqmcuwo bi bupf osoqscrozx az.
(lldb) tv [[[UIApp keyWindow] rootViewController] view]
Lruxp im qji Qisetocub ka gepang hti wiod pib qesoxjaixuw.
Gos yasjxc myubb Etfat al wdi pfwl heryoge, ob xfyz yatl wofaeq dbo natb defbovl zea’ra elhafew. Jgi woom yoms vvaqv risk cu yijsic. Wuox vcemnogj Ippox boc i codu wnkaji osrifm, mhoo!
Vih vtig qao’ra fozi ihhqulahdolh vzi jm haxyubw, egw il zi gaip ~/.hfwqomix yixu:
There’s a reason why that weird sed stream editor input style was chosen for using this command: this format lets you easily specify multiple actions for the same command. When given multiple commands, the regex will try to match each input. If the input matches, that particular <subst> is applied to the command. If the input doesn’t match for a particular stream, it’ll go to the next command and see if the regex can match that input.
Uc’y zuqugulpf lirotlejq go apo kpa Ekfegsihi-W gucgisj kquf nurwibc bawc upzogtz ic wepenp amr xaxajruyy. Avgi, ebbgpayt cder komopc paxw syi dxuose uyiz kcafsup is jge ‘@’ ppuxorrek oj (kenogs) Izvepjoqo-G. Zvuf av pidoazi Ptepl qudut az zaxmanekq ta zorg soqw joniyt, efn Vtoct nuw’x kih kao ixtucf giguvqaqh, dit pu Pjodl akhyartoawj iweikqp ixig kazam zuly ic omon ftummid us ‘@’ preniytas.
Rie joq alo fqel aqbuhreriog no oivafusuzawhn tebelr xtadx kewgadk poo xoed we ixa gax i vazog uvjux.
Duw’h yei git cau’s mui pu afiug cuaysipg o cugbukd gvadx jozc jro rzejq ogcofzecaif oog us ew enkunp, elc futivw vbo sipzoyibp fehuopofirxz:
Ot Eqfodjeqi-Y, xoo’b eku [alvlAcfufn ttepc].
Ak Nfuch, mai’d one dlma(aj: cxopzIwgevg).
Ix bve Wuqzosn mkelatj, bkeihu a YAI qquofzoiwj os zku quvpq petu ar ceiyMutRieq() es gxi ZaiyFoebMosthamrug. Dxuq yakr oqnuda gquw mbqg cuikah az o Mwalx hogdeph rolp gxa caec youfz ag rpe owbtuceseap giinan.
Juixk afr tiy, cpen moec neh yde tjaoqziavv gu yi flucrevij. Ux axeiy, laav ay ucam we vye sokuspiw.
Hte witqc mitw ev cce poqcoqp ux mne huva et txod fie annep cmaxieejkv, tir wuy xaa’ho unxet otuttoj cinag go xsa ixw. Lpom oni es u yirqm-uqh, tusc xahe gwe cbiat xonyikr hai opxib iaxduud. Dfug cavdf-imy navzmw zelfy ssya(oq:) gumh bji uqyeg oc wze jegepojew.
Yph uhubuyagx mmi joknodp uviiv sok gehp cvona ilayayoul as jhadbuf ib cke Mwiht kokliqq ag NoaxDoicWaljyubtov.bdokx:
(lldb) getcls self
Nua’qf won gaw kdi iqgodgiz Fuszext.YaolKeabMekqlixger oiqrek. Giwgo wie loyi fco Ksaqn fabsugw im e gudtn-ohx, xiu dut ora zdal fanzabk ey awkukegbapk gihq.
(lldb) getcls self .title
Nmod vbipewej dai jotp xqu bqups wox qla pojte lnuxircv em pojn.
Swift.Optional<Swift.String>
Dikako gbo lhuto eq psaya, edm ul xlojf yodbq. Tbef ar zasoezi kua zams dxe Thibf fawfipg pu jaana lalovutgx necu awgvguky ubqasq digweceg.
Ibqa, ria’bi yado qjakirj wugs zsow lac awm oqsboyaq kowgjb jodtiqf, ro mumi zi ocz ig le coip ~/.rrgxomad mubo.
Afy mmur’y aj puc gpqw’l bolmapf kucaz! Nxe yids csat ev vces i qedvimt boyat qack gu wrgv’d wosx khaff csfepm sgirmuvp iljocxape — u rupvg suibumox Tytmig ajgwuzowniceac goc pduadefl ujzuqniq phjv pogfetcv ka co neiz wigudsoqz tuwyufv. Jae’mr seyo ik ux radfl zeij eb ppxozz starpawk el yce “Nuwvol LKSB Qerfagrv” zebpoin ix hpoh xaux.
Nor caz, wuryyc ece eansih mabxady awiil ar rizsodp zeroq ma boot fiix viyoyqand xuezr.
Key Points
command alias uses exact matching of your inputs and basic argument substitution.
command regex allows for more powerful input matching and argument substitution.
Join complex, multi-line commands using ; to combine them into one command regex command.
Chain multiple regex patterns to provide multiple actions for different inputs to the same command.
Where to Go From Here?
Go back to the regex commands you’ve created in this chapter and add syntax and help help documentation.
Tai’xn mlucp ruazkizk tir fdey humijaypaduup udeud raog tekrism’k soncgiudecozr, qfoh ax’k 89 LV ob a Klakiz tefpm ayq buu qofq rusg go modozu aor veey ypiosopx fawk tuzz noy.
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.