在iOS开发中经常需要靠记录日志来调试应用程序、解决崩溃问题等,整理常用的日志输出和崩溃日志分析。
最新更新:2018-11-30
基于CocoaLumberjack 的 Swift使用封装库
一、崩溃的捕获
1、崩溃日志产生原因1、应用中有Bug。
2、Watchdog 超时机制
3、用户强制退出
4、低内存终止
5、其他违反系统规则的操作,大部分是内存问题
发生崩溃,系统会生成一份崩溃日志在本地,或者上传 ITC
2、崩溃的类型(异常、信号错误)
异常类
NSRangeException等 NSException类
信号错误类
信号中断(SGIABRT)、非法指令信号(SIGILL)、总线错误信号(SIGBUS)、段错误信号(SIGSEGV)、访问一个已经释放的对象(EXC_BAD_ACCESS)
3、捕获异常崩溃信息
只能捕获一些异常崩溃,如 unrecognized selector、NSRangeException beyond bounds越界等Exception属错误
Appdelegate在Appdelegate 的 didFinishLaunchingWithOptions 中 添加
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
方法实现如下
void UncaughtExceptionHandler(NSException *exception) {
/**
* 获取异常崩溃信息
*/
NSArray *callStack = [exception callStackSymbols];
NSString *reason = [exception reason];
NSString *name = [exception name];
NSString *content = [NSString stringWithFormat:@"========异常错误报告========
name:%@
reason:
%@
callStackSymbols:
%@",name,reason,[callStack componentsJoinedByString:@"
"]];
//将崩溃信息持久化在本地,下次程序启动时、或者后台,将崩溃信息作为日志发送给开发者。
[[NSUserDefaults standardUserDefaults] setObject:content forKey:@"ExceptionContent"];
}
测试数组越界错误
NSMutableArray *array = [NSMutableArray array];
NSLog(@"%@",array[1]);
4、捕获信号错误崩溃信息
信号类型崩溃捕获,测试的时候如果测试Signal类型的崩溃,不要在xcode下的debug模式进行测试。因为系统的debug会优先去拦截。应该build好应用之后直接点击运行app进行测试。
1、什么是信号在计算机科学中,信号(英语:Signals)是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式。它是一种异步的通知机制,用来提醒进程一个事件已经发生。当一个信号发送给一个进程,操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。
在iOS中就是未被捕获的Objective-C异常(NSException),导致程序向自身发送了SIGABRT信号而崩溃。SIGABRT–程序中止命令中止信号
SIGALRM–程序超时信号
SIGFPE–程序浮点异常信号
SIGILL–程序非法指令信号
SIGHUP–程序终端中止信号
SIGINT–程序键盘中断信号
SIGKILL–程序结束接收中止信号
SIGTERM–程序kill中止信号
SIGSTOP–程序键盘中止信号
SIGSEGV–程序无效内存中止信号
SIGBUS–程序内存字节未对齐中止信号
SIGPIPE–程序Socket发送失败中止信号
2、捕获方法Appdelegate 的 didFinishLaunchingWithOptions 中 添加
signal(SIGHUP, SignalHandler);
signal(SIGINT, SignalHandler);
signal(SIGQUIT, SignalHandler);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);
方法实现如下
void SignalHandler(int signal){
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
}
void* callstack[128];
int frames = backtrace(callstack, 128);
char **strs = backtrace_symbols(callstack, frames);
int i;
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
for (
i = UncaughtExceptionHandlerSkipAddressCount;
i
UncaughtExceptionHandlerReportAddressCount;
i++)
{
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
fr