iOS应用崩溃(三)——崩溃日志
2015-12-27 00:42
337 查看
一、模拟器上显示堆栈信息
当我们在模拟器上调试时,可能经常遇到下面的内存访问错误:2011-01-17 20:21:11.41 App[26067:207] * -[Testedit retain]: message sent to deallocated instance 0x12e4b
该错误是对一个已经释放的对象进行操作,定位如下:
(1)、设置MallocStackLogging:
①、点击Xcode的Product菜单,选择Edit Scheme…选项
②、选择左侧的Run…,右边点击Arguments
③、在Environment Variables栏里,添加NSZombieEnabled,value为YES;再添加MallocStackLogging,value为YES;
如下图所示:
以上选项只能在模拟器上有效,如果你改变了iOS的版本,需要重新设定。
调试结束后,最好记得把环境变量NSZombieEnabled,MallocStackLogging前面的勾去掉,因为它们会使得内存不会被释放.
(2)、终端输入 info malloc-history 命令,即可得到堆栈信息,从而分析具体问题所在
(gdb) info malloc-history 0x12e4b0
(3)、也可输入如下信息:
(gdb) shell malloc_history {pid/partial-process-name} {address}
PS:内存使用时“EXC_BAD_ACCESS”的错误信息也是经常遇到的,这时我们只要将上面执行文件属性中的 NSZombieEnabled 选上,也能定位该问题。
二、在iPhone上输出日志
iOS开发中我们会遇到程序抛出异常退出的情况,如果是在调试的过程中,异常的信息是一目了然,但是如果是在已经发布的程序中,获取异常的信息有时候是比较困难的。1、可以捕捉的异常(ECX_CRASH)
iOS提供了异常发生的处理API,我们在程序启动的时候可以添加这样的Handler,这样的程序发生异常的时候就可以对一部分的信息进行必要的处理,适时的反馈给开发者。NSException导致程序向自身发送了SIGABRT信号而崩溃;SIGABRT(也叫做ECX_CRASH)是一个比较好解决的Crash,以为他是一个可掌控的crash,App会在一个目的地终止,以为系统意识到app做了一些他不能支持的事情。接口声明:
#import <Foundation/Foundation.h> @interface NdUncaughtExceptionHandler : NSObject + (void)setDefaultHandler; + (NSUncaughtExceptionHandler*)getHandler; @end
接口实现:
#import "NdUncaughtExceptionHandler.h" //返回绝对路径 NSString *applicationDocumentsDirectory() { return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; } void UncaughtExceptionHandler(NSException *exception) { NSArray *arr = [exception callStackSymbols]; NSString *reason = [exception reason]; NSString *name = [exception name]; NSString *url = [NSString stringWithFormat:@"=============异常崩溃报告=============\nname:\n%@\nreason:\n%@\ncallStackSymbols:\n%@", name,reason,[arr componentsJoinedByString:@"\n"]]; NSString *path = [applicationDocumentsDirectory() stringByAppendingPathComponent:@"Exception.txt"]; [url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil]; //除了可以选择写到应用下的某个文件,通过后续处理将信息发送到服务器等 //还可以选择调用发送邮件的的程序,发送信息到指定的邮件地址 //或者调用某个处理程序来处理这个信息 } @implementation NdUncaughtExceptionHandler //返回绝对路径 -(NSString *)applicationDocumentsDirectory { return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; } + (void)setDefaultHandler { NSSetUncaughtExceptionHandler (&UncaughtExceptionHandler); } + (NSUncaughtExceptionHandler*)getHandler { return NSGetUncaughtExceptionHandler(); } @end
调用事例:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [NdUncaughtExceptionHandler setDefaultHandler]; NSArray *array = [NSArray arrayWithObject:@"there is only one objective in this arary,call index one, app will crash and throw an exception!"]; NSLog(@"%@", [array objectAtIndex:1]); return YES; }
崩溃信息如下:
=============异常崩溃报告============= name: NSRangeException reason: *** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0] callStackSymbols: 0 CoreFoundation 0x0000000108573c65 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x000000010820cbb7 objc_exception_throw + 45 2 CoreFoundation 0x000000010846a17e -[__NSArrayI objectAtIndex:] + 190 3 UIColorDemo 0x0000000107c88914 -[AppDelegate application:didFinishLaunchingWithOptions:] + 164 4 UIKit 0x00000001090be748 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 240 5 UIKit 0x00000001090bf357 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2540 6 UIKit 0x00000001090c219e -[UIApplication _runWithMainScene:transitionContext:completion:] + 1349 7 UIKit 0x00000001090c1095 -[UIApplication workspaceDidEndTransaction:] + 179 8 FrontBoardServices 0x000000010dd095e5 __31-[FBSSerialQueue performAsync:]_block_invoke_2 + 21 9 CoreFoundation 0x00000001084a741c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12 10 CoreFoundation 0x000000010849d165 __CFRunLoopDoBlocks + 341 11 CoreFoundation 0x000000010849c947 __CFRunLoopRun + 887 12 CoreFoundation 0x000000010849c366 CFRunLoopRunSpecific + 470 13 UIKit 0x00000001090c0b02 -[UIApplication _run] + 413 14 UIKit 0x00000001090c38c0 UIApplicationMain + 1282 15 UIColorDemo 0x0000000107c88e4f main + 111 16 libdyld.dylib 0x000000010afcc145 start + 1 17 ??? 0x0000000000000001 0x0 + 1
2、内存等导致的异常(EXC_BAD_ACCESS)
引起崩溃的大多数原因如:内存访问错误(访问了不属于本进程的内存地址),重复释放错误等;EXC_BAD_ACCESS是一个比较难处理的crash了,当一个app进入一种毁坏的状态,通常是由于内存管理问题而引起的时,就会出现出现这样的crash。这种错误它抛出的是Signal,上述方法无法捕捉到。所以必须要专门做Signal处理。代码如下:
相关文章推荐
- iOS应用崩溃(二)——符号化解析
- iOS应用崩溃(一)——Crash文件解析
- [iOS程序启动与运转]- RunLoop个人小结
- iOS9适配
- iOS-应用程序沙盒机制(SandBox)
- iOS中的锁
- IOS-Label
- 蓝懿 ios 技术交流和心得分享 12.26
- (转)cocoapods使用教程
- 浅谈iOS内存管理
- 蓝懿ios继承实际应用
- IOS对于控件用相对布局的方式
- IOS开发:使用真机调试
- ios 3D引擎 SceneKit 开发(2) --贴图篇
- iOS开发实践之FMDB
- nagios安装配置
- 深入浅出 iOS 之多线程 NSThread
- iOs真机调试时编译问题
- iOS开发——图形编程OC篇&(二)CALayer自定义图层
- iOS scrollview中添加button