EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) objective-c objective-c

EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)


This kind of crash will happen when you are running a (vector)extension which is not supported on your CPU.

For example, in xcode 5 under "project-settings / build-settings / Code Generation, set the "Enable Additional Vector extensions" to "AVX2". Build your executable.

Now run it on an:

  • Intel Core i5: it's going to crash (wherever the compiler decided to use avx2) with 'exc_i386_invop subcode=0x0'.
  • Intel Core i7: it will work.


EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP) is the by-product of a __builtin_trap() - which is a GCC and clang intrinsic function. On x86 it we get

    0x4dfa2:  movl   %esi, (%esp)    0x4dfa5:  movl   %edx, 4(%esp)    0x4dfa9:  movl   %eax, 8(%esp)    0x4dfad:  calll  0x110ffa                  ; symbol stub for: objc_msgSend    0x4dfb2:  cmpb   $0, %al    0x4dfb4:  je     38 -> 0x4dfba:  ud2        0x4dfbc:  movl   -32(%ebp), %eax

The instruction ud2 is the culprit here, and is not handled specially by Xcode.

On ARM we this compiles into trap and results in a trace break-point in XCode. Is this a bug in clang we have here?

Ultimately in the context of the original question, I suspect that the library function that is failing has hit a assertion.


In my case I was adding an observer for contentSize to a UITextView in viewDidLoad and was never removing it. Fixed it by adding it in viewDidAppear and then removing it in viewWillDisappear. It was so annoying to find out :(

Add observer in viewDidAppear

[self.textViewMessage addObserver:self                           forKeyPath:NSStringFromSelector(@selector(contentSize))                              options:NSKeyValueObservingOptionNew                              context:nil];

Remove observer in viewWillDisappear

[self.textViewMessage removeObserver:self forKeyPath:NSStringFromSelector(@selector(contentSize))];