Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

More than `po`: Debugging in lldb

6,837 views

Published on

Xcode is incredibly useful for debugging iOS apps, especially with the updates released in 6.0. But sometimes that isn’t enough. Sometimes you want to find the exact error that caused the objc_exception_throw, or only activate a breakpoint with a certain method in the call stack. These cases, which are hard to debug with Xcode’s toolset, are easy with LLDB. This talk will walk through the basics of debugging in LLDB, and solutions to common problems.

Published in: Software

More than `po`: Debugging in lldb

  1. 1. More than po: Debugging in lldb @MicheleTitolo
  2. 2. lldb
  3. 3. What we’ll cover • LLDB basics • Advanced thread, breakpoint, watchpoint • Debugging with script • Swift
  4. 4. lldb commands
  5. 5. Basics
  6. 6. po
  7. 7. expr -O --
  8. 8. (lldb) po self.myCar <Car: 0x7fc8206334d0>
  9. 9. -description
  10. 10. (lldb) po self.myCar 2014 Tesla S UIDeviceRGBColorSpace 0 0 1 1
  11. 11. p
  12. 12. expr --
  13. 13. (lldb) p self.myCar.year (NSInteger) $1 = 2014
  14. 14. (lldb) p *self.myCar (Car) $1 = {
 NSObject = {
 isa = Car
 }
 _running = NO
 _make = 0x000000010077d088 @"Tesla"
 _model = 0x000000010077d0a8 @"S"
 _year = 2014
 _color = 0x00007fd531eb9e30
 _gear = Park
 }
  15. 15. use expr to modify values at runtime
  16. 16. (lldb) po self.myCar
 2014 Tesla S UIDeviceRGBColorSpace 0 0 1 1

  17. 17. (lldb) po self.myCar
 2014 Tesla S UIDeviceRGBColorSpace 0 0 1 1
 (lldb) expr self.myCar.year = 2013 (NSInteger) $0 = 2013

  18. 18. (lldb) po self.myCar
 2014 Tesla S UIDeviceRGBColorSpace 0 0 1 1
 (lldb) expr self.myCar.year = 2013 (NSInteger) $0 = 2013
 (lldb) po self.myCar
 2013 Tesla S UIDeviceRGBColorSpace 0 0 1 1
  19. 19. frame variable
  20. 20. fr v
  21. 21. (lldb) fr v (ViewController *) self = 0x00007f9628520cd0
 (SEL) _cmd = "updateTipLabelsForBillAmount:"
 (float) billAmount = 33
 (float) tipPercentage = 0.200000003
 (float) tipAmount = 6.5999999
 (float) total = 39.5999985
  22. 22. bt
  23. 23. thread backtrace
  24. 24. (lldb) bt * thread #1: tid = 0x66c2, 0x0000000101a90330 Cars`-[ViewController viewDidLoad](self=0x00007fc3d2c21570, _cmd=0x0000000102f21cfb) + 448 at ViewController.m:28, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
 * frame #0: 0x0000000101a90330 Cars`-[ViewController viewDidLoad] (self=0x00007fc3d2c21570, _cmd=0x0000000102f21cfb) + 448 at ViewController.m:28
 frame #1: 0x000000010284f090 UIKit`-[UIViewController loadViewIfRequired] + 738
 frame #2: 0x000000010284f28e UIKit`-[UIViewController view] + 27
 frame #3: 0x000000010276b5e9 UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 58
 frame #4: 0x000000010276b9af UIKit`-[UIWindow _setHidden:forced:] + 247
 frame #5: 0x0000000102778219 UIKit`-[UIWindow makeKeyAndVisible] + 42
 frame #6: 0x000000010271b727 UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2732
 frame #7: 0x000000010271e43e UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1349
 frame #8: 0x000000010271d33c UIKit`-[UIApplication workspaceDidEndTransaction:] + 179
  25. 25. step / s
  26. 26. next / n
  27. 27. thread step-out / finish
  28. 28. continue / c
  29. 29. ~/.lldbinit
  30. 30. settings set prompt [lldb]$ command alias bd breakpoint disable command alias be breakpoint enable command alias bdel breakpoint delete command alias bcommand breakpoint command add command alias commands breakpoint command list
  31. 31. help
  32. 32. help breakpoint
  33. 33. help breakpoint command
  34. 34. help breakpoint command add
  35. 35. -h --help
  36. 36. -h --help
  37. 37. Thread
  38. 38. thread info
  39. 39. (lldb) thread info thread #1: tid = 0x66c2, 0x0000000101a90330 Cars`- [ViewController viewDidLoad](self=0x00007fc3d2c21570, _cmd=0x0000000102f21cfb) + 448 at ViewController.m:28, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  40. 40. thread list
  41. 41. (lldb) thread list Process 921 stopped
 * thread #1: tid = 0x66c2, 0x0000000101a90330 Cars`- [ViewController viewDidLoad](self=0x00007fc3d2c21570, _cmd=0x0000000102f21cfb) + 448 at ViewController.m:28, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
 thread #2: tid = 0x66da, 0x0000000104bcc232 libsystem_kernel.dylib`kevent64 + 10, queue = 'com.apple.libdispatch-manager'
 thread #3: tid = 0x66dc, 0x0000000104bc651a libsystem_kernel.dylib`semaphore_wait_trap + 10, queue = 'FBSSerialQueue'
 thread #4: tid = 0x66dd, 0x0000000104bcb94a libsystem_kernel.dylib`__workq_kernreturn + 10
 thread #5: tid = 0x66de, 0x0000000104bcb94a libsystem_kernel.dylib`__workq_kernreturn + 10
 thread #6: tid = 0x66df, 0x0000000104bcb94a libsystem_kernel.dylib`__workq_kernreturn + 10
  42. 42. thread until <linenum>
  43. 43. (lldb) thread until 31 Process 1615 resuming
 (lldb)
  44. 44. thread return <expr>
  45. 45. (lldb) thread return NO (lldb) thread return [NSNumber numberWithInt:7] (lldb) thread return @"Hello"
  46. 46. Breakpoints
  47. 47. breakpoint list
  48. 48. br list
  49. 49. (lldb) br list Current breakpoints:
 1: file = 'Cars/Car.m', line = 50, locations = 1, resolved = 1, hit count = 0
 
 1.1: where = Cars`-[Car changeGearTo:] + 52 at Car.m:50, address = 0x00000001026fd4e4, resolved, hit count = 0 
 
 2: file = 'Cars/ViewController.m', line = 31, locations = 1, resolved = 1, hit count = 1
 
 2.1: where = Cars`-[ViewController viewDidLoad] + 512 at ViewController.m:31, address = 0x00000001026fcb40, resolved, hit count = 1
  50. 50. br set br modify br delete
  51. 51. (lldb) br set -f ViewController.m -l 31 Breakpoint 2: where = Cars`-[ViewController viewDidLoad] +
 512 at ViewController.m:31, address = 0x000000010e2bdb40
  52. 52. (lldb) br set -F "-[Car changeGearTo:]” Breakpoint 3: where = Cars`-[Car changeGearTo:] + 20 at
 Car.m:47, address = 0x00000001073ba4c4
  53. 53. br ~= b
  54. 54. (lldb) b ViewController.m:31
  55. 55. (lldb) br ViewController.m:31 error: command 'breakpoint' did not recognize 'ViewController .m:31' as valid (subcommand might be invalid).
  56. 56. (lldb) b Car.m:63
 Breakpoint 2: where = Cars`-[Car increaseSpeedTo:] + 118 at Car.m:63, address = 0x0000000100b7a576
 (lldb) br modify -c "speed==15" 2
  57. 57. (lldb) b Car.m:63
 Breakpoint 2: where = Cars`-[Car increaseSpeedTo:] + 118 at Car.m:63, address = 0x0000000100b7a576
 (lldb) br modify -c "speed==15" 2 (lldb) c
 Process 3093 resuming
 (lldb)
  58. 58. (lldb) br modify -c "speed==15 && self.gear==4” 2
  59. 59. (lldb) br modify -c "speed==20 && [self canChangeGearTo:4]" 2
  60. 60. (lldb) br modify -c "speed==15 && self.gear==4" -i 17 2
  61. 61. -i <count> ( --ignore-count <count> ) Set the number of times this breakpoint is skipped before stopping.
  62. 62. -i <count> ( --ignore-count <count> ) Set the minimum number of times this breakpoint is skipped before stopping.
  63. 63. (lldb) br delete 2 1 breakpoints deleted; 0 breakpoint locations disabled.
  64. 64. br enable br disable
  65. 65. (lldb) breakpoint disable 2 1 breakpoints disabled. 
 ...
 2: file = 'Cars/ViewController.m', line = 31, locations = 1 Options: disabled
  66. 66. (lldb) breakpoint enable 2 1 breakpoints enabled.
 ...
 2: file = 'Cars/ViewController.m', line = 31, locations = 1, resolved = 1, hit count = 1
  67. 67. br command
  68. 68. (lldb) br command add -o "fr v" 2 (lldb) fr v
 (Car *) self = 0x00007fb59ad142b0
 (SEL) _cmd = "changeGearTo:"
 (Gear) gear = Neutral
  69. 69. (lldb) br command add 1 Enter your debugger command(s). Type 'DONE' to end.
 > fr v
 > continue
 > DONE
  70. 70. (lldb) br command add 1 Enter your debugger command(s). Type 'DONE' to end.
 > fr v
 > continue
 > DONE
  71. 71. (lldb) br command add 1 Enter your debugger command(s). Type 'DONE' to end.
 > fr v
 > continue
 > DONE (lldb) fr v
 (Car *) self = 0x00007f8061625490
 (SEL) _cmd = "changeGearTo:"
 (Gear) gear = Reverse
 (lldb) continue
 Process 2068 resuming
 Command #2 'continue' continued the target.
  72. 72. (lldb) br command list 3 Breakpoint 3:
 Breakpoint commands:
 fr v
  73. 73. (lldb) br command delete 3
  74. 74. Watchpoints
  75. 75. a watchpoint tracks a value over time
  76. 76. …kind of like KVO!
  77. 77. [self.myCar addObserver:self
 forKeyPath:@"speed"
 options:NSKeyValueObservingOptionNew
 context:KVOContext];
 

  78. 78. [self.myCar addObserver:self
 forKeyPath:@"speed"
 options:NSKeyValueObservingOptionNew
 context:KVOContext];
 
 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
 {
 if (car.speed > 1000) {
 NSLog(@"WHY AM I GOING SO FAST %ld",
 (long)car.speed);
 }
 }
  79. 79. - (void)setSpeed:(NSInteger)speed { _speed = speed; if (_speed > 1000) { NSLog(@"WHY AM I GOING SO FAST %ld", (long)_speed); } }
  80. 80. breakpoint: place watchpoint: value
  81. 81. watchpoint set
  82. 82. watch set
  83. 83. (lldb) watch set var self.speed
 error: "self" is a pointer and . was used to attempt to
 access "speed". Did you mean "self->speed"? (lldb) watch set var self->speed
 error: "speed" is not a member of "(Car *const) self" (lldb) watch set var _speed
  84. 84. watch modify -c … -i …
  85. 85. (lldb) watch set var _speed Watchpoint created: Watchpoint 1: addr = 0x7fb9c145d768 size
 = 8 state = enabled type = w
 watchpoint spec = ‘_speed'
 new value: 0
  86. 86. (lldb) watch set var _speed Watchpoint created: Watchpoint 1: addr = 0x7fb9c145d768 size
 = 8 state = enabled type = w
 watchpoint spec = ‘_speed'
 new value: 0 (lldb) watch modify -c '(_speed==15)'
  87. 87. (lldb) watch set var _speed Watchpoint created: Watchpoint 1: addr = 0x7fb9c145d768 size
 = 8 state = enabled type = w
 watchpoint spec = ‘_speed'
 new value: 0 (lldb) watch modify -c '(_speed==15)' (lldb) c
 Process 2150 resuming

  88. 88. (lldb) watch set var _speed Watchpoint created: Watchpoint 1: addr = 0x7fb9c145d768 size
 = 8 state = enabled type = w
 watchpoint spec = ‘_speed'
 new value: 0 (lldb) watch modify -c '(_speed==15)' (lldb) c
 Process 2150 resuming
 Watchpoint 1 hit:
 old value: 0
 new value: 15
 (lldb)
  89. 89. (lldb) watch set var _speed
 Watchpoint created: Watchpoint 1: addr = 0x7fa3b2e05278 size
 = 8 state = enabled type = w
 watchpoint spec = ‘_speed'
 new value: 0
 (lldb) watch modify -c '(_speed==15)'
  90. 90. (lldb) watch set var _speed
 Watchpoint created: Watchpoint 1: addr = 0x7fa3b2e05278 size
 = 8 state = enabled type = w
 watchpoint spec = ‘_speed'
 new value: 0
 (lldb) watch modify -c '(_speed==15)' (lldb) watch command add 1
  91. 91. (lldb) watch set var _speed
 Watchpoint created: Watchpoint 1: addr = 0x7fa3b2e05278 size
 = 8 state = enabled type = w
 watchpoint spec = ‘_speed'
 new value: 0
 (lldb) watch modify -c '(_speed==15)' (lldb) watch command add 1 Enter your debugger command(s). Type 'DONE' to end.
 > p _speed
 > continue
 > DONE
  92. 92. (lldb) watch set var _speed
 Watchpoint created: Watchpoint 1: addr = 0x7fa3b2e05278 size
 = 8 state = enabled type = w
 watchpoint spec = ‘_speed'
 new value: 0
 (lldb) watch modify -c '(_speed==15)' (lldb) watch command add 1 Enter your debugger command(s). Type 'DONE' to end.
 > p _speed
 > continue
 > DONE (lldb) c
 Process 2252 resuming
  93. 93. (lldb) watch set var _speed
 Watchpoint created: Watchpoint 1: addr = 0x7fa3b2e05278 size
 = 8 state = enabled type = w
 watchpoint spec = ‘_speed'
 new value: 0
 (lldb) watch modify -c '(_speed==15)' (lldb) watch command add 1 Enter your debugger command(s). Type 'DONE' to end.
 > p _speed
 > continue
 > DONE (lldb) c
 Process 2252 resuming (NSInteger) $16 = 15
 Process 2252 resuming
 Command #2 'continue' continued the target.
  94. 94. Stopped due to an error evaluating condition of watchpoint Watchpoint 1: addr = 0x7f84d940a180 size = 8 state = disabled type = w: "(_gear==First)" error: use of undeclared identifier 'First' error: 1 errors parsing expression Watchpoint 1 hit: old value: Park new value: First
  95. 95. watch delete watch enable watch disable
  96. 96. (lldb) watch disable 1
 1 watchpoints disabled. (lldb) watch enable 1
 1 watchpoints enabled.
  97. 97. script
  98. 98. write code to debug your code
  99. 99. rdar://20054190 (Apple closed the previous one !)
  100. 100. >>> if count > 1: ... print "hello" File "<console>", line 2 print "hello" ^ IndentationError: expected an indented block >>>
  101. 101. copy + paste
  102. 102. script
  103. 103. (lldb) help script Pass an expression to the script interpreter for evaluation and return the results. Drop into the interactive interpreter if no expression is given. This command takes 'raw' input (no need to quote stuff). Syntax: script [<script-expression-for-evaluation>]
  104. 104. (lldb) script
 Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.
  105. 105. (lldb) script
 Python Interactive Interpreter. To exit, type 'quit()', 'exit()'. >>> print lldb.debugger Debugger (instance: "debugger_47", id: 47) >>> print lldb.target Cars >>> print lldb.process SBProcess: pid = 6425, state = stopped, threads = 5, executable = Cars >>> print lldb.thread SBThread: tid = 0x3813e >>> print lldb.frame frame #0: 0x0000000103075979 Cars`-[ViewController viewDidLoad](self=0x00007f8173f23680, _cmd=0x0000000104507cfb) + 57 at ViewController.m:24 >>> quit()
  106. 106. writing functions
  107. 107. def breakpoint_func(frame, bp_loc, dict): # implementation here # return false to skip
  108. 108. def breakpoint_func(frame, bp_loc, dict): # implementation here # return false to skip current stack frame
  109. 109. def breakpoint_func(frame, bp_loc, dict): # implementation here # return false to skip breakpoint location
  110. 110. def breakpoint_func(frame, bp_loc, dict): # implementation here # return false to skip python session dict
  111. 111. def breakpoint_func(frame, bp_loc, dict): # implementation here # return false to skip python session dictuseless
  112. 112. Sample Case
  113. 113. only stop when -changeGearTo: is in the call stack
  114. 114. find_in_stack = ['-[Car changeGearTo:]'] def continue_ignored(frame, bp_loc, dict): global find_in_stack names = set([frame.GetFunctionName() for frame 
 in frame.GetThread()]) all_ignored = set(find_in_stack) ignored_here = all_ignored.intersection(names) if len(ignored_here) == 0: return False quit()
  115. 115. find_in_stack = [ def names = set([frame.GetFunctionName() all_ignored = set(find_in_stack) ignored_here = all_ignored.intersection(names) return False quit() find_in_stack = ['-[Car changeGearTo:]'] stack symbol
  116. 116. find_in_stack = [ def names = set([frame.GetFunctionName() all_ignored = set(find_in_stack) ignored_here = all_ignored.intersection(names) return False quit() find_in_stack = ['-[Car changeGearTo:]'] def continue_ignored(frame, bp_loc, dict): stack symbol function declaration
  117. 117. find_in_stack = [ def names = set([frame.GetFunctionName() all_ignored = set(find_in_stack) ignored_here = all_ignored.intersection(names) return False quit() find_in_stack = ['-[Car changeGearTo:]'] def continue_ignored(frame, bp_loc, dict): global find_in_stack stack symbol function declaration global accessor
  118. 118. find_in_stack = [ def names = set([frame.GetFunctionName() all_ignored = set(find_in_stack) ignored_here = all_ignored.intersection(names) return False quit() find_in_stack = ['-[Car changeGearTo:]'] def continue_ignored(frame, bp_loc, dict): global find_in_stack names = set([frame.GetFunctionName() for frame 
 in frame.GetThread()]) stack symbol function declaration global accessor all functions in stack
  119. 119. find_in_stack = [ def names = set([frame.GetFunctionName() all_ignored = set(find_in_stack) ignored_here = all_ignored.intersection(names) return False quit() find_in_stack = ['-[Car changeGearTo:]'] def continue_ignored(frame, bp_loc, dict): global find_in_stack names = set([frame.GetFunctionName() for frame 
 in frame.GetThread()]) all_ignored = set(find_in_stack)
 ignored_here = all_ignored.intersection(names) stack symbol function declaration global accessor all functions in stack check if symbol we want is in this stack
  120. 120. find_in_stack = [ def names = set([frame.GetFunctionName() all_ignored = set(find_in_stack) ignored_here = all_ignored.intersection(names) return False quit() find_in_stack = ['-[Car changeGearTo:]'] def continue_ignored(frame, bp_loc, dict): global find_in_stack names = set([frame.GetFunctionName() for frame 
 in frame.GetThread()]) all_ignored = set(find_in_stack)
 ignored_here = all_ignored.intersection(names) if len(ignored_here) == 0:
 return False
 stack symbol function declaration global accessor all functions in stack check if symbol we want is in this stack if it isn’t, continue
  121. 121. find_in_stack = [ def names = set([frame.GetFunctionName() all_ignored = set(find_in_stack) ignored_here = all_ignored.intersection(names) return False quit() find_in_stack = ['-[Car changeGearTo:]'] def continue_ignored(frame, bp_loc, dict): global find_in_stack names = set([frame.GetFunctionName() for frame 
 in frame.GetThread()]) all_ignored = set(find_in_stack)
 ignored_here = all_ignored.intersection(names) if len(ignored_here) == 0:
 return False
 quit() stack symbol function declaration global accessor all functions in stack check if symbol we want is in this stack if it isn’t, continue
  122. 122. find_in_stack = ['-[Car changeGearTo:]'] def continue_ignored(frame, bp_loc, dict): global find_in_stack names = set([frame.GetFunctionName() for frame 
 in frame.GetThread()]) all_ignored = set(find_in_stack) ignored_here = all_ignored.intersection(names) if len(ignored_here) == 0: return False quit()
  123. 123. br command add -s python #
  124. 124. (lldb) br command add -s python 2
  125. 125. (lldb) br command add -s python 2 Enter your Python command(s). Type 'DONE' to end.
 def function(frame,bp_loc,internal_dict):
 """frame: the SBFrame for the location at which you stopped
 bp_loc: an SBBreakpointLocation for the breakpoint location information
 internal_dict: an LLDB support object not to be used"""
  126. 126. (lldb) br command add -s python 2 Enter your Python command(s). Type 'DONE' to end.
 def function(frame,bp_loc,internal_dict):
 """frame: the SBFrame for the location at which you stopped
 bp_loc: an SBBreakpointLocation for the breakpoint location information
 internal_dict: an LLDB support object not to be used""" global find_in_stack
 find_in_stack = ['-[Car changeGearTo:]']
 names = set([frame.GetFunctionName() for frame in frame.GetThread()])
 all_ignored = set(find_in_stack)
 ignored_here = all_ignored.intersection(names)
 if len(ignored_here) == 0:
 return False
 DONE
  127. 127. (lldb) br command add -s python 2 -o “print 1+1”
  128. 128. type summary
  129. 129. Use a python function to better describe a class
  130. 130. def Car_Summary(value,unused): make = value.GetChildMemberWithName("_make") model = value.GetChildMemberWithName("_model") makeSummary = make.GetSummary() modelSummary = model.GetSummary() return makeSummary + " " + modelSummary quit()
  131. 131. def make = value.GetChildMemberWithName( model = value.GetChildMemberWithName( makeSummary = make.GetSummary() modelSummary = model.GetSummary() quit() def Car_Summary(value,unused): value is the frame
  132. 132. def make = value.GetChildMemberWithName( model = value.GetChildMemberWithName( makeSummary = make.GetSummary() modelSummary = model.GetSummary() quit() def Car_Summary(value,unused): make = value.GetChildMemberWithName("_make")
 model = value.GetChildMemberWithName("_model") value is the frame get the variables we want
  133. 133. def make = value.GetChildMemberWithName( model = value.GetChildMemberWithName( makeSummary = make.GetSummary() modelSummary = model.GetSummary() quit() def Car_Summary(value,unused): make = value.GetChildMemberWithName("_make")
 model = value.GetChildMemberWithName("_model") makeSummary = make.GetSummary()
 modelSummary = model.GetSummary() value is the frame get the variables we want printable summaries
  134. 134. def make = value.GetChildMemberWithName( model = value.GetChildMemberWithName( makeSummary = make.GetSummary() modelSummary = model.GetSummary() quit() def Car_Summary(value,unused): make = value.GetChildMemberWithName("_make")
 model = value.GetChildMemberWithName("_model") makeSummary = make.GetSummary()
 modelSummary = model.GetSummary() return makeSummary + " " + modelSummary value is the frame get the variables we want printable summaries return a string
  135. 135. def make = value.GetChildMemberWithName( model = value.GetChildMemberWithName( makeSummary = make.GetSummary() modelSummary = model.GetSummary() quit() def Car_Summary(value,unused): make = value.GetChildMemberWithName("_make")
 model = value.GetChildMemberWithName("_model") makeSummary = make.GetSummary()
 modelSummary = model.GetSummary() return makeSummary + " " + modelSummary 
 quit() value is the frame get the variables we want printable summaries return a string
  136. 136. def Car_Summary(value,unused): make = value.GetChildMemberWithName("_make") model = value.GetChildMemberWithName("_model") makeSummary = make.GetSummary() modelSummary = model.GetSummary() return makeSummary + " " + modelSummary quit()
  137. 137. More Use Cases
  138. 138. • Only break after another breakpoint has been hit • Check multiple threads for a symbol • Data formatters for everything • Custom LLDB commands More Use Cases
  139. 139. swift
  140. 140. p
  141. 141. (lldb) po self.myCar <SwiftCars.Car: 0x7fe8bb456a60>
 (lldb) p *self.myCar error: <EXPR>:1:1: error: '*' is not a prefix unary operator
 *self.myCar
 ^
  142. 142. (lldb) fr v -F self.myCar
  143. 143. (lldb) fr v -F self.myCar self.myCar = 0x00007fe8bb456a60
 self.myCar =
 self.myCar.isa = SwiftCars.Car
 self.myCar.make._core._owner = nil
 self.myCar.model._core._owner = nil
 self.myCar.color = 0x00007fe8bb452c80
 self.myCar.color.isa = UICachedDeviceRGBColor
 self.myCar.color._systemColorName = 0x00007fe8bb4424c0 “blueColor"
 self.myCar.color.redComponent = 0
 self.myCar.color.greenComponent = 0
 self.myCar.color.blueComponent = 1
 self.myCar.color.alphaComponent = 1
 self.myCar.color.cachedColor = 0x0000000000000000
 self.myCar.color.cachedColorOnceToken = 0
 self.myCar.running.value = 0
 self.myCar.gear = Park
  144. 144. type summary
  145. 145. type summary
  146. 146. script
  147. 147. script
  148. 148. find_in_stack = ['SwiftCars.Car.changeGearTo'] App name
  149. 149. file a radar
  150. 150. Resources • WWDC ’13 Session 413 • WWDC ’14 Sessions 409 & 410 • http://lldb.llvm.org/ • http://www.objc.io/issue-19/lldb-debugging.html • http://blog.ittybittyapps.com/blog/2013/11/07/ integrating-reveal-without-modifying-your-xcode- project/ • https://github.com/facebook/chisel
  151. 151. Questions? @MicheleTitolo

×