How To Solve SIGABRT Error In Xcode

Written by Reinder de Vries on November 20 2018 in App Development

How To Solve SIGABRT Error In Xcode

One minute your iOS app runs fine in Xcode, and the next it has hopelessly crashed with a cryptic SIGABRT error. What’s going on!?

In this article you’ll learn:

  • How to solve the “Signal SIGABRT” error in Xcode
  • How to use some of the debugging tools in Xcode
  • What SIGABRT stands for, and what its causes are
  • 3 approaches to find the root cause of SIGABRT

Ready? Let’s go.

  1. What Does “Thread 1: Signal SIGABRT” Mean?
  2. Check Your Outlets
  3. Check The Stacktrace
  4. Make An Exception Breakpoint
  5. Further Reading

What Does “Thread 1: Signal SIGABRT” Mean?

The error SIGABRT stands for “signal abort”. It’s a signal that’s sent by iOS to a running app, that immediately quits the app because of a runtime error. It essentially means your app has crashed…

Here’s what it looks like in Xcode:

In the screenshot you see a few things:

  • On the left you see a list of threads that ran when the app crashed. You see that the thread that caused the crash is the main thread, or “Thread 1”.
  • In the editor we see that dreaded Thread 1: signal SIGABRT error. It has highlighted line 12 in the editor, the class definition of AppDelegate.
  • At the bottom you see helpful debug output. In this case, you get a stacktrace and a cryptic error message about not being “key value coding-compliant.”

The problem with the SIGABRT error is that it’s too generic. Xcode is basically saying: “Look, your app has crashed, that’s all we know.” In most cases of the SIGABRT error, you get little information about what’s caused the error.

Before we go on, let’s discuss a few misconceptions and common pitfalls of SIGABRT:

  • The SIGABRT error has nothing to do with the AppDelegate class declaration, even though it highlights that line in Xcode. The line is highlighted because it’s the first line of code of your app. Don’t waste your time looking in the AppDelegate class, unless you’re absolutely certain the bug is in there.
  • The stacktrace is a list of function calls that lead up to the app crashing. That doesn’t mean the line of code that caused the error is anywhere in the stacktrace. It sometimes is, but in other cases, the stacktrace merely leads to the code that choked on a value you set elsewhere in your own code.
  • Don’t stare yourself blind on a SIGABRT error. There’s a rational, logical cause for the error. It’s probably a bug in your own code, and there’s nothing wrong with that. Apps aren’t magic, no one is out to get you, and bugs never appear out of the blue. Don’t frustrate yourself with thoughts like “It ran fine yesterday!” – it always did, and now it doesn’t!

Now that we’ve established a baseline, let’s get to the first cause of SIGABRT.

Learn how to build iOS apps

Get started with iOS 13 and Swift 5

Sign up for my iOS development course, and learn how to build great iOS 13 apps with Swift 5 and Xcode 11.

Check Your Outlets

A very common cause of “Signal SIGABRT” is a typo or bug in your outlets. Here’s what happened:

  • You created a new view controller in Interface Builder, and set it up with a few UI elements like buttons and labels
  • You connected these UI elements to your code by using outlet properties, which creates a connection between a property of your view controller and the UI element in Interface Builder
  • At one point you changed the name of the initial outlet property and your app started crashing with a SIGABRT error

When you’re using Interface Builder to create a view controller, your app will use the XIB file to generate the view controller’s UI when your app runs (roughly speaking). At this point it will also connect outlets from the XIB to properties of the view controller class.

If you’ve changed the name of an outlet property, your app can’t find it. And because of that it will throw an exception. What’s causing the SIGABRT error, is not handling that exception.

Here’s what that looks like in Xcode:

See what’s happening? The property is called otherButton, but the outlet is still called button. At one point we changed the outlet – because the new name is better – and confused the app, which made it crash.

At the top of the stacktrace we also spot another clue:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<···> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key button.

What does that mean? The app is telling us at this point that the view controller is not key value coding compliant for the key button. This means that it cannot find the button property on the view controller. And that’s true, because we’ve renamed it.

iOS uses a mechanism called key value coding to inspect the properties a view controller has, so it can use those properties to reference UI elements it has created based on the XIB.

How do you solve the bug at this point? You can use 2 approaches:

  1. You rename the property back to its original name
  2. You remove the outlet connection in Interface Builder, and reconnect it using the new outlet property name

Let’s move on!

Quick Tip: Just as a changed @IBOutlet can cause “Thread 1: signal SIGABRT”, so can erroneously changing the name of an action, i.e. with @IBAction, cause the SIGABRT error.

Check The Stacktrace

In many cases Xcode won’t show you any helpful error messages for a SIGABRT crash. When that happens, it’s useful to know a few debugging commands, such as bt.

Xcode has an integrated debugging environment called LLDB. It’s what you see at the bottom of Xcode when your app runs, the Console or debug output area. You often see debug messages here, but did you know you can also use it to input commands?

Next time your app crashes, try typing help in LLDB. Like this:

You’ll see that many of the LLDB commands directly correspond to actions you can take with the debugger, such as setting breakpoints, stepping over lines of code, and inspecting runtime values.

One command is particularly useful. You can type in bt to see the current call stack (also called “backtrace” or “stacktrace”). This is a list of all functions that ran up to the current crash. This trace typically includes the function that caused a bug.

Here, check out the stacktrace of a typical Index out of range error. In the screenshot below, we’ve deliberately caused that error by getting index 99 from an array that only has 4 items. When the app crashes, bt can tell us which line of code caused the error.

Can you spot the following information in the stacktrace?

  • The offending code is at line 21 of ViewController.swift, inside the viewDidLoad() function
  • You can even see that we used the subscript “getter” of Array
  • Before the crash a whole bunch of view controller-related function calls were made

Based on the information we got with bt, we can find the offending line in our code and fix it. Xcode already helped us in this case, by highlighting the error in the editor. In some scenarios you won’t have such luck, and then it can be helpful to use the bt command.

One last thing: you can inspect values at runtime with the print command. In the above scenario, typing print names would have produced this output:

([String]) $R0 = 4 values {
  [0] = "Ford"
  [1] = "Arthur"
  [2] = "Zaphod"
  [3] = "Trillian"
}

For printing complex objects, use po. Awesome!

Keep in mind that a stacktrace runs outside-in. The bottom of the stack trace shows top-level function calls, and the higher up the stack you go, the deeper the calls go in. The latest, most recent, deepest-level call is at the top of the stack.

Make An Exception Breakpoint

You can use breakpoints to stop execution of your code at a certain line. At that point you can then inspect values and step through functions.

An exception breakpoint is triggered whenever an exception occurs in your code. Instead of specifying on which line the breakpoint is triggered, you instruct the debugger to halt code execution for exceptions.

Exception breakpoints are useful for inspecting the code when an exception occurs. You can see which line of code threw the exception, and you can inspect values in your code at that point. Some exceptions are caused by bugs or invalid states of your app, so exception breakpoints are useful for finding and fixing those bugs.

Here’s how you can set an exception breakpoint:

  1. Go to the Breakpoint navigator in Xcode, by using the tabs on the left
  2. Click on the bottom-left +-button and choose Exception Breakpoint
  3. Leave the default settings as-is (although they’re helpful to customize)
  4. Run your code

Exception Breakpoint

When an exception is thrown, execution of your app halts. You can now use the debugger to inspect values, step through the code, and use LLDB commands. When possible, Xcode will take you to the line of code that caused the exception.

Keep in mind that an exception doesn’t necessarily crash your app! So, whenever the exception breakpoint is enabled, and an exception occurs, your app is halted. Halting code with a breakpoint isn’t the same as an app crash, so don’t let that confuse you.

For example, an exception breakpoint will get triggered by an Unsatisfied constraints exception, but that won’t crash your app. Use the exception breakpoint to gather extra information for the SIGABRT crash, and then disable it once you’ve solved the bug (until it’s needed again).

Learn how to build iOS apps

Get started with iOS 13 and Swift 5

Sign up for my iOS development course, and learn how to build great iOS 13 apps with Swift 5 and Xcode 11.

Further Reading

The SIGABRT error is quite cryptic, and can prove difficult to solve. Why can’t Xcode just give helpful error messages? Well, that’s a good question…

The short answer is that there are so many moving parts in iOS development that Xcode can’t always determine the cause of a crash. Xcode doesn’t know that you erroneously changed the name of an outlet. It only knows that in connecting the outlet, some code was invoked, and that caused an exception.

This means you’ll always see an error that’s as close to the root cause as possible. The best you can do is make lots of mistakes, decrypt lots of error messages, and get to know them better. And what you’ve learned in this article, is how to find and solve the SIGABRT error!

Want to learn more? Check out these resources:

Reinder de Vries

Reinder de Vries

Reinder de Vries is a professional iOS developer. He teaches app developers how to build their own apps at LearnAppMaking.com. Since 2009 he has developed a few dozen apps for iOS, worked for global brands and lead development at several startups. When he’s not coding, he enjoys strong espresso and traveling.