Advanced+apple+debugging (9)

Source: Internet
Author: User
Tags aliases

In the previous chapters, you learned to create aliases for commands and save them in the Lldbinit file. Unfortunately, there are some limitations to command aliases.
Aliases created in this way can perform well if you use a static command, but sometimes you want to enter some content in the command to get some useful output.
The essence of using a command alias is to replace the alias with an actual command. If you want to enter something in the middle of a command, such as a command to get the class of an object instance, provide the object you want to enter?
A very poor solution is to use a command alias to do the following (please never do this):

(LLDB) po id $INPUT = @ "INPUT test";
(LLDB) Command alias Getcls po-l objc-o--[$INPUT class]
This creates a temporary variable called $input in Lldb and then uses $input to get the class. But this is a bad way. You have to re-declare a $input every time, which completely violates the purpose of using shortcut commands.
However, don't despair-there is an elegant solution that can support input.

Command regular

Command-regex commands in Lldb are actually much like command aliases, unless you can provide a regular expression for the input that will be executed as part of the command.
Command regex brings an input syntax similar to the following:

s/<regex>/<subst>/
This is an ordinary regular expression. It starts with s/, which specifies that a stream editor will replace the input as a replacement command .<regex> the part that will be replaced, and the <subst> part is the part that is used for the substitution.

Note: This syntax is derived from the sed Terminal command. It is important to know this, because if you try to use advanced mode, you can sed look at the home page to see what might be in the replacement format syntax.
It's time to look at a specific example. Open the signals Xcode project. Build and run, and then pause the application in the debugger. Once the LLDB console appears and is ready to accept input, enter the following in the LLDB:

(lldb) command regex Rlook ' s/(. +)/image lookup-rn%1/'
This command you enter will make your image regular search easier. You have created a new command called Rlook. This new command takes everything behind Rlook and uses image Lookup-rn as its prefix. This command does this by replacing all content within the regular expression (parentheses) that can match one or more characters with image Lookup-rn%1. %1 indicates what this match is to.
So, for example, you entered something like this:

Rlook FOO
What the LLDB actually does is the following:

Image Lookup-rn FOO
Now you can replace the input long image lookup-rn command by simply entering Rlook.
But wait a minute, it's getting better now! If there is no conflict with the RL character, you can also use the RL character instead. You can specify any command that can be built-in or your own, as long as there are no conflicting prefixes with other commands.
This means that you can search for the Viewdidload method with a cleaner input. Let's try it now:

(LLDB) RL Viewdidload
This extracts the implementation of Viewdidload in all modules in the current executable file. Try scoping the search to Viewdidloadapp:

(LLDB) RL Viewdidload signals
Now that you are convinced of this command, the following line of code is added to the ~/.lldbinit file:

Command regex Rlook ' s/(. +)/image lookup-rn%1/'
Note: The best way to implement a regular command is to implement it with LLDB in a program run. This allows you to repeat the declaration in the command (when you are not satisfied with it) and to test it without restarting Lldb. If you are satisfied with the command, add it to the ~/.lldbinit file so that lldb can be used every time you start it.
From now on Rlook becomes available, and you no longer have to enter the full command of the headache image lookup-rn. Great!

Perform complex logic

It is time to raise the regular expression of a command by one level. You can actually execute multiple instructions with an alias for a command. Now LLDB should still be paused, enter this new command:

(LLDB) command regex--TV ' s/(. +)/expression-l Objc-o--@import
Quartzcore; [%1 sethidden:! (BOOL) [%1 Ishidden]]; (void) [Catransaction
flush];/'
This is a complex and useful command that will create a command called TV (toggle view) that can be toggled between UIView (or NSView) when the debugger pauses.
This command consists of three lines of code:

@import quartzcore, import the Quartzcore framework in the debugger's address space. This is necessary because the debugger understands what you are doing only after you have declared the code. You need to execute the code in the Quartzcore framework, which has not been imported before, but has now been imported.
[%1 sethidden:! (BOOL) [%1 Ishidden]];, which toggles the view from visible to invisible, depending on whether the previous state is visible or invisible. Note that Ishidden does not know the type of the return value, so you need to convert it to a bool value in Objective-c.
The last line of code is, [Catransactionflush], which refreshes the catransaction queue. The control UI in the debugger, which is commonly referred to as a screen, does not reflect any changes until the debugger continues to execute. However, this method will update the results performed in Lldb without needing continue to show visual changes.
Note: Multiple lines of input are not allowed due to the constraints of the input parameters, so you have to put all the instructions in one line of code. This is hard to see when manually controlling the regular command, but it is necessary. However, if you have Objective-C/Swift done this in the source code, then Apple God may use many times the review severely punished you!
If LLDB is still paused, execute the newly created TV command:

(LLDB) TV [[[Uiapp Keywindow] rootviewcontroller] view]
Page100image13312.png

Check the emulator to make sure the view is gone.
Now simply press ENTER in LLDB and LLDB will repeat the last instruction you executed earlier. The view refreshes to its previous state.
Now that you have implemented the TV command, add it to the ~/.lldbinit file.
Command regex--TV ' s/(. +)/expression-l Objc-o--@import quartzcore;
[%1 sethidden:! (BOOL) [%1 Ishidden]]; (void) [Catransaction flush];/'
Link Regular input

This command chose to use the grotesque stream editor input for a reason: This format allows you to easily specify multiple actions in a single command. When multiple instructions are given, the regular expression will try to match each input. If the input matches, the content is applied to the <subst> part of the instruction. If the input does not match to the specified stream, He will go to the next command and see if the regular expression matches those inputs.
It is generally necessary to use the OBJECTIVE-C environment when dealing with objects in memory or in registers. Because, any statement that begins with square brackets [or @ characters] is inside the objective-c. This is because Swift is difficult to handle in-memory data, and it does not allow you to access registers, nor does it start at [or @] when dealing with swift expressions.
You can use this information to automatically detect what environment is required for a given input.
Let's take a look at how you should build a command that gets the object class information:
? In Objective-c, you should use [Objcobject class].
? In Swift, you should enter (Of:swiftobject).
In Xcode, create a breakpoint (don't forget the middle space) at Masterviewcontroller.viewdidload ()-> ().

Page101image17376.png

Build and run, wait for the breakpoint to be triggered. As usual, go to the debugger.
First, the implementation of the new command Getcls Objective-c is constructed.
(lldb) command regex getcls ' s/([0-9]|\$|\@|[). )/CPO [%1 class]/'
Wow, this regular expression is going to take our eyes. Let's break it down:
First, there is an internal grouping that says in the start section you can match the following characters:
? [0-9] means a number that can be 0-9.
? \$ means that the $ literal will be matched
? \@ means that the literal of @ will be matched
? [means that the literal will be matched
Characters that begin with the above content will generate a match. Followed.
To produce a match for one or more characters.
As a whole, it means a number or a $ sign or an @ sign or a [symbol, followed by any character that follows the result of the command and runs the CPO [%1 class]. Again,%1 is replaced by the first match in the regular expression. Here, the whole command. The internal match (matching a number, $, and so on) will be used as%2.
Now use a set of commands to experiment with the GETCLS command to see how it works:

(LLDB) getcls @ "Hello World"
Nscfstring
(LLDB) getcls @[@ "Hello World"]
Nssingleobjectarrayi
(LLDB) Getcls [Uidevice Currentdevice]
Uidevice
(LLDB) CPO [Uidevice Currentdevice]
<UIDevice:0x60800002b520>
(LLDB) Getcls 0x60800002b520
Uidevice
It's amazing!
However, this can only handle references that are matched by commands in the OBJECTIVE-C environment. For example, try the following:

(LLDB) Getcls self
You will get an error:

Error:getcls
This is because the regular expression does not match the content you entered. Let's add a match to other forms of input in getcls. Now enter the following in the LLDB:

(lldb) command regex getcls ' s/([0-9]|\$|\@|[). *)/CPO [%1 class]/' s/
(. +)/expression-l Swift-o--type (of:% 1)/'
It looks more complicated, but it's not too bad. The first part of this command is the same as the one you added earlier. But now you have added another regular expression at the end. This regular expression captures all the input, just like the Rlook command you added. The instructions for all the content captured here are simply called type (of:) with the input content as the parameter.
Execute this command again with self:

(LLDB) Getcls self
You will get the desired signals.masterviewcontroller output. Given that you're in the swift environment, you can use this command in another interesting way.

(LLDB) getcls self. Title
Notice that there is a space in the middle and the command still works. This is because you tell the SWIFT environment to get all characters except the line break.
Once you've completed the exercise and improved the GETCLS command, don't forget to add it to the ~/.lldbinit file.

Limitations of the command regularization

The commands in Lldb are somewhat limited in the number of creative applications. The LLDB command has a restriction that you can apply only one parameter to <subst>. This means that your high-level commands that support multiple parameters will not escape this limitation.
Fortunately, Lldb has a script bridging interface-a feature that is implemented entirely by Python to implement advanced LLDB instructions during debugging. In the following chapters you will learn more about script bridging.
But for now, simply use command alias or command regex to meet your debugging needs.

Why do we have to learn this?

Back in this chapter you have created and added a regular expression command for grammar and help documents.
As mentioned earlier, you will thank yourself for providing these help documentation to remind you of the functionality of the commands you created earlier.

Advanced+apple+debugging (9)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.