让Xcode的 stack trace信息可读

昨天在写 iOS 代码的时候,调试的时候模拟器崩溃了。异常停在了如下整个 main 函数的入口处:

int main(int argc, char *argv[])
{
@autoreleasepool {
// 异常停在了下面这行,毫无提示作用
return UIApplicationMain(argc, argv, nil, NSStringFromClass([MyClass class]));
}
}

Xcode 的 Console 界面报出了一些出错信息 , 如下图所示:

我根据 Console 里面的文字提示信息,猜出应该是出现了空指针 nil 的操作。但是具体出错在哪一行,却不知道。最终虽然找到了 bug,但是 debug 的过程确实费了些时间。考虑到这个 stace trace 信息应该对我挺有帮助才对的,所以我就查了一下如何让这原本一堆 16 进制的调用栈信息更可读。于是在 stackoverflow 上找到了 2 个比较好的解决办法,在这里分享给大家。

方法一

该 方法 的步骤是,首先在你的 AppDelegate 中定义一个方法 , 用于处理异常:

void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
// Internal error reporting
}

然后在应用启动时,设置这个方法作为自己的自定义异常回调:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
// Normal launch stuff
}

完成之后,当对于上面的异常,在定义了这个回调之后,Log 信息变成如下所示,出错行一目了然,根据下面的可读的 stack trace,我一下就可以找到是 QuestionParser 这个类的第 378 行导致的异常,进而可以跳到出错行分析原因,很容易就把 bug 修复了。

Ape[2711:11303] CRASH: *** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[2]
Ape[2711:11303] Stack Trace: (
0 CoreFoundation 0x0209402e __exceptionPreprocess + 206
1 libobjc.A.dylib 0x01a71e7e objc_exception_throw + 44
2 CoreFoundation 0x0205aa95 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 165
3 CoreFoundation 0x020874e9 +[NSDictionary dictionaryWithObjects:forKeys:count:] + 73
4 Ape 0x00096a0a +[QuestionParser parseToDictionary:] + 378
5 Ape 0x00096434 -[QuestionStore putQuestion:] + 308
6 Ape 0x00089ddf -[QuestionViewController requestFinished:] + 303
7 Ape 0x000869dd -[NetworkAgent requestFinished:] + 653
8 Ape 0x00085d33 __27-[NetworkAgent addRequest:]_block_invoke_0 + 131
9 libdispatch.dylib 0x01cf153f _dispatch_call_block_and_release + 15
10 libdispatch.dylib 0x01d03014 _dispatch_client_callout + 14
11 libdispatch.dylib 0x01cf2fd6 _dispatch_after_timer_callback + 28
12 libdispatch.dylib 0x01d03014 _dispatch_client_callout + 14
13 libdispatch.dylib 0x01cfa8b7 _dispatch_source_latch_and_call + 219
14 libdispatch.dylib 0x01cf6405 _dispatch_source_invoke + 322
15 libdispatch.dylib 0x01cf3768 _dispatch_main_queue_callback_4CF + 187
16 CoreFoundation 0x0203aaf5 __CFRunLoopRun + 1925
17 CoreFoundation 0x02039f44 CFRunLoopRunSpecific + 276
18 CoreFoundation 0x02039e1b CFRunLoopRunInMode + 123
19 GraphicsServices 0x0282b7e3 GSEventRunModal + 88
20 GraphicsServices 0x0282b668 GSEventRun + 104
21 UIKit 0x00be265c UIApplicationMain + 1211
22 Ape 0x00016c5d main + 141
23 Ape 0x00002b05 start + 53
24 ??? 0x00000001 0x0 + 1
)

方法二

方法二相比方法一更加简单,具体做法是在 Xcode 界面中按 cmd + 6 跳到 Breakpoint 的 tab,然后点击左下角的 + 号,增加一个 Exception 的断点,如下图所示。这样,当异常出现时,会自动停在异常处,而不会抛出到 UIApplicationMain。拿我的有 bug 的程序来说,代码会自动断在 QuestionParser 这个类的第 378 行。

总结

其实以前 Xcode 是能显示出可读的 stack trace 信息的,似乎到了 Xcode4.2 以后就出问题了。所以上面提到的 2 个办法相当于 walk around 解决了 Xcode4.2 以后出现的 bug。如果该文章对你有用,希望你能帮我点击下面的分享按钮,分享给更多朋友,同时也帮我宣传一下博客,这将有助于我分享更多的心得给大家,Have fun!

让Xcode的 stack trace信息可读的更多相关文章

  1. 让XCode的Stack Trace信息可读

    程序报错信息如下:

  2. XCode的 Stack Trace,调试时抛出异常,定位到某一行代码

    在Xcode调试程序的时候,总是会出现不知道错误在什么地方的问题,很是捉急,现在又一个办法,可以具体定位到错误行的代码,试一下吧?超级好用 操作很简单: 1.在XCode界面中按cmd + 6快捷键, ...

  3. 怎么从代码中拿到栈回溯信息(call stack trace)

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:怎么从代码中拿到栈回溯信息(call stack trace).

  4. 三、jdk工具之jstack(Java Stack Trace)

    目录 一.jdk工具之jps(JVM Process Status Tools)命令使用 二.jdk命令之javah命令(C Header and Stub File Generator) 三.jdk ...

  5. dump 分析模式之 INCORRECT STACK TRACE - djm2005dy的专栏 - 博客频道 - CSDN.NET

    Dump 分析模式之 INCORRECT STACK TRACE dump 分析模式之 INCORRECT STACK TRACE 翻译自 MDA-Anthology Page288  初学者常犯的错 ...

  6. 项目跑起来之后,一会儿后台就会报错Illegal access: this web application instance has been stopped already. Could not load [com.mchange.v2.resourcepool.BasicResourcePool$1DestroyResourceTask]. The following stack trace

    一月 24, 2016 6:42:54 下午 org.apache.catalina.loader.WebappClassLoaderBase checkStateForResourceLoading ...

  7. This is very likely to create a memory leak. Stack trace of thread

    1.错误描述 警告: The web application [cmp] appears to have started a thread named [Abandoned connection cl ...

  8. java.lang.Exception: DEBUG -- CLOSE BY CLIENT STACK TRACE 的理解

    [2013-12-06 11:06:21,715] [C3P0PooledConnectionPoolManager[identityToken->2tl0n98y1iwg7cbdzzq7a|7 ...

  9. JavaScript 查看stack trace

    How can I get a JavaScript stack trace when I throw an exception? Edit 2 (2017): In all modern brows ...

随机推荐

  1. PMP 第十一章 项目风险管理

    1规划风险管理 2识别风险 3 风险定性分析 4风险定量分析 5规划风险应对 6监控风险 1.项目风险是什么?已知未知风险.未知未知风险对应应急储备和管理储备的关系.风险承受力和风险偏好是什么? 2. ...

  2. 在Salesforce中对某一个Object添加 Validation Rule

    在Salesforce中可以对某一个Object添加相应的 Validation Rule 来进行一个全局的条件判断,比如满足什么样的条件的修改允许提交,不满足的要提示相应的错误信息. 要创建一个Va ...

  3. IM服务器的架构

    一. 总的构架结构示意图: 如上图所示,目前系统总的分成六个模块, 分别为网络/协议解析模块,用户帐号管理模块,消息处理模块,动作处理模块,数据均衡处理模块,客户状态处理模块 . 正常流程应该这么实现 ...

  4. 【转】HTML网页中插入视频各种方法

    现在如果要在页面中使用video标签,需要考虑三种情况,支持Ogg Theora或者VP8(如果这玩意儿没出事的话)的(Opera.Mozilla.Chrome),支持H.264的(Safari.IE ...

  5. js实现页面的自动读秒跳转

    <!-- 代码片段A --> <!-- 倒计时跳转 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Trans ...

  6. 6754 Keyboard of a Mobile Telephone

    /*实践再次说明ch=getchar()的速度非常慢*/ /*大水题,不解释*/ #include<stdio.h> #include<string.h> int main() ...

  7. three.js透视投影照相机

    透视投影照相机(Perspective Camera)的构造函数是: THREE.PerspectiveCamera(fov, aspect, near, far) 让我们通过一张透视照相机投影的图来 ...

  8. 一个基于RBAC0的通用权限设计清单

    注:RBAC0与RBAC1不同在于权限继承.关于RBAC1的权限设计,敬请关注作者后续CSDN博客.1,用户表 保存系统用户信息,如张三.李四,字段可以有id.name.fullname.email. ...

  9. WPF – pass multiple parameters to a Command

    public class SendCommand : ICommand { public void Execute(object parameter) { var labels = ((object[ ...

  10. BZOJ3559 : [Ctsc2014]图的分割

    考试的时候看少了一行,导致暴力都写错额… 贾教说他出的这题水,但是我觉得并不水,那个结论还是很神的. 首先M(i)就是i的最小生成树的最大边, 设f[i]表示i属于哪个集合 我们把边按权值从小到大排序 ...