preface

The LLDB is not a Low Level Debugger, but a lightweight high performance Debugger. Xcode has it built in by default, so you don’t need to install it yourself. The author has also studied the usage of LLDB systematically recently, and has used P and Po before, haha 😄. The purpose of this article is to record and summarize the LLDB recently learned, so as to deepen memory and facilitate future search.

In addition, this article has two main parts, one is the basic usage of LLDB, and the other is the extension of the basic LLDB with plug-ins.

Basic LLDB usage

P, Po, print, expression

First, let’s look at the relationship between these common commands. First look at the expression directive.

expression

  1. Prints information about variables
  2. Execute a statement such as:expression a = 100Again, you can try it hereexpression self.view.backgroundColor = [UIColor redColor], can also modify the background color.
  3. through$Symbols define and use LLDB variables such as:expression int $b = 99.

P may be too easy to remind people of print, many people would think that P is short for print, Po is short for print object, but it is not the case. Both p and print are short for expression –, which can be viewed using the help command.

Po is not an abbreviation for print Object (which is not written as such). Po is an abbreviation for expression -o –, which can also be viewed using the help command.

help expression
expression -O --
-O
Description

breakpoint

Breakpoint debugging is often used in daily development, and it is easy to set, disable, and remove breakpoints in Xcode. Let’s take a look at how to use LLDB to reach and exceed interface breakpoints.

To set breakpoints

The parameters and meanings of breakpoints are often set.

abbreviations The full name meaning
-f –file The file name
-l –line The number of rows
-n –name The method name
-S –selector SEL
-r –func-regex Methods regular
  1. Set a breakpoint at line 28 of the viewController.m file.
/ / for
breakpoint set -f ViewController.m -l 28
Copy the code
  1. Let’s give the method name thetaclick1:Method to set a breakpoint.
breakpoint set -n click1:
Copy the code
  1. To SELclick2:Method to set a breakpoint.
breakpoint set -S click2:
Copy the code
  1. To containclickTo set a breakpoint.
breakpoint set -r click
Copy the code

The effect is as follows:

  1. toViewController.mThe file containsclickTo set a breakpoint.
breakpoint set -f ViewController.m -r click
Copy the code

Breakpoint set is too long for the LLDB to spell. You can just use B.

View all current breakpoints

// Abbreviate: br list
breakpoint list
Copy the code

Note that since all three breakpoints are set using a single statement, they are grouped into the same breakpoint group.

Invalid setting breakpoint

This step is equivalent to making the breakpoint color translucent in the interface operation.

// Setting breakpoint 14.1 is invalid
br disable 14.1
// Again, set invalid breakpoints to valid
br enable 14.1
Copy the code

Remove breakpoints

br delete 14.3
Copy the code

Doesn’t it feel 666? In fact, these things are rarely used, hahaha. In forward development, breakpoints can be set and removed using interface actions provided by Xcode. In reverse, these symbols (class name, file name, method name, etc.) are not available at all. Don’t believe it? Take a look at the image below:

Memory breakpoint

In reverse, we can’t set breakpoints directly from symbols because we can’t get symbols. What if we still need breakpoints? Down memory breakpoints.

Here, at the breakpoint on line 24, we get the address of the _name pointer and pass

watchpoint set expression 0x000000014b80b880
Copy the code

Set a memory breakpoint for the _name variable, then c– >continue over the breakpoint, click button 1, where _name = @” ABC “; When the statement is called, old value and new value are printed because the space the _name points to has changed.

variable

Here is a bit of a trick, the variable’s memory address is also directly obtained by the symbol, and this is only a demonstration of variable memory breakpoint, so how to break the method memory breakpoint? Suppose I now want to create a breakpoint for the click2: method, then I need to evaluate it like this:

  1. So let’s find the value of ASLR.
  2. Use MachOView or Hooper to open the MachO file of your App.
  3. Use ASLR+ method address in MachO file = method address in memory.
  4. Test the following to see if click2 really breaks: method. Click button 2 and notice that the program stops at this method. The breakpoint is set successfully.

Other common LLDB commands

image list

We used this command above to view the ASLR of the MachO file. “Image” is a mirror image. It can be understood that each MachO is an image, the main program is an image, and each dynamic library linked by the main program is also an image. Image list is to print all image information in App. The address of each image information is the first address of this image in memory, which is also the ASLR of this image.

bt

Click2 :,click2:, click3:, set a breakpoint in click3:, click button 1, enter the bt command as follows:

Frame Select [call stack number]Copy the code

View the details of the call stack, including the memory address of the caller, the method called, the memory address of the parameter, and so on.

up
down

C, N, S

This is easy, as shown below:

LLDB plug-in extension

Xcode’s LLDB can be extended by plug-ins to make LLDB simpler and more powerful.

chisel

The easiest way to install Chisel is to use Homebrew. Using a MAC, it is very useful to install a Homebrew. However, it is a foreign server, so it is very slow to install and update, and even prone to error. For this, we can use domestic sources.

Here is a way to install using a domestic source by the terminal executing the following statement. If you’re not using ZSH, try changing ZSH to bash.

/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
Copy the code

After Homebrew is installed, chisel is installed using the command below the direct terminal.

brew install chisel
Copy the code

/Users/[username]/.lldbinit /Users/[username]/.lldbinit

command script import /usr/local/ Cellar/chisel 2.0.0 / libexec/FBLLDB pyCopy the code

After chisel is installed, try chisel’s extension to LLDB.

pviews

Get all view class objects recursively and print them out according to the view hierarchy.

pvc

Print all current controller objects and hierarchy. So I’m going to change the code a little bit here, and I’m going to jump to the NextViewController when I click blank.

ViewController
NextViewController
state
The state of the ViewController is black

caflush

To refresh the UI. During dynamic debugging, we might modify the layout of UI controls, and use CafLush to refresh the view directly.

Fv and FVC

F –>find, these two commands are used to find views and viewControllers.

taplog

This is a little bit more cool, just type in Taplog, and you’ll see that it works, click on any button, and it’ll print out the information about the button that was clicked.

presponder

Print out the responder chain.

pclass

Prints the inheritance of the class to which the object belongs.

pactions

Find the actions that the button responds to directly from the memory address of the button.

methods

Prints all the methods and properties of the class to which the object belongs. Similar to class-dump functionality.

flicker

Make the control corresponding to the memory address flash on the phone.

vs

Make the memory address corresponding control turn translucent red, and enter an edit mode, use

  • W: Locate the parent view of the current view.
  • S: Locate the first subview of the current view.
  • A: Locate the previous sibling view of the current view.
  • D: Locate the next sibling view of the current view.
  • P: Displays information about the located view.
  • Q: Exit this editing mode.

There are other features that can be viewed using the help command.

conclusion

This article mainly records

  1. Xcode provides the LLDB.
  2. How to set breakpoints in reverse.
  3. Use the plug-in Chisel to extend the LLDB functionality (more reverse-friendly).

This paper addresses https://juejin.cn/post/6844904142419263502