7

我从一位客户那里得到了崩溃日志,以找出我的应用程序在她的 iPhone 上崩溃的原因。

这里有一些来自崩溃日志的信息:

异常类型:EXC_CRASH (SIGABRT)
异常代码:0x00000000、0x00000000
崩溃的线程:0

线程 0 的堆栈跟踪

线程 0 崩溃:
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 核心基础 0x335c8210 0x33534000 + 606736
11 核心基础 0x3354ea8e 0x33534000 + 109198
12 核心基础 0x33545ab8 0x33534000 + 72376
13 Journaler Lite 0x0001699e -[AccountManager unsignedIntegerValueForPath:] (AccountManager.m:151)
...

这是来自的代码AccountManager.m

NSNumber *number = ...;
 如果(数字){
  返回[数字无符号整数值];// 第 151 行
 } 别的 {
  返回0;
 }

主要问题是如何阅读这样的崩溃日志?该应用程序在系统库内的某处崩溃,没有更多其他信息。有什么方法可以找到崩溃的原因吗?

更新: 我搜索了很多论坛帖子,其中异常类型是EXC_CRASH (SIGABRT),崩溃线程堆栈的第一行是:

线程 0 崩溃:
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 核心基础 0x335c8210 0x33534000 + 606736
11 核心基础 0x3354ea8e 0x33534000 + 109198

这个异常类型 ( EXC_CRASH (SIGABRT)) 是什么意思?

4

1 回答 1

5

首先,您需要使用 DSYM 符号化崩溃日志以了解发生了什么。您需要在构建应用程序时就拥有 DSYM 文件。DSYM 文件允许您将这些内存地址的映射反向映射回可读的代码行。

SIGABRT 是当您有未处理的异常时收到的信号,例如[someArray objectAtIndex:2]如果数组只有 1 个项目时调用。或者,更常见的是无法识别的选择器:[NSArray unsignedIntValue].

看看这个问题中的崩溃日志。请注意,Foundation 中的调用堆栈库与您的代码相同 - 它是一个无法识别的选择器。

你的代码是:

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

您没有告诉我们的——但非常重要的——是“foo”中的内容。您如何分配该 NSNumber?如果它是 NSNumber 以外的任何其他对象,那么您的崩溃日志将看起来像您的。

如果你想在你的编程中真正防御,你可以说:

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

但实际上,无论您的“foo”是什么,都应该始终返回一个 NSNumber。

于 2010-11-28T20:11:13.593 回答