How to read crash log? How to find why the app cra

2020-02-11 05:41发布

问题:

I got an crash logs from a customer to figure why my app crash on her iPhone.

Here some info from crash log:

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread:  0

Stack trace for Thread 0

Thread 0 Crashed:
0   libSystem.B.dylib              0x3293f98c 0x328c1000 + 518540
1   libSystem.B.dylib              0x3293f97c 0x328c1000 + 518524
2   libSystem.B.dylib              0x3293f96e 0x328c1000 + 518510
3   libSystem.B.dylib              0x3295461a 0x328c1000 + 603674
4   libstdc++.6.dylib              0x30a143b0 0x309cf000 + 283568
5   libobjc.A.dylib                0x3347a858 0x33475000 + 22616
6   libstdc++.6.dylib              0x30a12776 0x309cf000 + 276342
7   libstdc++.6.dylib              0x30a127ca 0x309cf000 + 276426
8   libstdc++.6.dylib              0x30a12896 0x309cf000 + 276630
9   libobjc.A.dylib                0x33479714 0x33475000 + 18196
10  CoreFoundation                 0x335c8210 0x33534000 + 606736
11  CoreFoundation                 0x3354ea8e 0x33534000 + 109198
12  CoreFoundation                 0x33545ab8 0x33534000 + 72376
13  Journaler Lite                 0x0001699e -[AccountManager unsignedIntegerValueForPath:] (AccountManager.m:151)
...

Here is code from AccountManager.m:

 NSNumber *number = ...;
 if (number) {
  return [number unsignedIntegerValue]; // line 151
 } else {
  return 0;
 }

The main question is how to read such crash log? The app crashes somewhere inside the system library, no more additional info. Is there some way how find reason of crash?

update: I have googled a lot of forums posts, where exception type is EXC_CRASH (SIGABRT) and first lines from a crashed thread stack is:

Thread 0 Crashed:
0   libSystem.B.dylib              0x3293f98c 0x328c1000 + 518540
1   libSystem.B.dylib              0x3293f97c 0x328c1000 + 518524
2   libSystem.B.dylib              0x3293f96e 0x328c1000 + 518510
3   libSystem.B.dylib              0x3295461a 0x328c1000 + 603674
4   libstdc++.6.dylib              0x30a143b0 0x309cf000 + 283568
5   libobjc.A.dylib                0x3347a858 0x33475000 + 22616
6   libstdc++.6.dylib              0x30a12776 0x309cf000 + 276342
7   libstdc++.6.dylib              0x30a127ca 0x309cf000 + 276426
8   libstdc++.6.dylib              0x30a12896 0x309cf000 + 276630
9   libobjc.A.dylib                0x33479714 0x33475000 + 18196
10  CoreFoundation                 0x335c8210 0x33534000 + 606736
11  CoreFoundation                 0x3354ea8e 0x33534000 + 109198

What does this exception type (EXC_CRASH (SIGABRT)) mean?

回答1:

First, you need to symbolicate the crash log using the DSYM to understand what's happening. You'll need to have the DSYM file from the time that the application was built. The DSYM file allows you to reverse map from those memory addresses back to readable lines of code.

SIGABRT is the signal that you get when you have an unhandled exception, such as calling [someArray objectAtIndex:2] if the array only had 1 item. Or, more often, an unrecognized selector: [NSArray unsignedIntValue].

Take a look at this crash log in this question. Note that the call stack libraries in Foundation are the same as your code - and it's an unrecognized selector.

Your code is:

NSNumber *num = foo;
if (num)
{
  bar = [num unsignedIntValue];
}

What you haven't told us -- but is very important -- is what is in "foo". How do you assign that NSNumber? If it is any other object than an NSNumber, then your crash log will look like yours.

If you wanted to be REALLY defensive in your programming, you can say:

if (num && [num isKindOfClass:[NSNumber class]])

But really, whatever your "foo" is should always be returning an NSNumber.