Вопрос

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?

Это было полезно?

Решение

@throw NSInternalInconsistencyException;

Другие советы

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

[self performSelector:@selector(die_die)];

also

@[][666];

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

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.

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.

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)

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.

For swift these worked for me:

assert(false, "sdf")

And this:

var hey:[Int] = []
hey[0] = 1
*(long*)0 = 0xDEADBEEF;

Gives an EXC_BAD_ACCESS

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top