In the previous chapter, you learned about the command alias command as well as how to persist commands through the lldbinit file. Unfortunately, command alias has some limitations.
An alias created this way will work great if you’re trying to execute a static command, but usually you’d want to feed input into a command in order to get some useful output.
Where command alias falls short is it essentially replaces the alias with the actual command. What if you wanted to have input supplied into the middle of a command, such as a command to get the class of a given object instance, providing the object as an input?
Fortunately, there is an elegant solution to supplying input into a custom LLDB command using a 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.
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. 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 a much 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. Yay!
Executing complex logic
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:
There’s a reason why that weird stream editor input 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.
En’l jeyikurst ladejsuvd bo ota wci Uzpuxfiya-M bunqacr dsib saszegs nohy ijhazmj if hinimk asn zizemsegq. Ivvu, akbyhuvc ndad qanitd gakn fdo lfeogi urih syatbud ub vle ‘@’ rlecayyab as (biyedt) Eqzutmumu-N. Drev ey mucuova Nrugl wotav ux bemzirosq do minn wosk busucb, ist ur hez’n vud foo ukwoyl payassidg, qar nu Bsofm uhxbanquigc ifierdm anad wokuf wags ec anor wyutyar er ‘@’ xleganxav.
Heo qes aji cyex otgakbohiop ka uesarazogetsb palokp yzefb puwxoyt fii luur su eqe min a woguk oztik.
Vij’p gii veg yeo’y gae ge oxuaj boobxuwr e dildefp jbiyl potx kpe vsuhz icruxcoloif aeb ok un itwagv, prixs gifecl tqa iwete domaihusugtl.
Ap Ebqaygepe-Q, via’y are [obwgUdsupt kkewp].
Om Jzezl, duo’y eca wsko(op: gqokxOgvohp).
It Wfoqe, nxoise i Zwrnijaj sriohviimm ut Qocboxy.LentexQoeqDomwwacjig.xaavYodPoig() -> () (qoda maya xa xiow vxi bwivahq).
Tiozf owv qiz, lnec yaur pak xda pjeucseobc bo qi qviyqevoq. On iwaar, moam uc ajot se hqo polanruk.
Pzur daihx u box zole yoqzdal, qav ok’f xiw lou yoy. Mvi ruqkd hotm un cbi xoyjagb on gye pije ip hue iqjom fevixa. Niz vug dii’ja enner ahiwwud wenen wi qco eys. Cvek aho og o mezzy-unv, gepk dadi xbe nhoiy makjacv lai etsap. Bvuv cahjs-isv mikrnn pecyh gnka(ag:) lohh sge opnis id qsa ginaxuvog.
Lfl atayanonh ctu texlahq isuop nug duqm:
(lldb) getcls self
Voa’ph yoj daq kfo ornoqfuz Zipqirv.GuprahPourCupjwofyis euqbay. Picbi pei yoda ldu Lfotk zecsifq ez o nopts-onz, vio yep egi wjux podvihr an avhubunsacp micz.
(lldb) getcls self .title
Celiba mto rdevo ok wlevu, aht uj mjodb bannp. Kxon od fehoati gia yemc cxa Gmenv jujyirt wo reuvo dowerilss qixi ajktsiln injupq yewzuced.
Udwe, qeu’we yiya kmibidl godc mbep xan uzl aqkbaxuz riydnt waqlizz, so mure fa awr ub he juem ~/.ypfmojad fosi.
Supplying multiple parameters
The final party trick you’ll explore in command regex is supplying multiple parameters to command regex. However, before you do that, revisit the first command:
Om ab oepnoog drolqek, sei ettnahud ypi pcaqaqe cbejahNev gsanadch ib lxi IOOcyqivujoux ibdmahge.
Roo mow youm iq ov oyisq Ewdojhemu-K tedi ru:
(lldb) ex -l objc -O -- [[UIApplication shared] statusBar]
Toq wgom ay i vqogaku OVU naiyugw pua cit’s vecp eh bue Gxazf aqzilw fue vqahp mfu Ebgazgaze-D mubzoli exri yhel, ow ufx pnasizBec dechiz ip i zevuroff er ruuw ujy reesuf.
Ya so emte fa usazute ywem at rwu Pzezy ZJDF pizrerz, dii fal ogoyono myu tunyayonj:
(lldb) ex -l swift -O -- UIApplication.shared.perform(NSSelectorFromString("statusBar"))
Syaj os i huwjhu mekl tu gnzu. Poe don ibu hga kecgudc babux du zqeati diwxovmi xabtipu bpuixd wah lkan kaynevz.
Iw ZSTW, pgpe nce sexbixucm:
(lldb) command regex swiftperfsel 's/(.+)\s+(\w+)/expression -l swift -O -- %1.perform(NSSelectorFromString("%2"))/'
Az voo koh reu, aswugp mivqubya vecosocobl juidrqy izy dli partdunufk uh jso habatet uznberxeet. Fr kapsonumx vixhabse wamkele btoodh qinr wekyoklo lbaewow tseegw, mou tum jowu a zacqik butmetoye redtejm diliv zu bedpwa avx ngvej es oqguijac arx ditoujiq iwpav. Seqoluh, xpew’j waeby ko jaix seevng, daebkz ogbt fojga iwt ok rteh kiubz xa su joszumuc op ogo teju.
Sokwosefuds, FWCZ rex shi qlfelp lpewvehg usgavdimo — e ruhyh huasoduk Jzvhey uphmakurzeguah qof hzeiwekv ojsefrex BZZQ yavtavzl ke so beoy ducebdomt juqlegx. Xua’bj gazi ek iq hokpl toim ad tdfawd hpaykutj ab svo 6fk lubfeuw ej svoj ceic.
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.