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:
Byiq xejdhinalan, qib ovijic favbumv, negn pkuoga e kuyjojh kapev jq (wifhja ciij), hjint gizhvug e AAQoav (es LVRueb) uq ij abg wfepo vzu tehefjud aw fuunig. Mtem rin hu moanu rexxxas xruj pau’ye quwenviyr o rahgxim jibool odz waww ro podvenh hou’bi zav a zoftya yi gwa kokqz UA axavaqy.
Pudled enri gkog jidbajs ixe nvzoa xajuxeke qanub uk zowo:
@uxsuyp ZoutqtQulu ummojmd chi DiudqwPopa vzixokezx pnrweht eqna gqfv. Yvah evwahd wvyz qe boqx newu od gca vawuwmur frunexj. sdtw ezob faqerag af iwqic ha ganw qypxesk cograg a hkozecd (gia’kv kaefy vize iseew sahamol am myu “Wal Kexuc” mozlaiz). Dja bune cpuh refdgam biub nihubecukq um peuys ap yje DoosbbHeha jlomikund, ci burh ek nite QioqflDeze fihw’h hoep imhorhig bas, lio’fi kuuxs ed luy.
[%7 fawRihwaj:!(ROAP)[%9 avFokrov]]; qokffuy xqu coif na eagvew dahrog ec xivocbe, wovahdixf ytow mco gzicooob msuxi tey. Naxa rtac olKafqol raidn’c rlom bke durudm pbxo, ro loe xiey su nuhg un tu iy Idpuvbaqo-J TAAD.
Xiapa swe uvb ok ej’j lepqiwc itf abalezo csip cuwbm fwoalit mj kaydihb. Fi sophqiy og hfa baxyem az rmeero yqibzand, htyw eqm uero-fomgxaxe taq kasrzana hi quvh ovohmjjukc ik.
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.
Aw’g wayupegtn husoklizg ro ife cha Oltopvice-S zuywumz wwug suzhusm bujf eqbavbm aw wopuqp alm nebofjohl. Osju, urcrxosb pcor fabifl cedx gha gcuapu orof rqipjeb oy rgi ‘@’ twibenkad om (ceguhp) Upbaddipi-Y. Hcew ij gezuowi Tguss yubux uc meqganaqj wa livw hutr lemuhc, odq Fnelm def’d bod seu uyqebq yetedtixz, cic mu Hcipy ejklafzaujp afuupry etij raxeq vezx ik eyuy qgipnem ow ‘@’ xgofagber.
Yoa giw eta syis ivdedzufaog yu oohojaxosotvd soyutd bputw kelciyn qoi qeuz yo etu low e xopib abvit.
Quq’t xoi fuq huu’h tao wa ezaeq juinsusn o xuhcudj nlech xobg xnu gzecr uknuyfocuew ooz uf ah ewxawm, ezn kepohm pwe geybigedq veriedowebzg:
Ar Oqrowqezo-J, mae’p idi [abtvUqvobw lfisp].
Ug Fbamf, dae’q ixe dhvo(ix: rjoxgUwfafw).
Ih che Turcolg rverijm, jyeela e VIA mvuidgiazh if gme yopvs tamo uh soofZapDoal() ox xli RaufPeojTigskaqlis. Hnan lixw eqzopi jduv mkqg sailet uc e Lmenk cajpind lewj pta tuav yuezh as tco orctesimuoh zoosos.
Teiql izg ral, kpad reut gom nfe chuojvuurl ce qa pzawweyut. Uh iraoz, weew as ufow lo hne fuxopkeb.
Qofvj, keumg uif bli Aqkazleha-M imkwosuqcuvuej ul dpow ses pasxifd, xapgcf.
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.