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.

KKBOX WWDC17 Xcode debug - Oliver

3,567 views

Published on

KKBOX iOS 工程師 Oliver 分享
影片位置 https://youtu.be/_UQkm3iXDoA
相關 Sessions
- [Debugging with Xcode 9] (https://developer.apple.com/videos/wwdc2017/videos/play/wwdc2017/404/)
- [What's New in LLVM] (https://developer.apple.com/videos/wwdc2017/videos/play/wwdc2017/411/)
- [Finding Bugs Using Xcode Runtime Tools] (https://developer.apple.com/videos/wwdc2017/videos/play/wwdc2017/406/)
- [Understanding Undefined Behavior] (https://developer.apple.com/videos/wwdc2017/videos/play/wwdc2017/407/)

Published in: Technology
  • Be the first to comment

  • Be the first to like this

KKBOX WWDC17 Xcode debug - Oliver

  1. 1. Xcode - Debug KKBOX WWDC 2017 Study Oliver Huang iOS Engineer
  2. 2. Related Video Sessions 404 - Debugging with Xcode 9 https://developer.apple.com/videos/play/wwdc2017/404/ 406 - Finding Bugs Using Xcode Runtime Tools https://developer.apple.com/videos/play/wwdc2017/406/ 407 - Understanding Undefined Behavior https://developer.apple.com/videos/play/wwdc2017/407/ 411 - What's New in LLVM https://developer.apple.com/videos/play/wwdc2017/411/
  3. 3. Debugging with Xcode 9 • Development: Unplugged (Wireless Development) • Breakpoint Workflow Enhancements • Debug View Hierarchy Improvements
  4. 4. Wireless Development NEW
  5. 5. Wireless Development • Minimum requirement - iOS 11, tvOS 11, macOS 10.12.4+ • Tools support - Xcode, Instruments, Accessibility Inspector, Console, Configurator - (tvOS only) Safari Web Inspector for TVMLKit, QuickTime Screen Recording
  6. 6. Demo
  7. 7. Wireless Development tvOS device pairing
  8. 8. Breakpoint Workflow Enhancements • Code Completion in Text Field • Options Indicator • Deep Filtering Breakpoints
  9. 9. Demo
  10. 10. Debug View Hierarchy Enhancements • View Controller Debugging • SpriteKit Debugging • SceneKit Debugging
  11. 11. View Controller Debugging NEW
  12. 12. SpriteKit Debugging NEW SpriteKit Debugging
  13. 13. SceneKit Debugging NEW
  14. 14. Finding Bugs Using Xcode Runtime Tools Improvements in Runtime Checking
  15. 15. Improvements in Runtime Checking Runtime Issues Finding Bugs Using Xcode Runtime Tools
  16. 16. Improvements in Runtime Checking • Main Thread Checker (New) • Address Sanitizer • Thread Sanitizer • Undefined Behavior Sanitizer (New)
  17. 17. 4 Main Thread Checker
  18. 18. Designing Asynchronous APIs Let API user specify callback queue DeepThought.asyncComputeAnswer(to: theQuestion) { reply in … }
  19. 19. Designing Asynchronous APIs Let API user specify callback queue DeepThought.asyncComputeAnswer(to: theQuestion, completionQueue: queue) { reply in … }
  20. 20. Address Sanitizer • Detects use-after-scope • Detects use-after-return (opt-in) • Compatible with Malloc Scribble Finding Memory Issues Security critical bugs • Use-after-free and buffer overflows Diagnoses hard-to-reproduce crashes Advanced Debugging and the Address Sanitizer WWDC 2015
  21. 21. Use of out of scope stack memory // Use of Stack Memory Out of Scope int *integer_pointer = NULL; if (is_some_condition_true()) { int value = calculate_value(); integer_pointer = &value; } *integer_pointer = 42;
  22. 22. // Use of Stack Memory after Return int *returns_address_of_stack() { int a = 42; return &a; } int *integer_pointer = returns_address_of_stack(); *integer_pointer = 43;
  23. 23. Thread Sanitizer • Race on collections • Swift access races What is Thread Sanitizer Multithreading issues Finds races even if they did not manifest 64-bit macOS, 64-bit simulators Thread Sanitizer and Static Analysis WWDC 2016
  24. 24. // Thread 1 eventLog.log(source: networkingSubsystem, message: "Download finished") // Thread 2 eventLog.log(source: databaseSubsystem, message: "Query complete") Thread 2: Data race in EventLog.log(source:message:) // Swift Data Race Example class EventLog { private var lastEventSource: LogSource? func log(source: LogSource, message: String) { print(message) lastEventSource = source } }
  25. 25. // Use DispatchQueue to Synchronize Access class EventLog { private var lastEventSource: LogSource? private var queue = DispatchQueue(label: "com.example.EventLog.queue") func log(source: LogSource, message: String) { queue.async { print(message) lastEventSource = source } } }
  26. 26. // Swift Access Race with Mutating Methods struct BluePoliceBoxLocation { private var x, y, z: Int private var time: Int } mutating func teleport(toPlanet: String) { … } mutating func fly(toCity: String) { … } mutating func travelToEndOfTime() { … } Thread 2: Swift access race Thread 1: Previous access // Thread 1 location.teleport(toPlanet: "Mars") // Thread 2 location.travelToEndOfTime() changes x, y, z changes time
  27. 27. Undefined Behavior Sanitizer
  28. 28. Alignment Violation Nonnull Return Value Violation Integer Overflow C++ Dynamic Type Violation Invalid Float Cast Invalid Shift Exponent Invalid Boolean Invalid EnumInvalid Variable-Length Array Integer Division by Zero Invalid Shift BaseInvalid Integer Cast Out-of-Bounds Array Access Invalid Object SizeMissing Return Value Reached Unreachable Code Nonnull Parameter ViolationNonnull Assignment Violation Null Dereference
  29. 29. “undefined behavior:
 behavior for which this International Standard imposes no requirements.”
 • ISO C++14 Standard
  30. 30. Undefined Behavior Is About Tradeoffs Performance over safety
  31. 31. (INT_MAX + 1) ≯ INT_MAX Integer Overflow
  32. 32. Null pointer returned from function declared to never return null // Nonnull Return Value Violation @implementation SolarSystem + (nonnull NSDictionary *)planetMoons { return @{@"Earth": @[@"Moon"], @"Mars" : @[@"Phobos", @"Deimos"], // … }; } - (nonnull NSArray *)moonsOfPlanet:(nonnull NSString *)planet { return [[self class] planetMoons][planet]; } @end // Find the biggest moon for each planet NSMutableArray *biggestMoons = [NSMutableArray new]; [biggestMoons addObject:[solarSystem moonsOfPlanet:@"Pluto"][0]]; Nonnull Return Value Violation
  33. 33. Compiler 2 Source code .c, .m, .cpp, .mm Object file .o Let’s Experiment: A Very Simple Optimization Pipeline Compiler 1 Dead Code Elimination Redundant Null Check Elimination Redundant Null Check Elimination void contains_null_check(int *P) { int unused = *P; …Hidden text for MM *P = 4; } Keep the brace in MM if (P == NULL) return; Dead Code Elimination void contains_null_check(int *P) { int unused = *P; …Hidden text for MM if (P == NULL) return; *P = 4; } Keep the closing brace MM Compiler Optimization
  34. 34. Compiler 2 Source code .c, .m, .cpp, .mm Object file .o Let’s Experiment: A Very Simple Optimization Pipeline Compiler 1 Dead Code Elimination Redundant Null Check Elimination Redundant Null Check Elimination void contains_null_check(int *P) { int unused = *P; …Hidden text for MM *P = 4; } Keep the brace in MM Dead Code Elimination void contains_null_check(int *P) { int unused = *P; …Hidden text for MM if (P == NULL) return; *P = 4; } Keep the closing brace MM Compiler Optimization 1
  35. 35. Compiler 2 Source code .c, .m, .cpp, .mm Object file .o Let’s Experiment: A Very Simple Optimization Pipeline Compiler 1 Dead Code Elimination Redundant Null Check Elimination Dead Code Elimination int unused = *P; void contains_null_check(int *P) { …Hidden text for MM *P = 4; } Keep closing brace in MM void contains_null_check(int *P) { int unused = *P; …Hidden text for MM *P = 4; } Keep the brace in MM Compiler Optimization 1
  36. 36. Compiler 2 Source code .c, .m, .cpp, .mm Object file .o Let’s Experiment: A Very Simple Optimization Pipeline Compiler 1 Dead Code Elimination Redundant Null Check Elimination Dead Code Elimination void contains_null_check(int *P) { …Hidden text for MM *P = 4; } Keep closing brace in MM void contains_null_check(int *P) { int unused = *P; …Hidden text for MM *P = 4; } Keep the brace in MM Compiler Optimization 1
  37. 37. Compiler 2 Source code .c, .m, .cpp, .mm Object file .o Let’s Experiment: A Very Simple Optimization Pipeline Compiler 2 Redundant Null Check Elimination Dead Code Elimination Dead Code Elimination void contains_null_check(int *P) {
 
 …Hidden text for MM if (P == NULL) return; *P = 4; } Please keep the brace MM void contains_null_check(int *P) { int unused = *P; …Hidden text for MM if (P == NULL) return; *P = 4; } Keep brace during MM int unused = *P; Compiler Optimization 2
  38. 38. Compiler 2 Source code .c, .m, .cpp, .mm Object file .o Let’s Experiment: A Very Simple Optimization Pipeline Compiler 2 Redundant Null Check Elimination Dead Code Elimination Dead Code Elimination void contains_null_check(int *P) {
 
 …Hidden text for MM if (P == NULL) return; *P = 4; } Please keep the brace MM void contains_null_check(int *P) { int unused = *P; …Hidden text for MM if (P == NULL) return; *P = 4; } Keep brace during MM Compiler Optimization 2
  39. 39. Source code .c, .m, .cpp, .mm Object file .o Compiler 2 Let’s Experiment: A Very Simple Optimization Pipeline Compiler 2 Redundant Null Check Elimination Dead Code Elimination Redundant Null Check Elimination void contains_null_check(int *P) { …Hidden text for MM if (P == NULL) return; *P = 4; } Please keep me MM! void contains_null_check(int *P) {
 
 …Hidden text for MM if (P == NULL) return; *P = 4; } Please keep the brace MM Compiler Optimization 2
  40. 40. Let’s Experiment: A Very Simple Optimization Pipeline A surprising result void contains_null_check(int *P) { int unused = *P; … if (P == NULL) return; *P = 4; } Keep brace during MM Compiler 1 void contains_null_check(int *P) { … *P = 4; } Keep closing brace in MM void contains_null_check(int *P) { … if (P == NULL) return; *P = 4; } void contains_null_check(int *P) { int unused = *P; … if (P == NULL) return; *P = 4; } Keep brace during MM Compiler 2 Compiler Optimization
  41. 41. Using Runtime Tools Effectively • Exercise more code • Use the tools together
  42. 42. Runtime Tool Overhead Execution overhead Memory overhead Main Thread Checker 1.02x negligible Undefined Behavior Sanitizer 1.2x negligible Address Sanitizer 2–3x 2x Thread Sanitizer 5–10x 4x
  43. 43. What's New in LLVM • API Availability Checking for Objective-C • Static Analyzer Checks • New Warnings • C++ Refactoring & Features from C++17 • Link-Time Optimization (LTO) • API Availability Checking for Objective-C • Static Analyzer Checks • New Warnings • C++ Refactoring & Features from C++17 • Link-Time Optimization (LTO)
  44. 44. API Availability Checking for Objective-C [UIView instancesRespondToSelector:@selector(addInteraction:)] [UIDragInteraction class] [NSOrthography respondsToSelector:@selector(defaultOrthographyForLanguage:)] &ARErrorDomain != NULL futimens != NULL [UIView instancesRespondToSelector:@selector(addInteraction:)] [UIDragInteraction class] [NSOrthography respondsToSelector:@selector(defaultOrthographyForLanguage:) &ARErrorDomain != NULL futimens != NULL w instancesRespondToSelector:@selector(addInteraction:)] [UIDragInteraction class] y respondsToSelector:@selector(defaultOrthographyForLanguage:)] main != NULL futimens != NULL [UIView instancesRespondToSelector:@selector(addInteraction:)] [UIDragInteraction class] [NSOrthography respondsToSelector:@selector(defaultOrthographyForLanguage &ARErrorDomain != NULL futimens != NULL [UIView instancesRespondToSelector:@selector(addInteraction:)] [UIDragInteraction class] [NSOrthography respondsToSelector:@selector(defaultOrthographyForLanguage:)] &ARErrorDomain != NULL futimens != NULL
  45. 45. API Availability Checking in Objective-C if (@available(iOS 11,x*)) { r = [VNDetectFaceRectanglesRequest new]; if ([handler performRequests:@[r] error:&error]) { // Draw rectangles } } else { // Fall back when API not available } Compiler warns about unguarded uses of new API Use @available to query API availability at run time API Availability Checking for Objective-C
  46. 46. Convenient to write entire methods with limited availability @interface MyAlbumController : UIViewController - (void)showFaces @end API_AVAILABILITY(ios(11.0)); Factor out Code with API_AVAILABILITY() Convenient to write entire methods with limited availability @interface MyAlbumController : UIViewController - (void)showFaces @end API_AVAILABILITY(ios(11.0)) ; Can apply to entire classes Factor out Code with API_AVAILABILITY()
  47. 47. API Availability Checking in C/C++ Use __builtin_available to check availability at runtime if (__builtin_available(iOS 11, macOS 10.13, *)) { CFNewAPIOniOS11(); }
  48. 48. API Availability Checking in C/C++ Use __builtin_available to check availability at runtime Include <os/availability.h> for the API_AVAILABILITY macro #include <os/availability.h> void myFunctionForiOS11OrNewer(int i) API_AVAILABILITY(ios(11.0), macos(10.13));
  49. 49. Do Not Compare Number Objects to Scalars Comparing NSNumber pointer value to 0 checks for nil – not zero number @property NSNumber *photoCount; - (BOOL)hasPhotos { } Comparing pointer value to a scalar integer valuereturn self.photoCount > 0; Do Not Auto-Synthesize NSMutable copy Properties Setter calls -copy, which yields an immutable copy - (void)replaceWithStockPhoto:(NSImage *)stockPhoto { self.photos = [NSMutableArray<NSImage *> new]; [self.photos addObject:stockPhoto]; } -[__NSArray0 addObject:]: unrecognized selector sent to instance @property (copy) NSMutableArray<NSImage *> *photos; Static Analyzer Checks Run Analyzer on Your Code! Supports Objective-C, C, C++ Analyze during build
  50. 50. Q & A

×