57

I'm trying to test my crash analytics. I didn't realize how hard it is to make an app crash at will. it seems so simple mid-programming. Does anybody have a suggestion as to how i'd force my app to crash? And i don't mean a little "memory error" crash, i mean the phone doesn't know what to do with itself. I need it to at the very least enter into the device logs as a crash, in Xcode's organizer. Any suggestions?

Katushai
  • 1,510
  • 2
  • 14
  • 27

9 Answers9

94
@throw NSInternalInconsistencyException;
Stavash
  • 14,244
  • 5
  • 52
  • 80
  • this one worked. i accepted this answer because it came first, but assert(no) also worked. also i chose this one because it appears to be native to cocoa as opposed to C, so apple designed this for this specific reason (my guess) – Katushai Feb 04 '14 at 15:14
  • 4
    Throwing an exception does not necessarily lead to a crash. If the exception will be caught, the program can proceed. If the exception will not handled, the system function `terminate()` will be called, which in turn calls `abort()`. That is, strictly, the program does NOT crash, but it _terminates_. – CouchDeveloper Feb 05 '14 at 08:41
  • termination resulted in a crash report to my analytics, so this worked for my purposes – Katushai Sep 02 '14 at 15:07
  • 2
    Why not just call abort() directly then? Thrown exceptions can be caught - abort() cannot. On the Mac, abort() generates a crashlog, I presume it does on iOS as well. – Peter N Lewis Aug 07 '15 at 06:44
  • I'm not sure about how crash analytics SDKs work with abort(). The original question was for testing crash analytics services so a native @throw statement was my best guess. – Stavash Aug 09 '15 at 08:22
  • Its not crash its just an exception and results into troggering exc_breakpoint – NaXir Nov 17 '15 at 07:18
25

So many ways to kill an app! Here are two one liners:

[self performSelector:@selector(die_die)];

also

@[][666];
radj
  • 4,360
  • 7
  • 26
  • 41
fsaint
  • 8,759
  • 3
  • 36
  • 48
14

Just write assert(NO). This checks the condition given as parameter and crashes the app if it is false.

Edit:

exit(0) will also do the trick

Levi
  • 7,313
  • 2
  • 32
  • 44
  • this method worked as well. i had to accept the other answer because it came first though. very nice. this seems like something most people wouldn't know would cause a crash on iOS – Katushai Feb 04 '14 at 15:08
  • @Stavash By default no. But easy to do so. Check your target's build settings: Apple LLVM 5.0 - Preprocessing > Enable Foundation Assertions. – Desdenova Feb 04 '14 at 15:12
  • for the sake of completeness, i think it should be NSAssert, in true cocoa fashion. but it works either way – Katushai Sep 12 '14 at 15:12
11
int* p = 0;
*p = 0;

Gives a EXC_BAD_ACCESS (code=2, address=0x0)

Edit:

After Greg Parkers comment that a compiler is allowed to optimize away the above statements, it made me think more thoroughly about the above statements, and why Greg Parker is right:

In fact, dereferencing the NULL pointer is "undefined behavior" in C and C++ (see also C99 §6.5.3.2/4).

This means, the effect of the above statements depend on the compiler. This "undefined behavior" also means, that the compiler is allowed to apply a couple of optimizations, which may have the effect that the above statements will be "optimized aways" - as Greg Parker asserts.

Well, now that made me curious what clang would actually do:

This is the small test program:

int main(int argc, const char * argv[])
{
    int* p = 0;
    *p = 0;
    return 0;
}

with optimization set to "-Ofast", we get this disassembly:

0x100000f90:  pushq  %rbp
0x100000f91:  movq   %rsp, %rbp
0x100000f94:  ud2    

where ud2 is an opcode meaning "undefined opcode" and causes a CPU exception:

`EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)`

(Maybe @GregParker can comment why clang chooses this approach?)

While this is interesting, it refers to "dereferencing the NULL pointer" only. If we have this instead:

int* p = (int*)1;
*p = 0;

the program crashes as expected - but requires the "prerequisite" that the hardware refuses writes to this (invalid) address.

CouchDeveloper
  • 18,174
  • 3
  • 45
  • 67
9

I think the good old array index out of range is a guarantee of "successful crash", so here my favourite list:

Swift 4:

  1. [][0]
  2. fatalError()

Objective-C:

  1. @[][0];
  2. int *x = nil; *x = 0;

Although @throw NSInternalInconsistencyException; fixes your problem, is an exception (not a crash), hence might be caught.

mugx
  • 9,869
  • 3
  • 43
  • 55
6

I often find it useful to have the application start up, do its thing for a bit, and then crash after 10 seconds. In this case (for Objective-C), I use:

[self performSelector:NSSelectorFromString(@"crashme:") withObject:nil afterDelay:10];

A secondary benefit to this is that the compiler doesn't throw any warnings (if using Objective-C) about the selector not being found. :)

Swift:

self.perform("crashme:", with: nil, afterDelay: 10)
ChrisJF
  • 6,822
  • 4
  • 36
  • 41
3

A more controlled way would be to actually throw an exception yourself:

@throw [NSException exceptionWithName:NSGenericException reason:@"" userInfo:nil];

Check NSException.h for more exceptions.

ABeanSits
  • 1,725
  • 1
  • 17
  • 34
2

For swift these worked for me:

assert(false, "sdf")

And this:

var hey:[Int] = []
hey[0] = 1
Esqarrouth
  • 38,543
  • 21
  • 161
  • 168
-1
*(long*)0 = 0xDEADBEEF;

Gives an EXC_BAD_ACCESS

Antoine Rosset
  • 1,045
  • 2
  • 13
  • 22