Advanced iOS Debugging

Advanced iOS Debugging

The debug process constitutes an important part in an app's development cycle. Knowing the (right) tools and techniques means you can optimizes time and therefore costs. In this session we will see a number of techniques to optimize debugging of iOS applications exploiting the power of Xcode, LLDB and other support tools.

5a72f2b358600fbcdba1ceeaef3f5222?s=128

Massimo Oliviero

March 23, 2013
Tweet

Transcript

  1. massimo.oliviero@gmail.com Massimo Oliviero Advanced iOS Debugging @maxoly #code12

  2. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Massimo Oliviero

    Freelance Software Developer Co-founder of #pragma mark http://pragmamark.org Online web http://www.massimooliviero.net email massimo.oliviero@gmail.com twitter @maxoly slide http://www.slideshare.net/MassimoOliviero
  3. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Agenda •

    Code, some tips for standard functions • Xcode, the best tools for debugging • LLDB, your great friend • Tools, network debugging how to and more • Remote, over the air debugging
  4. Advanced iOS Debugging Code

  5. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly It all

    began... NSLog(@"Error :( %@", error); NSLog(@"User: %@", user); NSLog(@"Array: %@", array); NSLog(@"URL: %@", url); NSLog(@"Count: %i", count); NSLog(@"User %@", user); NSLog(@"Array %@", array); NSLog(@"Error :( %@", error); NSLog(@"Error :( %@", error NSLog(@"URL: %@", url); NSLog(@"Array: %@", array); NSLog(@"User: NSLog(@"User: %@", user); NSLog(@"User: %@", user); NSLog(@"User: %@", user); NSLog(@"User: %@", user); NSLog(@"User: %@", user); NSLog(@"User: %@", user);
  6. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly NSLog •

    It prints debugs output only to the console • It’s a simple native Foundation function • It’s not too bad, but It’s an ancient technique • It slows things down considerably (if not handled)
  7. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly NSLog optimization

    • Use convenient macro • Use string conversions • Try alternative frameworks
  8. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly NSLog macro

    #if defined DEBUG #define MYNSLog(s, ...) NSLog((@"%s [Line %d] " s), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__) #else #define MYNSLog(s, ...) #endif -[TestViewController viewDidLoad] [Line 33] message - (void)viewDidLoad { [super viewDidLoad]; MYNSLog(@"message"); } MyGreatApp-prefix.pch TestViewController.m Console
  9. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly NSLog macro

    • Enables DEBUG mode output only • Outputs function name and line number • Place macro into .pch file or in a header file • You can use other macros like __ FILE__ (for example)
  10. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly String conversion

    functions CGPoint point = CGPointMake(10.5f, 12.3f); NSLog(@"point: %@", NSStringFromCGPoint(point)); AdvanceDebuggingExample[3050:c07] point: {10.5, 12.3} AdvanceDebuggingExample.m Console
  11. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly String conversion

    functions Returns a string formatted to contain the data from a structure: • NSStringFromCGAffineTransform • NSStringFromCGPoint • NSStringFromCGRect • NSStringFromCGSize • NSStringFromUIEdgeInsets • NSStringFromUIOffset
  12. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Try alternative

    frameworks • CocoaLumberjack https://github.com/robbiehanson/CocoaLumberjack • NSLogger https://github.com/fpillet/NSLogger • DMLogger https://github.com/malcommac/DMLogger
  13. Advanced iOS Debugging Demo

  14. Advanced iOS Debugging Xcode

  15. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Xcode •

    Configure your Behaviors • Print more information with Arguments • Go beyond logging with Breakpoints
  16. Advanced iOS Debugging Behaviors

  17. Xcode default Behaviors Debugger bar

  18. Xcode default Behaviors Variables View Console Debugger Navigator

  19. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Xcode Behaviors

    • Match Xcode to your Workflow • Use Behaviors to control Xcode • Behaviors lets you specify what should happen when a variety of events occur (like Run)
  20. Behaviors When pauses Show Debug Navigator Show debugger views

  21. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Change default

    Behavior For example, when Running pauses: • show the Breakpoint Navigator instead of Debug Navigator • show only Variable Views • open another tab only with Console view
  22. Advanced iOS Debugging Demo

  23. Advanced iOS Debugging Arguments

  24. Arguments Product > Scheme > Edit Scheme > Arguments

  25. Core Data Logging -com.apple.CoreData.SQLDebug 1

  26. Core Data and iCloud -com.apple.coredata.ubiquity.logLevel 3

  27. Advanced iOS Debugging Breakpoints

  28. Creating and editing breakpoint

  29. Breakpoint Navigator

  30. Exception Breakpoint

  31. Symbolic Breakpoint

  32. Breakpoint Action

  33. Breakpoint action Condition to evaluate The num of time to

    ignore breakpoint before stoping Log Message Action Debugger Command Action Play sound Continue program execution
  34. Debugger Command Action po variable expr (void)NSLog(@”variable: %@”, variable) breakpoint

    set -f ADEMasterViewController.m -l 83
  35. Sharing Breakpoint Share breakpoints with the team, so that all

    can benefit from it This action will create a new directory to be committed in the repository AdvanceDebuggingExample.xcodeproj/xcshareddata/
  36. Advanced iOS Debugging Demo

  37. Advanced iOS Debugging LLDB

  38. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Why LLDB

    • Consistent Command Syntax • Scriptability with Python • Performance • ...
  39. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly LLDB Commands

    print object po [object] print variable print [variable] assign value expr [variable] = [value] (lldb) <command>
  40. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly LLDB Commands

    set breakpoint breakpoint set -f [file] -l [line] load script command script import ~/test.py evaluate expression expr <expression> <noun> <verb> [-options [option-value]] [argument [argument...]]
  41. Custom object, the problem No summary for custom object @interface

    ADEEvent : NSObject @property (nonatomic, strong) NSString *title; @property (nonatomic, strong) NSDate *when; @end ADEEvent *event = [[ADEEvent alloc] init]; event.title = @"Codemotion Conference"; event.when = [NSDate date]; Init object Custom object
  42. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Custom summary

    • Create a Python script that will instruct LLDB on how to display a summary of your custom object • Load your Python script via command line or ~/.lldbinit file
  43. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Custom summary

    import lldb def ade_summary(valobj, internal_dict): ! titleAsString = valobj.GetChildMemberWithName('_title').GetSummary() ! whenAsString = valobj.GetChildMemberWithName('_when').GetSummary() ! return 'Title: ' + titleAsString + ' - when: ' + whenAsString def __lldb_init_module(debugger, dict): debugger.HandleCommand('type summary add ADEEvent -F CustomSummaries1.ade_summary') • Create “ADEEvent_summary.py” in Xcode project • Then load script: (lldb) command script import /path/to/ADEEvent_summary.py
  44. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Console tips

    (lldb) po [self.view recursiveDescription] $7 = 0x082a2c60 <UITableView: 0x8971000; frame = (0 0; 320 504); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x8184be0>; layer = <CALayer: 0x8184570>; contentOffset: {0, 0}> | <UITableViewCell: 0x8282900; frame = (0 176; 320 44); text = '2013-03-12 21:22:34 +0000'; autoresize = W; layer = <CALayer: 0x8282a30>> | | <UITableViewCellContentView: 0x8282a60; frame = (0 0; 300 43); gestureRecognizers = <NSArray: 0x8282c30>; layer = <CALayer: 0x8282ac0>> | | | <UILabel: 0x8282e50; frame = (10 0; 280 43); text = '2013-03-12 21:22:34 +0000'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x8282ee0>> | | <UIButton: 0x8282c80; frame = (290 0; 30 43); opaque = NO; userInteractionEnabled = NO; layer = ... (lldb) po [[UIWindow keyWindow] recursiveDescription] $5 = 0x08273bc0 <UIWindow: 0x8181010; frame = (0 0; 320 568); layer = <UIWindowLayer: 0x81810e0>> | <UILayoutContainerView: 0xd06eed0; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0xd071460>> | | <UINavigationTransitionView: 0xd09e850; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W +H; layer = <CALayer: 0xd09e920>> | | | <UIViewControllerWrapperView: 0x846e160; frame = (0 64; 320 504); autoresize = W+H; layer = <CALayer: 0x846e210>> ...
  45. Advanced iOS Debugging Demo

  46. Advanced iOS Debugging Tools

  47. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Tools •

    Network Link Conditioner • Charles • PonyDebugger • Deploymate
  48. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Network Link

    Conditioner • It’s a utility that enables you to simulate network conditions • To install just select Xcode > Open Developer Tool > More Developer Tools. You’ll be taken to Apple’s developer downloads site • Download “Hardware IO Tools for Xcode”
  49. Network Link Conditioner

  50. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Charles •

    It’s a web debugging proxy • You can inspect, modify and record requests & responses • SSL Proxing (http://www.charlesproxy.com/ documentation/faqs/ssl-connections-from-within-iphone- applications/) http://www.charlesproxy.com/
  51. Charles

  52. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly PonyDebugger •

    Network Traffic Debugger • Core Data Browser • It is a client library and gateway server combination that uses Chrome Developer Tools on your browser to debug your application's network traffic and managed object contexts. https://github.com/square/PonyDebugger
  53. PonyDebugger

  54. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Deploymate •

    If using an API introduced later than your target OS but your app is targeting an older OS version, Xcode doesn't warn you about it • It helps identify unavailable, deprecated and obsolete API
  55. Deploymate

  56. Advanced iOS Debugging Demo

  57. Advanced iOS Debugging Remote

  58. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Remote debugging

    • Apple Crash Reports • PLCrashReporter • TestFlight
  59. Advanced iOS Debugging Apple Crash Reports

  60. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Apple Crash

    Reports • For app published on App Store, you can acquire crash log from iTunes Connect and import it into Organizer for symbolication • To symbolicate a crash log, Xcode needs to have access to the matching application binary that was uploaded to the App Store, and the .dSYM file that was generated when that binary was built. This must be an exact match https://itunesconnect.apple.com
  61. Apple Crash Reports

  62. Apple Crash Reports

  63. Xcode Symbolication

  64. Advanced iOS Debugging PLCrashReporter

  65. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly PLCrashReporter •

    In-process CrashReporter framework for the iPhone and Mac OS X • Handles both uncaught Objective-C exceptions and fatal signals • Backtraces for all active threads are provided https://code.google.com/p/plcrashreporter/
  66. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly - (void)

    handleCrashReport { PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter]; NSData *crashData; NSError *error; // Try loading the crash report crashData = [crashReporter loadPendingCrashReportDataAndReturnError: &error]; if (crashData == nil) { NSLog(@"Could not load crash report: %@", error); goto finish; } PLCrashReport *report = [[[PLCrashReport alloc] initWithData: crashData error: &error] autorelease]; if (report == nil) { NSLog(@"Could not parse crash report"); goto finish; } .... return; } // from UIApplicationDelegate protocol - (void) applicationDidFinishLaunching: (UIApplication *) application { PLCrashReporter *crashReporter = [PLCrashReporter sharedReporter]; NSError *error; // Check if we previously crashed if ([crashReporter hasPendingCrashReport]) [self handleCrashReport]; // Enable the Crash Reporter if (![crashReporter enableCrashReporterAndReturnError: &error]) NSLog(@"Warning: Could not enable crash reporter: %@", error); }
  67. Advanced iOS Debugging TestFlight

  68. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly TestFlight •

    Invite your testers, drop in the SDK and start uploading your builds. • Upload your builds and TestFlight takes care of the rest. Painless over-the-air distribution to your testers and distribution lists. • Complete tracking of your build, from distribution to sessions, checkpoints and crashes. https://testflightapp.com/
  69. TestFlight Apps Managment

  70. TestFlight Crashes

  71. Advanced iOS Debugging Final Thoughts

  72. Massimo Oliviero - massimo.oliviero@gmail.com - www.massimooliviero.net - @maxoly Final Thoughts

    • Don’t use NSLog anymore ;) • Create your Xcode Behaviors • Breakpoints are your friends • LLDB is a promising youngster • Tools can save your life • The QA phase is essential
  73. Advanced iOS Debugging Thank you! Massimo Oliviero massimo.oliviero@gmail.com http://www.massimooliviero.net follow

    me on twitter @maxoly http://www.slideshare.net/MassimoOliviero https://speakerdeck.com/massimooliviero