LLDB breakpoint syntax

前言

lldb

In order to create useful breakpoints, you need to learn how to query what you’re looking for.

There are two configurations you’ll use in this book for code hunting.

  • The first is the following:
image lookup -n "-[UIViewController viewDidLoad]

This command dumps the load address of the function for -[UIViewController viewDidLoad].

The -n argument tells LLDB to look up either a symbol or function name.
The output will be similar to below:

(lldb)  image lookup -n "-[UIViewController viewDidLoad]"
1 match found in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk//System/Library/Frameworks/UIKit.framework/UIKit:
        Address: UIKit[0x00000000001ca9a4] (UIKit.__TEXT.__text + 1868340)
        Summary: UIKit`-[UIViewController viewDidLoad]
(lldb) 
  • Another useful, similar command is this:
image lookup -rn test

This does a case-sensitive regex lookup for the word "test".

If the lowercase word "test" is found anywhere, in any function, in any of the modules (i.e. UIKit, Foundation, Core Data, etc) loaded in the current executable (that are not stripped out of a release builds... more on that later), this command will spit out the results.

4 matches found in /Users/devzkn/Library/Developer/Xcode/DerivedData/Signals-gapxmeuzbwrtezfxiurjojmtpzvt/Build/Products/Debug-iphonesimulator/Signals.app/Signals:
        Address: Signals[0x0000000100005fb0] (Signals.__TEXT.__text + 16640)
        Summary: Signals`Signals.DetailViewController.test () throws -> () at DetailViewController.swift:49        Address: Signals[0x0000000100006010] (Signals.__TEXT.__text + 16736)
        Summary: Signals`@objc Signals.DetailViewController.test () throws -> () at DetailViewController.swift        Address: Signals[0x0000000100005fb0] (Signals.__TEXT.__text + 16640)

Note:

Use the -n argument when you want exact matches (with quotes around your query if it contains spaces) and
use the -rn arguments to do a regex search.

The -n only command helps figure out the exact parameters to match a breakpoint, especially when dealing with Swift, while the -rn argument option will be heavily favored since a smart regex can eliminate quite a bit of typing — as you’ll soon find out.

Objective-C properties

Both Objective-C and Swift have specific property signatures when they’re created by the compiler, which results in different breakpoint strategies.

图片描述
verify these methods do
exist by typing the following into LLDB:

1 match found in /Users/devzkn/Library/Developer/Xcode/DerivedData/Signals-gapxmeuzbwrtezfxiurjojmtpzvt/Build/Products/Debug-iphonesimulator/Signals.app/Signals:
        Address: Signals[0x0000000100001eb0] (Signals.__TEXT.__text + 0)
        Summary: Signals`-[TestClass name] at TestClass.h:28

LLDB was also able to tell that this method was declared on line 28 in TestClass.h.

at an offset of 0x0000000100001eb0 in the __TEXT section to be exact.

Swift properties

import Foundation

class SwiftTestClass: NSObject {
  var name: String!
}
(lldb) image lookup -rn Signals.SwiftTestClass.name.setter
2 matches found in /Users/devzkn/Library/Developer/Xcode/DerivedData/Signals-gapxmeuzbwrtezfxiurjojmtpzvt/Build/Products/Debug-iphonesimulator/Signals.app/Signals:
        Address: Signals[0x000000010000ba60] (Signals.__TEXT.__text + 39856)
        Summary: Signals`@objc Signals.SwiftTestClass.name.setter : Swift.ImplicitlyUnwrappedOptional<Swift.String> at SwiftTestClass.swift        Address: Signals[0x000000010000bb20] (Signals.__TEXT.__text + 40048)
        Summary: Signals`Signals.SwiftTestClass.name.setter : Swift.ImplicitlyUnwrappedOptional<Swift.String> at SwiftTestClass.swift:28

If you wanted to set a breakpoint on this setter, you’d have to write something similar to below:

(lldb) b Signals.SwiftTestClass.name.setter : Swift.ImplicitlyUnwrappedOptional<Swift.String>
Breakpoint 2: where = Signals`Signals.SwiftTestClass.name.setter : Swift.ImplicitlyUnwrappedOptional<Swift.String> + 175 at SwiftTestClass.swift:28, address = 0x000000010a66cbcf

Try hunting for the SwiftTestClass setter and getter for the name property, at the same time, using the following regular expression query:

image lookup -rn Signals.SwiftTestClass.name
5 matches found in /Users/devzkn/Library/Developer/Xcode/DerivedData/Signals-gapxmeuzbwrtezfxiurjojmtpzvt/Build/Products/Debug-iphonesimulator/Signals.app/Signals:
        Address: Signals[0x000000010000b930] (Signals.__TEXT.__text + 39552)
        Summary: Signals`@objc Signals.SwiftTestClass.name.getter : Swift.ImplicitlyUnwrappedOptional<Swift.String> at SwiftTestClass.swift        Address: Signals[0x000000010000b9d0] (Signals.__TEXT.__text + 39712)
        Summary: Signals`Signals.SwiftTestClass.name.getter : Swift.ImplicitlyUnwrappedOptional<Swift.String> at SwiftTestClass.swift:28        Address: Signals[0x000000010000ba60] (Signals.__TEXT.__text + 39856)
        Summary: Signals`@objc Signals.SwiftTestClass.name.setter : Swift.ImplicitlyUnwrappedOptional<Swift.String> at SwiftTestClass.swift        Address: Signals[0x000000010000bb20] (Signals.__TEXT.__text + 40048)
        Summary: Signals`Signals.SwiftTestClass.name.setter : Swift.ImplicitlyUnwrappedOptional<Swift.String> at SwiftTestClass.swift:28        Address: Signals[0x000000010000bc00] (Signals.__TEXT.__text + 40272)
        Summary: Signals`Signals.SwiftTestClass.name.materializeForSet : Swift.ImplicitlyUnwrappedOptional<Swift.String> at SwiftTestClass.swift

creating breakpoints

There are several different ways to create breakpoints. The most basic way is to simply type the letter b followed by the name of your breakpoint. This is fairly easy in Objective-C and C, since the names are short and easy to type (e.g. -[NSObject init]). They’re quite tricky to type in C++ and Swift, since the compiler turns your methods into symbols with rather long names.

b -[UIViewController viewDidLoad]
Breakpoint 3: where = UIKit`-[UIViewController viewDidLoad], address = 0x000000010b9cc9a4

Regex breakpoints and scope

Another extremely powerful command is the regular expression breakpoint, rbreak, which is an abbreviation for breakpoint set -r %1. You can quickly create many breakpoints using smart regular expressions to stop wherever you want.

Going back to the previous example with the egregiously long Swift property
function names, instead of typing:

(lldb) b Signals.SwiftTestClass.name.setter : Swift.ImplicitlyUnwrappedOptional<Swift.String>
Breakpoint 6: where = Signals`Signals.SwiftTestClass.name.setter : Swift.ImplicitlyUnwrappedOptional<Swift.String> + 175 at SwiftTestClass.swift:28, address = 0x000000010c17cbcf
(lldb) rb SwiftTestClass.name.setter
Breakpoint 7: 2 locations.
(lldb) rb name\.setter
Breakpoint 8: 8 locations.
(lldb) rb '\-\[UIViewController\ '
Breakpoint 9: 699 locations.

You can simply type:
(lldb) rb SwiftTestClass.name.setter

Although this is much shorter, there is one annoyance with this breakpoint. This breakpoint will capture both the name setter as well as the Objective-C bridging method, forcing you to stop twice when this method gets called.

  • This command deletes all the breakpoints you have set.
(lldb)  breakpoint delete
About to delete all breakpoints, do you want to do that?: [Y/n] y
All breakpoints removed. (9 breakpoints)

You can limit the scope of your breakpoints to a certain file, using the -f option. For example, you could type the following:

(lldb) rb '\-\[UIViewController(\(\w+\))?\ '
Breakpoint 10: 841 locations.
(lldb)  rb . -f DetailViewController.swift
Breakpoint 11: 66 locations.

There are other ways to limit the scope of your searches. You can limit to a single library using the -s option:

(lldb) rb . -s UIKit
Breakpoint 1: 68436 locations.

click on a cell in the table view. The debugger stops on the first UIKit method this action calls. Finally, continue the debugger, and the breakpoint will no longer fire.

breakpoint delete
About to delete all breakpoints, do you want to do that?: [Y/n] y
All breakpoints removed. (1 breakpoint)
2017-11-27 10:16:50.640 Signals[20718:1454356] Appending new signal: SIGSTOP
(lldb) rb . -s UIKit -o
Breakpoint 2: 68436 locations.

Modifying and removing breakpoints

You can also name breakpoints when you create then using the -N option

  • shows the details of that breakpoint, including all locations that
    include the word "main".
(lldb) b main
Breakpoint 5: 22 locations.
(lldb) breakpoint list 5
5: name = 'main', locations = 22, resolved = 22, hit count = 0
  5.1: where = Signals`main + 4 at AppDelegate.swift:28, address = 0x0000000105e43b74, resolved, hit count = 0 
  5.2: where = Foundation`-[NSThread main], address = 0x0000000105f41353, resolved, hit count = 0 
  5.3: where = Foundation`-[NSBlockOperation main], address = 0x0000000105f52056, resolved, hit count = 0 
  5.4: where = Foundation`-[NSFilesystemItemRemoveOperation main], address = 0x0000000105f8c5d5, resolved, hit count = 0 
  5.5: where = Foundation`-[NSFilesystemItemMoveOperation main], address = 0x0000000105f8d0fd, resolved, hit count = 0 
  5.6: where = Foundation`-[NSInvocationOperation main], address = 0x0000000105fb71e1, resolved, hit count = 0 
  5.7: where = Foundation`-[NSDirectoryTraversalOperation main], address = 0x0000000105ffb8d1, resolved, hit count = 0 
  5.8: where = Foundation`-[NSOperation main], address = 0x000000010604208f, resolved, hit count = 0 
  5.9: where = UIKit`-[UIStatusBarServerThread main], address = 0x000000010768eda5, resolved, hit count = 0 
  5.10: where = UIKit`-[_UIDocumentActivityItemProvider main], address = 0x00000001076efd76, resolved, hit count = 0 
  5.11: where = UIKit`-[_UIDocumentActivityDownloadOperation main], address = 0x0000000107754a18, resolved, hit count = 0 
  5.12: where = UIKit`-[_UIGetAssetThread main], address = 0x000000010776d4a5, resolved, hit count = 0 
  5.13: where = UIKit`-[_UIFocusMoveTest main], address = 0x0000000107775cf7, resolved, hit count = 0 
  5.14: where = UIKit`-[_UIFocusSwipeTest main], address = 0x00000001078967aa, resolved, hit count = 0 
  5.15: where = UIKit`-[UIWebPDFSearchOperation main], address = 0x00000001078cec61, resolved, hit count = 0 
  5.16: where = UIKit`-[_UIFocusTest main], address = 0x00000001079eefb1, resolved, hit count = 0 
  5.17: where = UIKit`-[UIActivityItemProvider main], address = 0x0000000107a338f0, resolved, hit count = 0 
  5.18: where = ImageIO`main, address = 0x000000010d00cad6, resolved, hit count = 0 
  5.19: where = AppSupport`-[_CPPowerAssertionThread main], address = 0x000000010f5581dc, resolved, hit count = 0 
  5.20: where = AppSupport`-[CPDistributedMessagingAsyncOperation main], address = 0x000000010f55db0c, resolved, hit count = 0 
  5.21: where = JavaScriptCore`WTF::RunLoop::main(), address = 0x0000000112604080, resolved, hit count = 0 
  5.22: where = ConstantClasses`main, address = 0x0000000115042cfb, resolved, hit count = 0 
  • query all the breakpoints in your LLDB session
(lldb) breakpoint list
  • little easier on the visual senses
(lldb) breakpoint list 5 -b
5: name = 'main', locations = 22, resolved = 22, hit count = 0
  • You can also specify multiple breakpoint IDs and ranges
 (lldb) breakpoint list 1 3
(lldb) breakpoint list 1-3

You can delete a single breakpoint by specifying the ID like so

(lldb) breakpoint delete 5
1 breakpoints deleted; 0 breakpoint locations disabled.
  • our breakpoint for "main" had 20 locations. You can also delete a
    single location, like so:
(lldb) breakpoint delete 6.22
0 breakpoints deleted; 1 breakpoint locations disabled.

Where to go from here

Check out https://docs.python.org/2/lib... to learn (or relearn) regular expressions. Try figuring out how to make a case-insensitive breakpoint query.

by using the Objective-C runtime you can declare, initialize, and inject code all on the fly to help aid in your understanding of the program.
you’ll learn about the expression command. This allows you to execute arbitrary code in the debugger.

阅读 2.2k

推荐阅读

showed you how to dynamically load them in LLDB;showed you how to modify or execute Swift or C c...

5 人关注
66 篇文章
专栏主页