欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

LLDB 调试命令、插件和技巧

最编程 2024-03-01 22:07:01
...

原生

p/po 命令

  • p 打印基本数据类型的值,查看对象返回对象的指针地址(不可以用宏)。
  • po 打印对象的描述,常量、变量、表达式返回的对象等。
(lldb) p p1
(Person *) $0 = 0x000061200023130
(lldb) po p1
<Person *): 0x000061200023130>

e 命令

给具体变量赋值。

if dataArray.count == 0 {
	 print("dataArray is empty")
}

if 处断点,控制台输入 e dataArray.count = 0 回车,继续运行即可。

call 命令

动态调用函数。

(lldb) po cell.contentView.subviews
<__NSArrayM 0x60800005f5f0>(
<UILabel: 0x7f91f4f18c90; frame = (5 5; 300 25); text = '2 - Drawing index is top ...'; userInteractionEnabled = NO; tag = 1; layer = <_UILabelLayer: 0x60800009ff40>>,
<UIImageView: 0x7f91f4d20050; frame = (105 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 2; layer = <CALayer: 0x60000003ff60>>,
<UIImageView: 0x7f91f4f18f10; frame = (200 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 3; layer = <CALayer: 0x608000039860>>
)
(lldb) call [label removeFromSuperview]
(lldb) po cell.contentView.subviews
<__NSArrayM 0x600000246de0>(
<UIImageView: 0x7f91f4d20050; frame = (105 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 2; layer = <CALayer: 0x60000003ff60>>,
<UIImageView: 0x7f91f4f18f10; frame = (200 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 3; layer = <CALayer: 0x608000039860>>
)

动态将 cell 的某个子视图移除。

bt 命令

打印线程的堆栈信息(bt all 打印全部线程堆栈信息)。

(lldb) bt 
* thread #1: tid = 0x27363, 0x000000010d204125 TestDemo`-[FifthViewController tableView:cellForRowAtIndexPath:](self=0x00007f91f4e153c0, _cmd="tableView:cellForRowAtIndexPath:", tableView=0x00007f91f5889600, indexPath=0xc000000000400016) + 2757 at FifthViewController.m:91, queue = 'com.apple.main-thread', stop reason = breakpoint 6.1
* frame #0: 0x000000010d204125 TestDemo`-[FifthViewController tableView:cellForRowAtIndexPath:](self=0x00007f91f4e153c0, _cmd="tableView:cellForRowAtIndexPath:", tableView=0x00007f91f5889600, indexPath=0xc000000000400016) + 2757 at FifthViewController.m:91
frame #1: 0x0000000111d0a7b5 UIKit`-[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 757
frame #2: 0x0000000111d0aa13 UIKit`-[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
frame #3: 0x0000000111cde47d UIKit`-[UITableView _updateVisibleCellsNow:isRecursive:] + 3295
frame #4: 0x0000000111d13d95 UIKit`-[UITableView _performWithCachedTraitCollection:] + 110
frame #5: 0x0000000111cfa5ef UIKit`-[UITableView layoutSubviews] + 222
frame #6: 0x0000000111c61f50 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1237
frame #7: 0x00000001117a5cc4 QuartzCore`-[CALayer layoutSublayers] + 146
(lldb)

image 命令

列出当前 App 中的所有 module,可以查看某一个地址对应的代码位置。

image lookup -address

查找崩溃位置

0   CoreFoundation                      0x0000000103209b0b __exceptionPreprocess + 171
1   libobjc.A.dylib                     0x00000001079db141 objc_exception_throw + 48
2   CoreFoundation                      0x000000010313effb -[__NSArrayM objectAtIndex:] + 203
3   DiDi                                0x00000001009a9f3a -[FW_MyHomeTableView tableView:cellForRowAtIndexPath:] + 1322
4   UIKit                               0x00000001055a2ab2 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 750
5   UIKit                               0x00000001055a2cf8 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
6   UIKit                               0x0000000105577639 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2845
7   UIKit                               0x00000001055abccc -[UITableView _performWithCachedTraitCollection:] + 111
8   UIKit                               0x0000000105592e7a -[UITableView layoutSubviews] + 233
9   UIKit                               0x00000001054f955b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1268
10  QuartzCore                          0x0000000105114904 -[CALayer layoutSublayers] + 146

image lookup -a 0x00000001009a9f3a
      Address: DiDi[0x0000000100609f3a] (DiDi.__TEXT.__text + 6323194)
      Summary: DiDi`-[FW_MyHomeTableView tableView:cellForRowAtIndexPath:] + 1322 at FW_MyHomeTableView.m:243

当遇到 crash 时,查看线程栈,只能看到栈帧的地址,使用 image lookup –address 地址 可以方便的定位到这个地址对应的代码行。

image lookup -name

查找方法来源。

(lldb) image lookup -n transformOtherModelToSuit:
1 match found in /Users/xxx/Library/Developer/Xcode/DerivedData/DiDi-cwpbvvyvqmeijmcjnneothzuthsy/Build/Products/Debug-iphonesimulator/DiDi.app/DiDi:
        Address: DiDi[0x0000000100293d60] (DiDi.__TEXT.__text + 2693664)
        Summary: DiDi`+[FW_BetFunction transformOtherModelToSuit:] at FW_BetFunction.m:107

image lookup –type

查看成员

(lldb) image lookup -t MatchEvent
1 match found in /Users/xxxx/Library/Developer/Xcode/DerivedData/DiDi-cwpbvvyvqmeijmcjnneothzuthsy/Build/Products/Debug-iphonesimulator/DiDi.app/DiDi:
id = {0x00433d32}, name = "MatchEvent", byte-size = 48, decl = MatchEvent.h:11, compiler_type = "@interface MatchEvent : NSObject{
    BOOL _isHome;
    NSString * _playerName;
    NSString * _timePoint;
    NSString * _eventType;
    NSString * _eventDesc;
}
@property ( getter = isHome,setter = setIsHome:,assign,readwrite,nonatomic ) BOOL isHome;
@property ( getter = playerName,setter = setPlayerName:,readwrite,copy,nonatomic ) NSString * playerName;
@property ( getter = timePoint,setter = setTimePoint:,readwrite,copy,nonatomic ) NSString * timePoint;
@property ( getter = eventType,setter = setEventType:,readwrite,copy,nonatomic ) NSString * eventType;
@property ( getter = eventDesc,setter = setEventDesc:,readwrite,copy,nonatomic ) NSString * eventDesc;
@end"

breakpoint

breakpoint set -f xxx -l xxx

(lldb) breakpoint set -f FW_ProfilesDetailModel.m -l 95
Breakpoint 3: where = DiDi`-[FW_ProfilesDetailModel incomeRate] + 27 at FW_ProfilesDetailModel.m:96, address = 0x0000000105b404bb

breakpoint set -n func name

(lldb) breakpoint set -n viewDidLoad
Breakpoint 4: 414 locations.
???? Tips: 这里要说一下,xcode 其实也有函数名断点,不过用 breakpoint set -n 实现,比 xcode 下断点快 N 倍,不过 xcode 下的断点还给提示所有断到的位置。

breakpoint set -n "-[类名 方法名]"

(lldb) breakpoint set -n "-[FW_MyHomeViewController viewDidLoad]"
Breakpoint 8: where = DiDi`-[FW_MyHomeViewController viewDidLoad] + 20 at FW_MyHomeViewController.m:58, address = 0x0000000105aec944

breakpoint set -c "xxxx"

条件断点操作。

breakpoint set -f FW_HomeCell.m -l 362 -c "width > 68"
Breakpoint 5: where = DiDi`-[FW_HomeCell_HotBill setDataSource:] + 2006 at FW_HomeCell.m:363, address = 0x000000010d22e0a6

breakpoint list

查看断点列表。

(lldb) breakpoint list
Current breakpoints:
8: name = '-[FW_MyHomeViewController viewDidLoad]', locations = 1, resolved = 1, hit count = 2
  8.1: where = DiDi`-[FW_MyHomeViewController viewDidLoad] + 20 at FW_MyHomeViewController.m:58, address = 0x0000000105aec944, resolved, hit count = 2 
9: file = '/Users/xxxx/didi-ios/DiDi/FollowWinner/Model/FW_HomeModel.m', line = 24, exact_match = 0, locations = 1, resolved = 1, hit count = 0
  9.1: where = DiDi`+[FW_HomeModel_Rank parasWithDict:limitNickLength:] + 89 at FW_HomeModel.m:24, address = 0x00000001061bc169, resolved, hit count = 0

breakpoint disable/enable

禁用/启用断点。

//禁用断点
(lldb) breakpoint disable 9
1 breakpoints disabled.
(lldb) breakpoint list
Current breakpoints:
9: file = '/Users/zmz/didi-ios/DiDi/FollowWinner/Model/FW_HomeModel.m', line = 24, exact_match = 0, locations = 1 Options: disabled 
  9.1: where = DiDi`+[FW_HomeModel_Rank parasWithDict:limitNickLength:] + 89 at FW_HomeModel.m:24, address = 0x00000001061bc169, unresolved, hit count = 0
//启用断点
(lldb) breakpoint enable 9
1 breakpoints enabled.
(lldb) breakpoint list
Current breakpoints:
9: file = '/Users/zmz/didi-ios/DiDi/FollowWinner/Model/FW_HomeModel.m', line = 24, exact_match = 0, locations = 1, resolved = 1, hit count = 0
  9.1: where = DiDi`+[FW_HomeModel_Rank parasWithDict:limitNickLength:] + 89 at FW_HomeModel.m:24, address = 0x00000001061bc169, resolved, hit count = 0

breakpoint delete

删除断点。

(lldb) breakpoint delete 8
1 breakpoints deleted; 0 breakpoint locations disabled.
(lldb) breakpoint list
Current breakpoints:
9: file = '/Users/xxxx/didi-ios/DiDi/FollowWinner/Model/FW_HomeModel.m', line = 24, exact_match = 0, locations = 1, resolved = 1, hit count = 0
 9.1: where = DiDi`+[FW_HomeModel_Rank parasWithDict:limitNickLength:] + 89 at FW_HomeModel.m:24, address = 0x00000001061bc169, resolved, hit count = 0

command alias

自定义别名。

(lldb) command alias see thread backtrace
(lldb) see 5
  thread #5
    frame #0: 0x000000010bd3544e libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x000000010bd69621 libsystem_pthread.dylib`_pthread_wqthread + 1426
    frame #2: 0x000000010bd6907d libsystem_pthread.dylib`start_wqthread + 13

command alias %1 %2

自定义别名带参数。

(lldb) command alias dlt breakpoint delete %1
(lldb) breakpoint list
Current breakpoints:
3: file = 'JSONKit.m', line = 725, exact_match = 0, locations = 1, resolved = 1, hit count = 0
  3.1: where = TEST`-[JKArray dealloc] + 20 at JSONKit.m:727, address = 0x00000001073360c4, resolved, hit count = 0
(lldb) dlt 3
1 breakpoints deleted; 0 breakpoint locations disabled.

lldb 初始化时会读取 ~/.lldbinit 文件,可以把简写命令写进此文件中。

  1. 打开终端,输入 vi ~/.lldbinit 进入文件编辑。
  2. 写入自定义内容,如:command alias 堆栈 thread backtrace
  3. 然后 ESC 键,出现冒号后输入 wqenter 键保存并退出编辑。

menthods

打印当前对象的属性和方法。

(lldb) methods p1
<Person: 0x60000003eac0> : 
in Person:
		Properties:
				@property (copy, nonatomic) NSString* name; (@synthesize name = _name;) 
				@property (nonatomic) long age; (@synthesize age = _age; )
		Instance Methods:
				- (void) eat; (0x1098bf3e0)
				- (void) .cxx_destruct; (0x1098bf4fo)
				- (id) description; (0x1098bf410)
				- (id) name; (0x1098bf430)
(NSObject . . )

pachtion

打印对象调用者及方法。

(lldb) pactions 0x7fcdhsja212728
<ViewController: 0x7fcdhsja212728>: login:

pclass

打印对象继承关系。

pcalss s
Student
		| Preson
		|		| NSObject

presponder

打印响应者链。

(lldb) presponder 0x7ff1ab5a6770
<UIView: 0x7ff1ab5a6770; frame = (75 362; 123 96); autoresize = RM+BM; layer = <CALayer: 0x7ff1ab5a10a0>>
   | <UIView: 0x7ff1ab5a6660; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7ff1ab5a23c0>>
   |    | <test.ViewController: 0x7ff1ab6380a0>
   |    |    | <UIWindow: 0x7ff1ab411de0; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x7ff1ab409a20>; layer = <UIWindowLayer: 0x7ff1ab417a90>>
   |    |    |    | <UIApplication: 0x7ff1ab528330>
   |    |    |    |    | <test.AppDelegate: 0x7ff1ab40f050>

search

搜索栈内控件及其子控件。

search UIButton
<UIButton: 0x7fc373828111; frame = (0 0; 100 90);
opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x608000221060>>

lookup 搜索,可执行正则表达式。

  • 所有 LLDB 命令

    (lldb) help
    Debugger commands:
      apropos           -- List debugger commands related to a word or subject.
      breakpoint        -- Commands for operating on breakpoints (see 'help b' for
                           shorthand.)
      bugreport         -- Commands for creating domain-specific bug reports.
      command           -- Commands for managing custom LLDB commands.
      disassemble       -- Disassemble specified instructions in the current
                           target.  Defaults to the current function for the
                           current thread and stack frame.
      expression        -- Evaluate an expression on the current thread.  Displays
                           any returned value with LLDB's default formatting.
      frame             -- Commands for selecting and examing the current thread's
                           stack frames.
      gdb-remote        -- Connect to a process via remote GDB server.  If no host
                           is specifed, localhost is assumed.
      gui               -- Switch into the curses based GUI mode.
      help              -- Show a list of all debugger commands, or give details
                           about a specific command.
      kdp-remote        -- Connect to a process via remote KDP server.  If no UDP
                           port is specified, port 41139 is assumed.
      language          -- Commands specific to a source language.
      log               -- Commands controlling LLDB internal logging.
      memory            -- Commands for operating on memory in the current target
                           process.
      platform          -- Commands to manage and create platforms.
      plugin            -- Commands for managing LLDB plugins.
      process           -- Commands for interacting with processes on the current
                           platform.
      quit              -- Quit the LLDB debugger.
      register          -- Commands to access registers for the current thread and
                           stack frame.
      reproducer        -- Commands controlling LLDB reproducers.
      script            -- Invoke the script interpreter with provided code and
                           display any results.  Start the interactive interpreter
                           if no code is supplied.
      settings          -- Commands for managing LLDB settings.
      source            -- Commands for examining source code described by debug
                           information for the current target process.
      statistics        -- Print statistics about a debugging session
      target            -- Commands for operating on debugger targets.
      thread            -- Commands for operating on one or more threads in the
                           current process.
      type              -- Commands for operating on the type system.
      version           -- Show the LLDB debugger version.
      watchpoint        -- Commands for operating on watchpoints.
    Current command abbreviations (type 'help command alias' for more info):
      add-dsym  -- Add a debug symbol file to one of the target's current modules
                   by specifying a path to a debug symbols file, or using the
                   options to specify a module to download symbols for.
      attach    -- Attach to process by ID or name.
      b         -- Set a breakpoint using one of several shorthand formats.
      bt        -- Show the current thread's call stack.  Any numeric argument
                   displays at most that many frames.  The argument 'all' displays
                   all threads.
      c         -- Continue execution of all threads in the current process.
      call      -- Evaluate an expression on the current thread.  Displays any
                   returned value with LLDB's default formatting.
      continue  -- Continue execution of all threads in the current process.
      detach    -- Detach from the current target process.
      di        -- Disassemble specified instructions in the current target. 
                   Defaults to the current function for the current thread and
                   stack frame.
      dis       -- Disassemble specified instructions in the current target. 
                   Defaults to the current function for the current thread and
                   stack frame.
      display   -- Evaluate an expression at every stop (see 'help target
                   stop-hook'.)
      down      -- Select a newer stack frame.  Defaults to moving one frame, a
                   numeric argument can specify an arbitrary number.
      env       -- Shorthand for viewing and setting environment variables.
      exit      -- Quit the LLDB debugger.
      f         -- Select the current stack frame by index from within the current
                   thread (see 'thread backtrace'.)
      file      -- Create a target using the argument as the main executable.
      finish    -- Finish executing the current stack frame and stop after
                   returning.  Defaults to current thread unless specified.
      image     -- Commands for accessing information for one or more target
                   modules.
      j         -- Set the program counter to a new address.
      jump      -- Set the program counter to a new address.
      kill      -- Terminate the current target process.
      l         -- List relevant source code using one of several shorthand formats.
      list      -- List relevant source code using one of several shorthand formats.
      n         -- Source level single step, stepping over calls.  Defaults to
                   current thread unless specified.
      next      -- Source level single step, stepping over calls.  Defaults to
                   current thread unless specified.
      nexti     -- Instruction level single step, stepping over calls.  Defaults to
                   current thread unless specified.
      ni        -- Instruction level single step, stepping over calls.  Defaults to
                   current thread unless specified.
      p         -- Evaluate an expression on the current thread.  Displays any
                   returned value with LLDB's default formatting.
      parray    -- Evaluate an expression on the current thread.  Displays any
                   returned value with LLDB's default formatting.
      po        -- Evaluate an expression on the current thread.  Displays any
                   returned value with formatting controlled by the type's author.
      poarray   -- Evaluate an expression on the current thread.  Displays any
                   returned value with LLDB's default formatting.
      print     -- Evaluate an expression on the current thread.  Displays any
                   returned value with LLDB's default formatting.
      q         -- Quit the LLDB debugger.
      r         -- Launch the executable in the debugger.
      rbreak    -- Sets a breakpoint or set of breakpoints in the executable.
      re        -- Commands to access registers for the current thread and stack
                   frame.
      repl      -- Evaluate an expression on the current thread.  Displays any
                   returned value with LLDB's default formatting.
      run       -- Launch the executable in the debugger.
      s         -- Source level single step, stepping into calls.  Defaults to
                   current thread unless specified.
      si        -- Instruction level single step, stepping into calls.  Defaults to
                   current thread unless specified.
      sif       -- Step through the current block, stopping if you step directly
                   into a function whose name matches the TargetFunctionName.
      step      -- Source level single step, stepping into calls.  Defaults to
                   current thread unless specified.
      stepi     -- Instruction level single step, stepping into calls.  Defaults to
                   current thread unless specified.
      t         -- Change the currently selected thread.
      tbreak    -- Set a one-shot breakpoint using one of several shorthand formats.
      undisplay -- Stop displaying expression at every stop (specified by stop-hook
                   index.)
      up        -- Select an older stack frame.  Defaults to moving one frame, a
                   numeric argument can specify an arbitrary number.
      v         -- Show variables for the current stack frame. Defaults to all
                   arguments and local variables in scope. Names of argument,
                   local, file static and file global variables can be specified.
                   Children of aggregate variables can be specified such as
                   'var->child.x'.  The -> and [] operators in 'frame variable' do
                   not invoke operator overloads if they exist, but directly access
                   the specified element.  If you want to trigger operator
                   overloads use the expression command to print the variable
                   instead.
                   It is worth noting that except for overloaded operators, when
                   printing local variables 'expr local_var' and 'frame var
                   local_var' produce the same results.  However, 'frame variable'
                   is more efficient, since it uses debug information and memory
                   reads directly, rather than parsing and evaluating an
                   expression, which may even involve JITing and running code in
                   the target program.
      var       -- Show variables for the current stack frame. Defaults to all
                   arguments and local variables in scope. Names of argument,
                   local, file static and file global variables can be specified.
                   Children of aggregate variables can be specified such as
                   'var->child.x'.  The -> and [] operators in 'frame variable' do
                   not invoke operator overloads if they exist, but directly access
                   the specified element.  If you want to trigger operator
                   overloads use the expression command to print the variable
                   instead.
                   It is worth noting that except for overloaded operators, when
                   printing local variables 'expr local_var' and 'frame var
                   local_var' produce the same results.  However, 'frame variable'
                   is more efficient, since it uses debug information and memory
                   reads directly, rather than parsing and evaluating an
                   expression, which may even involve JITing and running code in
                   the target program.
      vo        -- Show variables for the current stack frame. Defaults to all
                   arguments and local variables in scope. Names of argument,
                   local, file static and file global variables can be specified.
                   Children of aggregate variables can be specified such as
                   'var->child.x'.  The -> and [] operators in 'frame variable' do
                   not invoke operator overloads if they exist, but directly access
                   the specified element.  If you want to trigger operator
                   overloads use the expression command to print the variable
                   instead.
                   It is worth noting that except for overloaded operators, when
                   printing local variables 'expr local_var' and 'frame var
                   local_var' produce the same results.  However, 'frame variable'
                   is more efficient, since it uses debug information and memory
                   reads directly, rather than parsing and evaluating an
                   expression, which may even involve JITing and running code in
                   the target program.
      x         -- Read from the memory of the current target process.
    Current user-defined commands:
      alamborder    -- Put a border around views with an ambiguous layout
      alamunborder  -- Removes the border around views with an ambiguous layout
      bdisable      -- Disable a set of breakpoints for a regular expression
      benable       -- Enable a set of breakpoints for a regular expression
      binside       -- Set a breakpoint for a relative address within the
                       framework/library that's currently running. This does the
                       work of finding the offset for the framework/library and
                       sliding your address accordingly.
      bmessage      -- Set a breakpoint for a selector on a class, even if the
                       class itself doesn't override that selector. It walks the
                       hierarchy until it finds a class that does implement the
                       selector and sets a conditional breakpoint there.
      border        -- Draws a border around <viewOrLayer>. Color and width can be
                       optionally provided. Additionally depth can be provided in
                       order to recursively border subviews.
      caflush       -- Force Core Animation to flush. This will 'repaint' the UI
                       but also may mess with ongoing animations.
      dcomponents   -- Set debugging options for components.
      dismiss       -- Dismiss a presented view controller.
      fa11y         -- Find the views whose accessibility labels match labelRegex
                       and puts the address of the first result on the clipboard.
      findinstances -- Find instances of specified ObjC classes.
      flicker       -- Quickly show and hide a view to quickly help visualize where
                       it is.
      fv            -- Find the views whose class names match classNameRegex and
                       puts the address of first on the clipboard.
      fvc           -- Find the view controllers whose class names match
                       classNameRegex and puts the address of first on the
                       clipboard.
      heapfrom      -- Show all nested heap pointers contained within a given
                       variable.
      hide          -- Hide a view or layer.
      mask          -- Add a transparent rectangle to the window to reveal a
                       possibly obscured or hidden view or layer's bounds
      mwarning      -- simulate a memory warning 模拟一个内存警告
      pa11y         -- Print accessibility labels of all views in hierarchy of
                       <aView>
      pa11yi        -- Print accessibility identifiers of all views in hierarchy of
                       <aView>
      pactions      -- Print the actions and targets of a control.
      paltrace      -- Print the Auto Layout trace for the given view. Defaults to
                       the key window.
      panim         -- Prints if the code is currently execution with a UIView
                       animation block.
      pbcopy        -- Print object and copy output to clipboard
      pblock        -- Print the block`s implementation address and signature
      pbundlepath   -- Print application's bundle directory path. 打印应用bundle目录地址
      pcells        -- Print the visible cells of the highest table view in the
                       hierarchy. 打印最高层的tableview的可见cell
      pclass        -- Print the inheritance starting from an instance of any class.
      pcomponents   -- Print a recursive description of components found starting
                       from <aView>.
      pcurl         -- Print the NSURLRequest (HTTP) as curl command.
      pdata         -- Print the contents of NSData object as string.
      pdocspath     -- Print application's 'Documents' directory path. 打印应用的Documents目录路径
      pinternals    -- Show the internals of an object by dereferencing it as a
                       pointer.
      pinvocation   -- Print the stack frame, receiver, and arguments of the
                       current invocation. It will fail to print all arguments if
                       any arguments are variadic (varargs).
      pivar         -- Print the value of an object's named instance variable.
      pjson         -- Print JSON representation of NSDictionary or NSArray object 使用json格式打印字典或数组
      pkp           -- Print out the value of the key path expression using
                       -valueForKeyPath:
      pmethods      -- Print the class and instance methods of a class.
      poobjc        -- Print the expression result, with the expression run in an
                       ObjC++ context. (Shortcut for "expression -O -l ObjC++ -- " )
      pproperties   -- Print the properties of an instance or Class
      present       -- Present a view controller.
      presponder    -- Print the responder chain starting from a specific responder.
      psjson        -- Print JSON representation of Swift Dictionary or Swift Array
                       object
      ptv           -- Print the highest table view in the hierarchy.
      pvc           -- Print the recursion description of <aViewController>.
      pviews        -- Print the recursion description of <aView>.
      rcomponents   -- Synchronously reflow and update all components.
      sequence      -- Run commands in sequence, stopping on any error.
      setinput      -- Input text into text field or text view that is first
                       responder.
      settext       -- Set text on text on a view by accessibility id.
      show          -- Show a view or layer.
      slowanim      -- Slows down animations. Works on the iOS Simulator and a
                       device.
      taplog        -- Log tapped view to the console.
      uikit         -- Imports the UIKit module to get access to the types while in
                       lldb.
      unborder      -- Removes border around <viewOrLayer>.
      unmask        -- Remove mask from a view or layer
      unslowanim    -- Turn off slow animations.
      visualize     -- Open a UIImage, CGImageRef, UIView, or CALayer in
                       Preview.app on your Mac.
      vs            -- Interactively search for a view by walking the hierarchy.
      wivar         -- Set a watchpoint for an object's instance variable.
      xdebug        -- Print debug description the XCUIElement in human readable
                       format.
      xnoid         -- Print XCUIElement objects with label but without identifier.
      xobject       -- Print XCUIElement details.
      xtree         -- Print XCUIElement subtree.
      zzz           -- Executes specified lldb command after delay.
    For more information on any command, type 'help <command-name>'.
    

插件

Chisel

Facebook 开源帮助调试 iOS 应用程序的 LLDB 命令的集合。

Chisel 使用 homebrew 来安装,如果你没有安装 homebrew, 参考 homebrew

brew update
brew install chisel

安装完成按照安装日志上的提示,在 ~/.lldbinit 文件中添加一行,没有则新建。 提示类似如下:

==> Caveats
Add the following line to ~/.lldbinit to load chisel when Xcode launches:
  command script import /usr/local/opt/chisel/libexec/fblldb.py

做好上面的步骤,然后重启 Xcode 就可以尝试下了。

LLDB

与 chisel 都是用 Python 写的,其安装需要手动下载仓库,然后将仓库中 dslldb.py 文件的路径用与上述同样的方式添加到 .lldbinit 中。

扩展

pviews

打印当前层级结构。

(lldb) pviews view
<TestView: 0x18df8070; baseClass = UIControl; frame = (144 9; 126 167); layer = <CALayer: 0x18df8150>>
   | <UIView: 0x18df81d0; frame = (0 0; 126 126); userInteractionEnabled = NO; layer = <CALayer: 0x18df8240>>
   | <UIImageView: 0x18df8330; frame = (0 0; 126 126); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x18df83b0>>
   | <UILabel: 0x18df8460; frame = (0 135; 126 14); text = 'haha'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x18df7fb0>>
   |    | <_UILabelContentLayer: 0x131a3d50> (layer)
   | <UILabel: 0x18df8670; frame = (0 155; 126 12); text = 'hahaha'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x18df8730>>
   |    | <_UILabelContentLayer: 0x131bea10> (layer)
   | <UIImageView: 0x18df88d0; frame = (0 9; 28 27); hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x18df8ba0>>

pvc

递归打印 viewController 层级,利用它我们可以对 viewController 的结构一目了然。

(lldb) pvc
<TabBarController: 0x13772fd0; view = <UILayoutContainerView; 0x151b3a30>; frame = (0, 0; 414, 736)>
   | <UINavigationController: 0x1602b800; view = <UILayoutContainerView; 0x1b00aca0>; frame = (0, 0; 414, 736)>
   |   | <FirstViewController: 0x16029c00; view = <UIView; 0x1b01e1c0>; frame = (0, 0; 414, 736)>
   | <UINavigationController: 0x138c5200; view = <UILayoutContainerView; 0x1316a080>; frame = (0, 0; 414, 736)>
   |   | <SecondViewController: 0x16030400; view = <UIView; 0x2094b370>; frame = (0, 0; 414, 736)>
   |   |   | <SecondChildViewController: 0x15af6000; view = <UIView; 0x18d4e650>; frame = (0, 64; 414, 628)>
   | <UINavigationController: 0x1383ca00; view = <UILayoutContainerView; 0x13180070>; frame = (0, 0; 414, 736)>
   |   | <ThirdViewController: 0x138ddc00; view = <UIView; 0x18df6650>; frame = (0, 0; 414, 736)>
   |   |   | <ThirdChild1ViewController: 0x1393fe00; view = <UIView; 0x131ec000>; frame = (0, 0; 414, 672)>
   |   |   | <ThirdChild2ViewController: 0x138dce00; view = <UIView; 0x204075a0>; frame = (414, 0; 414, 672)>
   |   |   | <ThirdChild3ViewController: 0x138a8e00; view = <UIView; 0x20426250>; frame = (828, 0; 414, 672)>
   | <UINavigationController: 0x160eca00; view = <UILayoutContainerView; 0x152f7d90>; frame = (0, 0; 414, 736)>
   |   | <FourViewController: 0x13157cc0; view not loaded>

visualize

使用 Mac 的预览打开一个 UIImage,CGImageRef,UIView 或 CALayer。

(lldb) visualize imageView

fv & fvc

fv 和 fvc 这两个命令是用来通过类名搜索当前内存中存在的 view 和 viewController 实例的命令,支持正则搜索。

(lldb) fv scrollView
0x18d3b8c0 UIScrollView
0x137d0c50