Painted levels: being fostered fostered fostered

Tags: “Xcode Console debug” “iOS debug Console” “iOS Console” by Xs·H


In the process of iOS project development, static analysis (Analyze), Breakpoint (Breakpoint) and Console (Console) are commonly used for code debugging, among which the core of Console debugging is the LLDB command. This article introduces the LLDB command debugging method that the author uses most frequently in his projects.

A list,

LLDB is a new generation of high-performance debuggers. It is built as a set of reusable components that can highly leverage existing libraries from larger LLVM projects, such as the Clang expression parser and LLVM disassembler. LLDB is the default debugger for Xcode on Mac OS X and supports debugging C, Objective-C and C ++ on desktop and iOS devices and emulators. All the code in the LLDB project is provided under the standard LLVM license, which is an open source “BSD-style” license. More information can be obtained from the LLDB Homepage.

Second, help

The LLDB command format is as follows: < command name > < Command Action > [- Optional [Optional value]] [Parameter 1 [Parameter 2…]]

Each part of the LLDB command is separated by Spaces. If a parameter contains Spaces, use double quotation marks to enclose the parameter; if a parameter contains double quotation marks or backslashes, use backslashes to escape the parameter.

The LLDB command has so much functionality that it is not easy or necessary to memorize all of it. Developers can use the help command to see how commands are used, or even how the help command is used.

(lldb) help help Show a list of all debugger commands, or give details about a specific command. Syntax: help [<cmd-name>] Command Options Usage: help [-ahu] [<cmd-name> [<cmd-name> [...]]] -a ( --hide-aliases ) Hide aliases in the command list. -h ( --show-hidden-commands ) Include commands prefixed with an underscore. -u ( --hide-user-commands ) Hide user-defined commands from the list. This command takes options and free-form arguments. If your arguments resemble option specifiers  (i.e., they start with a - or --), you must use ' -- ' between the end of the command options and the beginning of the arguments.Copy the code

Three, execute,

In the LLDB, the expression command is the most basic command, which is expr or e. The syntax is: expression < cd-options > —

. It executes an expression and outputs the result returned by the expression. The following is an example.

/ /! LLDB expression count (NSUInteger) $0 = 10 Execute string concatenation string method (LLDB) expression [String stringByAppendingString:@"732"] (__NSCFString *) $1 = 0x00006000006AC870 @"QiShare732" //! Change the color of the view (LLDB) expression self. The backgroundColor = [UIColor redColor] $2 = (UICachedDeviceRGBColor *) 0x0000600001d74780 (lldb) expression [CATransaction flush] //! < Because the breakpoint terminates the UI thread, executing the [CATransaction flush] command renders the modified interfaceCopy the code

Four, print,

The print command is most commonly used. It is abbreviated pri or p and has the syntax: print

. It prints variables or expressions. We can see from help print that print is really a shorthand for the expression — command: ‘print’ is an abbreviation for ‘expression –‘ where — identifies the end of options and the beginning of parameters. Other commonly used expressions are Po and call. Where Po stands for print Object, which prints an object, and call, which calls a method. The following is an example:

(lldb) expression -- self.view (UIView *) $4 = 0x00007f8ca8401690 (lldb) e self.view (UIView *) $5 = 0x00007f8ca8401690 (lldb) p self.view (UIView *) $6 = 0x00007f8ca8401690 (lldb) po self.view <UIView: 0x7f8ca8401690; frame = (0 0; 375, 812); autoresize = W+H; layer = <CALayer: 0x6000008a1dc0>> (lldb) call self.view (UIView *) $8 = 0x00007f8ca8401690Copy the code

Alternatively, the developer can specify a print format for the print command following the syntax of print/< FMT > :

p/x //! < Prints integers in hexadecimal p/d //! < Prints the integer p/u //! In signed decimal notation. < Prints the integer p/o //! In unsigned decimal. < Print the integer p/t // in octal! < Prints the integer p/a // in binary! < Print address in hexadecimal p/c //! < print character constant p/f //! < print float p/s //! < Prints the string p/r //! < Format printCopy the code

The following is an example:

(lldb) p count (NSUInteger) $0 = 10 (lldb) p/t count (NSUInteger) $1 = 0b0000000000000000000000000000000000000000000000000000000000001010 (lldb) p/o count (NSUInteger) $2 = 012 (lldb) p/x count (NSUInteger) $3 = 0x000000000000000a (lldb) p/x string (__NSCFConstantString *) $4 = 0x000000010416a0b8 @"QiShare"  (lldb) p/c string (__NSCFConstantString *) $5 = \xb8\xa0\x16\x04\x01\0\0\0 @"QiShare" (lldb) p/s string (__NSCFConstantString *) $6 = @"QiShare" (lldb) p/a string (__NSCFConstantString *) $7 = 0x000000010416a0b8 @"QiShare" @"QiShare"Copy the code

Five, the thread

Thread is a thread-related command. The syntax is thread

[

]. It can accept different optional parameters to achieve rich functions. Thread list, Thread Backtrace, and Thread Return are commonly used. Developers can view all current threads using the thread list command as shown in the following example:

(lldb) thread list
Process 4031 stopped
* thread #1: tid = 0x25cac, 0x0000000104167e23 QiDebugDemo`-[QiConsoleViewController testLLDBCommands](self=0x00007f850df0bbf0, _cmd="testLLDBCommands") at QiConsoleViewController.m:34, queue = 'com.apple.main-thread', stop reason = breakpoint 4.1
  thread #2: tid = 0x25d2f, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #3: tid = 0x25d30, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #4: tid = 0x25d31, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #5: tid = 0x25d32, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #6: tid = 0x25d33, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #7: tid = 0x25d3e, 0x00000001079f520a libsystem_kernel.dylib`mach_msg_trap + 10, name = 'com.apple.uikit.eventfetch-thread'
Copy the code

The thread backtrace command is an easy way for developers to view thread stack information, abbreviated as BT. For example, developers can view a list of stack calls when an application crashes. The following is an example.

Thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 frame #0: 0x0000000104cc2705 libobjc.A.dylib`objc_exception_throw frame #1: 0x00000001056704ec CoreFoundation`_CFThrowFormattedException + 194 frame #2: 0x00000001057a6b00 CoreFoundation`-[__NSArrayI objectAtIndexedSubscript:] + 96 * frame #3: 0x00000001043a1df7 QiDebugDemo`-[QiConsoleViewController testLLDBCommands](self=0x00007fadc7c50400, _cmd="testLLDBCommands") at QiConsoleViewController.m:33 frame #4: 0x00000001043a1d5a QiDebugDemo`-[QiConsoleViewController viewDidLoad](self=0x00007fadc7c50400, _cmd="viewDidLoad") at QiConsoleViewController.m:26 ... frame #18: 0x00000001056830be CoreFoundation`__CFRunLoopDoObservers + 430 frame #19: 0x0000000105683751 CoreFoundation`__CFRunLoopRun + 1537 frame #20: 0x0000000105682e11 CoreFoundation`CFRunLoopRunSpecific + 625 frame #21: 0x000000010ddd51dd GraphicsServices`GSEventRunModal + 62 frame #22: 0x000000010a1db81d UIKitCore`UIApplicationMain + 140 frame #23: 0x00000001043a2450 QiDebugDemo`main(argc=1, argv=0x00007ffeeb85df90) at main.m:7 frame #24: 0x0000000107858575 libdyld.dylib`start + 1Copy the code

During debugging, the developer can use the Thread Return command to terminate a method and return a desired value. The following is an example.

(lldb) thread return string
(lldb) continue
2019-02-27 17:22:47.323225+0800 QiDebugDemo[5071:222700] resultString: Qi_Share
Copy the code

Six, breakpoint

The author explained the use of breakpoints in the iOS Debugging Methods: Breakpoints article. In fact, visual breakpoints can be implemented using LLDB syntax. For example, 1, 2, 3, 4, and 5 in the figure below can all be expressed using the LLDB command.

  1. Breakpoint enable/disable
  2. Continue the program (continue)
  3. Perform next
  4. Entry method (STEP)
  5. Exit method (Finish)

In breakpoint-related operations, the breakpoint command is not often used because Xcode has integrated visual breakpoint manipulation tools. However, the breakpoint command has very powerful functions. The syntax is breakpoint

[

].

/ /! Breakpoint list //! Breakpoint set -n viewDidAppear: //! Set breakpoints for QiConsoleViewController. M file testLLDBCommands method (LLDB) breakpoint set - f QiConsoleViewController. M - n testLLDBCommands //! For QiConsoleViewController. M file line 32 code set breakpoints (LLDB) breakpoint set - f QiConsoleViewController. 32 m - l / /! Set a conditional breakpoint for the handleString: method, conditional on string! = nil (lldb) breakpoint set - handleString: -c string ! = nilCopy the code

Observation points

Whereas breakpoint is a breakpoint for methods, watchpoint is a breakpoint for addresses. Watchpoint

[

] works like KVO. It interrupts the program when something inside the property address is observed to change. The following is an example of the application scenario.

(lldb) watchpoint set variable string
Watchpoint created: Watchpoint 1: addr = 0x7ffeef497360 size = 8 state = enabled type = w
    declare @ '/Users/huangxianshuai/Desktop/Products/QiShare/QiDebugDemo/QiDebugDemo/QiConsoleViewController.m:33'
    watchpoint spec = 'string'
    new value: 0x00000001007670b8

(lldb) next

Watchpoint 1 hit:
old value: 0x00000001007670b8
new value: 0x0000000100767138

(lldb) image lookup -a 0x00000001007670b8
      Address: QiDebugDemo[0x00000001000040b8] (QiDebugDemo.__DATA.__cfstring + 32)
      Summary: @"QiShare"
(lldb) image lookup -a 0x0000000100767138
      Address: QiDebugDemo[0x0000000100004138] (QiDebugDemo.__DATA.__cfstring + 160)
      Summary: @"huang"
Copy the code

Image lookup-a is short for image lookup-address. You can view the parameter address.

conclusion

This article only lists some of the LLDB commands that the author uses on a regular basis, and these commands can actually improve debugging efficiency. More LLDB commands can be obtained from the LLDB Homepage or other network resources.


Recommended articles:

IOS Message forwarding iOS custom drag-and-drop control: QiDragView iOS custom card control: QiCardView iOS Wireshark capture iOS Charles capture QiCardView Weekly