Hide chapters

Concurrency by Tutorials

Third Edition · iOS 16 · Swift 5.7 · Xcode 14

12. Thread Sanitizer
Written by Scott Grosch

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

By the time you reach this chapter, you should be a whiz at concurrent programming.

However, just because your app seems to run correctly doesn’t mean you took care of various concurrency and threading related edge cases. In this chapter you’ll learn how to utilize Xcode’s built-in Thread Sanitizer to discover races and before you deploy to the App Store.

Why the Sanitizer?

As discussed in Chapter 5, “Concurrency Problems,” you know how important it is to keep all accesses to a variable on the same thread to avoid data races. Depending on how your app is structured, or the architecture of a third-party library that you’re using, it can be hard to tell if you’re crossing a thread boundary.

The Thread Sanitizer, commonly referred to as TSan, is a tool Apple provides as part of the LLVM compiler. TSan allows you to identify when multiple threads attempt to access the same memory without providing proper access synchronization.

Note: TSan is only supported when running on the simulator.

While there are a few other sanitizers available — such as the Address Sanitizer or the Main Thread Checker — the only one you’ll need to actively use at this point is the Thread Sanitizer. The other sanitizers are either meant for other languages, or are on by default.

Getting Started

Open up the Xcode project provided in this chapter’s starter folder. It’s a pretty simple-looking app that writes to a variable in two separate locations. Build and run the app; you won’t see any issues. If you look at the code of MainViewController.swift, though, you can see you’re clearly utilizing the counter property in different dispatch queues.

Enabling Sanitization

The first step to checking your code with the Thread Sanitizer is enabling it. Edit the scheme by pressing Command-< or by clicking on the Concurrency scheme next to where you select the build device, then perform these steps:

It’s Not Code Analysis

It’s important to keep in mind that the Thread Sanitizer is runtime analysis. What that means is that, if an issue doesn’t occur during execution, it won’t be flagged. If you look at the code in ContentView, you’ll see this, around line 23:

Thread.sleep(forTimeInterval: 0.1)

Xcode Keeps Getting Smarter

Apple continues to improve runtime analysis of your apps even without the Thread Sanitizer. You know how important it is, by now, to always execute UI tasks on the main thread. If you forget, your app will abort at runtime in debugging. In years past, you’d have had to use the Thread Sanitizer to identify such a mistake.

Where to Go From Here?

You’ve seen how important the Thread Sanitizer is to ensuring stable apps for your customers. I suggest you enable the sanitizer at the start of app development and leave it on until you find that it is impacting the performance of testing. Once it has reached an impactful point, then disable it but continue to run at regular intervals.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.

Unlock now