An EXC__BAD_ACCESS occurs whenever you try to access or send a message to a deallocated object. The most common cause of EXC_BAD_ACCESS is when you initialize a variable in one of your initializer methods but use the wrong ownership qualifier, which results in deallocation of your object. For example, you create an NSMutableArray of elements for your UITableViewController in the viewDidLoad method but set the ownership qualifier of the list to unsafe_unretained or assign instead of strong. Now in cellForRowAtIndexPath:, when you try to access the deallocated object, you’ll crash with a EXC_BAD_ACCESS. Debugging EXC_BAD_ACCESS is made easy with the NSZombiesEnabled environment variable.
A signal segment fault(SIGSEGV) is a more serious issue that the operating system raises. It occurs when there is a hardware failure or when you try to access a memory address that cannot be read or when you try to write to a protected address.
The first case, a hardware failure, is uncommon. When you try to read data stored in RAM and the RAM hardware at that location is faulty, you get a SIGSEGV. But more often than not, a SIGSEGV occurs for the latter two reasons. By default, code pages are protected from being written into and data pages are protected from being executed. When one of your pointers in your application points to a code page and tries to alter the value pointed to, you get a SIGSEGV. You also get a SIGSEGV when you try to read the value of a pointer that was initialized to a garbage value pointing to an address that is not a valid memory location.
SIGSEGV faults are more tedious to debug, and the most common case reason a SIGSEGV happens is an incorrect typecast. Avoid hacking around with pointers or trying to a read a private data structure by advancing the pointer manually. When you do that and don’t advance the pointer to take care of the memory alignment or padding, you get a SIGSEGV.
A signal bus(SIGBUS) error is a kind of bad memory access where the memory you tried to access is an invalid memory address. That is, the address pointed to is not a physical memory address at all. Both SIGSEGV and SIGBUS are subtypes of EXC_BAD_ACCESS.
SIGTRAP stands for signal trap. This is not really a crash signal. It’s sent when the processor executes a trap instruction. The LLDB debugger usually handles this signal and stops at a specified breakpoint. If you get a SIGTRAP for no apparent reason, a clean build will usually fix it.
SIGILL stands for SIGNAL ILLEGAL INSTRUCTION. This happens when you try to execute an illegal instruction on the processor. You execute an illegal instruction when you’re trying to pass a function pointer to another function, but for one reason or other, the function pointer is corrupted and is pointing to a deallocated memory or a data segment. Sometimes you get an EXC_BADINSTRUCTION instead of SIGILL, and through both are synonymous, EXC* are machine-independent equivalents of this signal.
SIGABRT stands for SIGNAL ABORT. This is a more controlled crash where the operating system has detected a condition that is not safe and asks the process to perform cleanup if any is needed. There is no one silver bullet to help you debug the underlying error for this signal. Frameworks like cocos2d or UIKit often call the C function abort when certain preconditions are not met or when something really bad happens. When a SIGABRT occurs, the console usually has a wealth of information about what went wrong. Since it’s controlled crash, you can print the backtrace by typing bt into the LLDB console.