SlideShare a Scribd company logo
Xcode - Debug
KKBOX WWDC 2017 Study
Oliver Huang iOS Engineer
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/
Debugging with Xcode 9
• Development: Unplugged (Wireless Development)
• Breakpoint Workflow Enhancements
• Debug View Hierarchy Improvements
KKBOX WWDC17  Xcode debug - Oliver
Wireless Development NEW
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
Demo
KKBOX WWDC17  Xcode debug - Oliver
Wireless Development
tvOS device pairing
Breakpoint Workflow Enhancements
• Code Completion in Text Field
• Options Indicator
• Deep Filtering
Breakpoints
Demo
Debug View Hierarchy Enhancements
• View Controller Debugging
• SpriteKit Debugging
• SceneKit Debugging
View Controller Debugging NEW
SpriteKit Debugging NEW
SpriteKit Debugging
KKBOX WWDC17  Xcode debug - Oliver
SceneKit Debugging NEW
KKBOX WWDC17  Xcode debug - Oliver
Finding Bugs Using Xcode Runtime Tools
Improvements in Runtime Checking
Improvements in Runtime Checking
Runtime Issues
Finding Bugs Using Xcode Runtime Tools
Improvements in Runtime Checking
• Main Thread Checker (New)
• Address Sanitizer
• Thread Sanitizer
• Undefined Behavior Sanitizer (New)
4
Main Thread Checker
KKBOX WWDC17  Xcode debug - Oliver
Designing Asynchronous APIs
Let API user specify callback queue
DeepThought.asyncComputeAnswer(to: theQuestion) { reply in
…
}
Designing Asynchronous APIs
Let API user specify callback queue
DeepThought.asyncComputeAnswer(to: theQuestion, completionQueue: queue) { reply in
…
}
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
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;
// 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;
KKBOX WWDC17  Xcode debug - Oliver
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
// 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
}
}
// 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
}
}
}
// 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
Undefined Behavior Sanitizer
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
“undefined behavior:

behavior for which this International Standard
imposes no requirements.”

•
ISO C++14 Standard
Undefined Behavior Is About Tradeoffs
Performance over safety
(INT_MAX + 1) ≯ INT_MAX
Integer Overflow
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
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
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
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
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
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
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
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
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
Using Runtime Tools Effectively
• Exercise more code
• Use the tools together
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
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)
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
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
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()
API Availability Checking in C/C++
Use __builtin_available to check availability at runtime
if (__builtin_available(iOS 11, macOS 10.13, *)) {
CFNewAPIOniOS11();
}
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));
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
Q & A

More Related Content

PDF
KKBOX WWDC17 Airplay 2 - Dolphin
PDF
ElixirConf Lightning Talk: Elixir |> Production
PDF
Hello elixir (and otp)
PDF
Introduction to the Roku SDK
PDF
aptly: Debian repository management tool
KEY
Deploying and maintaining your software with RPM/APT
PDF
Elixir Into Production
PPT
Calico docker+ipam
KKBOX WWDC17 Airplay 2 - Dolphin
ElixirConf Lightning Talk: Elixir |> Production
Hello elixir (and otp)
Introduction to the Roku SDK
aptly: Debian repository management tool
Deploying and maintaining your software with RPM/APT
Elixir Into Production
Calico docker+ipam

What's hot (20)

PDF
Configuration of Ansible - DevOps: Beginner's Guide To Automation With Ansible
PDF
Dependency management with Composer
PDF
Dependencies Managers in C/C++. Using stdcpp 2014
PDF
Nike pop up habitat
PPTX
Controlling multiple VMs with the power of Python
PDF
Compliance as Code
PPT
Learn REST API with Python
PDF
Flask With Server-Sent Event
PDF
Introduction to Elixir
PDF
Composer for Busy Developers - php|tek13
PDF
Jaringan, Linux, Docker
PPTX
Compliance Automation with Inspec Part 4
PDF
Ansible-for-openstack
PDF
Testing in Ballerina Language
PDF
Fluentd v0.12 master guide
PDF
Bootstrap |> Elixir - Easy fun for busy developers
PDF
Eclipse Concierge - an OSGi R5 framework for IoT applications
PPTX
Java Day Kharkiv - Next-gen engineering with Docker and Kubernetes
PPTX
London Community Summit - Chef at SkyBet
PDF
FrenchKit 2017: Server(less) Swift
Configuration of Ansible - DevOps: Beginner's Guide To Automation With Ansible
Dependency management with Composer
Dependencies Managers in C/C++. Using stdcpp 2014
Nike pop up habitat
Controlling multiple VMs with the power of Python
Compliance as Code
Learn REST API with Python
Flask With Server-Sent Event
Introduction to Elixir
Composer for Busy Developers - php|tek13
Jaringan, Linux, Docker
Compliance Automation with Inspec Part 4
Ansible-for-openstack
Testing in Ballerina Language
Fluentd v0.12 master guide
Bootstrap |> Elixir - Easy fun for busy developers
Eclipse Concierge - an OSGi R5 framework for IoT applications
Java Day Kharkiv - Next-gen engineering with Docker and Kubernetes
London Community Summit - Chef at SkyBet
FrenchKit 2017: Server(less) Swift
Ad

Viewers also liked (11)

PDF
KKBOX WWDC17 Notification and Autolayout - Jefferey
PDF
KKBOX WWDC17 UIKit - QQ
PDF
KKBOX WWDC17 UIKit Drag and Drop - Mario
PDF
KKBOX WWDC17 WatchOS - Dada
PDF
KKBOX WWDC17 Xcode IDE - Hardy
PDF
KKBOX WWDC17 Security - Antony
PDF
KKBOX WWDC17 SiriKit and CoreSpotlight - Seraph
PDF
KKBOX WWDC17 Core Image - Daniel Tien
PDF
KKBOX WWDC17 Swift and Foundation - Liyao
PDF
KKBOX WWDC17 Performance and Testing - Hokila
PPTX
專利入門
KKBOX WWDC17 Notification and Autolayout - Jefferey
KKBOX WWDC17 UIKit - QQ
KKBOX WWDC17 UIKit Drag and Drop - Mario
KKBOX WWDC17 WatchOS - Dada
KKBOX WWDC17 Xcode IDE - Hardy
KKBOX WWDC17 Security - Antony
KKBOX WWDC17 SiriKit and CoreSpotlight - Seraph
KKBOX WWDC17 Core Image - Daniel Tien
KKBOX WWDC17 Swift and Foundation - Liyao
KKBOX WWDC17 Performance and Testing - Hokila
專利入門
Ad

Similar to KKBOX WWDC17 Xcode debug - Oliver (20)

PPTX
Boost.Python: C++ and Python Integration
KEY
What's New In Python 2.5
PDF
Pascal script maxbox_ekon_14_2
PDF
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
PDF
A Check of the Open-Source Project WinSCP Developed in Embarcadero C++ Builder
PDF
Pyhton-1a-Basics.pdf
PPTX
Introduction to Python.Net
PDF
2018 cosup-delete unused python code safely - english
PDF
Brief Introduction to Cython
PDF
C_and_C++_notes.pdf
PDF
Pemrograman Python untuk Pemula
PDF
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
PDF
Projects Panama, Valhalla, and Babylon: Java is the New Python v0.9
PDF
CSW2017 Henry li how to find the vulnerability to bypass the control flow gua...
PDF
PyCon 2013 : Scripting to PyPi to GitHub and More
PPT
PDF
Python introduction
ODP
Lambda Chops - Recipes for Simpler, More Expressive Code
PDF
.NET @ apache.org
PDF
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Boost.Python: C++ and Python Integration
What's New In Python 2.5
Pascal script maxbox_ekon_14_2
MobileConf 2021 Slides: Let's build macOS CLI Utilities using Swift
A Check of the Open-Source Project WinSCP Developed in Embarcadero C++ Builder
Pyhton-1a-Basics.pdf
Introduction to Python.Net
2018 cosup-delete unused python code safely - english
Brief Introduction to Cython
C_and_C++_notes.pdf
Pemrograman Python untuk Pemula
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
Projects Panama, Valhalla, and Babylon: Java is the New Python v0.9
CSW2017 Henry li how to find the vulnerability to bypass the control flow gua...
PyCon 2013 : Scripting to PyPi to GitHub and More
Python introduction
Lambda Chops - Recipes for Simpler, More Expressive Code
.NET @ apache.org
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...

More from Liyao Chen (10)

PDF
Auto Layout part 1
PDF
iOS Unit testing II
PDF
iOS Unit test getting stared
PDF
Continuous Integration
PDF
iOS Design to Code - Code
PDF
iOS Design to Code - Design
PDF
Beta testing with CI
PPTX
PTTHOT x IDEAS_HACKATHON 2014
PDF
選擇
PDF
Windows 8 apps dev.整理及分享
Auto Layout part 1
iOS Unit testing II
iOS Unit test getting stared
Continuous Integration
iOS Design to Code - Code
iOS Design to Code - Design
Beta testing with CI
PTTHOT x IDEAS_HACKATHON 2014
選擇
Windows 8 apps dev.整理及分享

Recently uploaded (20)

PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Encapsulation_ Review paper, used for researhc scholars
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
KodekX | Application Modernization Development
PDF
Approach and Philosophy of On baking technology
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Empathic Computing: Creating Shared Understanding
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPTX
Cloud computing and distributed systems.
PPT
Teaching material agriculture food technology
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Machine learning based COVID-19 study performance prediction
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Encapsulation_ Review paper, used for researhc scholars
“AI and Expert System Decision Support & Business Intelligence Systems”
Dropbox Q2 2025 Financial Results & Investor Presentation
KodekX | Application Modernization Development
Approach and Philosophy of On baking technology
Understanding_Digital_Forensics_Presentation.pptx
Reach Out and Touch Someone: Haptics and Empathic Computing
Network Security Unit 5.pdf for BCA BBA.
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Per capita expenditure prediction using model stacking based on satellite ima...
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Empathic Computing: Creating Shared Understanding
Chapter 3 Spatial Domain Image Processing.pdf
MIND Revenue Release Quarter 2 2025 Press Release
Cloud computing and distributed systems.
Teaching material agriculture food technology
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Machine learning based COVID-19 study performance prediction

KKBOX WWDC17 Xcode debug - Oliver

  • 1. Xcode - Debug KKBOX WWDC 2017 Study Oliver Huang iOS Engineer
  • 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. Debugging with Xcode 9 • Development: Unplugged (Wireless Development) • Breakpoint Workflow Enhancements • Debug View Hierarchy Improvements
  • 6. 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
  • 10. Breakpoint Workflow Enhancements • Code Completion in Text Field • Options Indicator • Deep Filtering Breakpoints
  • 11. Demo
  • 12. Debug View Hierarchy Enhancements • View Controller Debugging • SpriteKit Debugging • SceneKit Debugging
  • 18. Finding Bugs Using Xcode Runtime Tools Improvements in Runtime Checking
  • 19. Improvements in Runtime Checking Runtime Issues Finding Bugs Using Xcode Runtime Tools
  • 20. Improvements in Runtime Checking • Main Thread Checker (New) • Address Sanitizer • Thread Sanitizer • Undefined Behavior Sanitizer (New)
  • 23. Designing Asynchronous APIs Let API user specify callback queue DeepThought.asyncComputeAnswer(to: theQuestion) { reply in … }
  • 24. Designing Asynchronous APIs Let API user specify callback queue DeepThought.asyncComputeAnswer(to: theQuestion, completionQueue: queue) { reply in … }
  • 25. 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
  • 26. 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;
  • 27. // 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;
  • 29. 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
  • 30. // 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 } }
  • 31. // 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 } } }
  • 32. // 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
  • 34. 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
  • 35. “undefined behavior:
 behavior for which this International Standard imposes no requirements.”
 • ISO C++14 Standard
  • 36. Undefined Behavior Is About Tradeoffs Performance over safety
  • 37. (INT_MAX + 1) ≯ INT_MAX Integer Overflow
  • 38. 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
  • 39. 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
  • 40. 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
  • 41. 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
  • 42. 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
  • 43. 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
  • 44. 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
  • 45. 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
  • 46. 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
  • 47. Using Runtime Tools Effectively • Exercise more code • Use the tools together
  • 48. 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
  • 49. 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)
  • 50. 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
  • 51. 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
  • 52. 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()
  • 53. API Availability Checking in C/C++ Use __builtin_available to check availability at runtime if (__builtin_available(iOS 11, macOS 10.13, *)) { CFNewAPIOniOS11(); }
  • 54. 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));
  • 55. 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
  • 56. Q & A