iOS崩溃报告获取二
//
// JKExceptionHandler.h
// JKExceptionHandler
//
// Created by Jack on 16/9/7.
// Copyright © 2016年 mini1. All rights reserved.
// #import <Foundation/Foundation.h> @interface JKExceptionHandler : NSObject
{
BOOL dismissed;
}
@end void HandleException(NSException *exception);
void SignalHandler(int signal); void InstallUncaughtExceptionHandler(void);
//
// JKExceptionHandler.m
// JKExceptionHandler
//
// Created by Jack on 16/9/7.
// Copyright © 2016年 mini1. All rights reserved.
// #import "JKExceptionHandler.h"
#import <UIKit/UIKit.h>
#import <libkern/OSAtomic.h>
#import <execinfo.h> #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations" NSString * const UncaughtExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName";
NSString * const UncaughtExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";
NSString * const UncaughtExceptionHandlerAddressesKey = @"UncaughtExceptionHandlerAddressesKey"; volatile int32_t UncaughtExceptionCount = 0;
const int32_t UncaughtExceptionMaximum = 10; const NSInteger UncaughtExceptionHandlerSkipAddressCount = 4;
const NSInteger UncaughtExceptionHandlerReportAddressCount = 5; @implementation JKExceptionHandler + (NSArray *)backtrace
{
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 < UncaughtExceptionHandlerSkipAddressCount +
UncaughtExceptionHandlerReportAddressCount;
i++)
{
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
free(strs); return backtrace;
} - (void)alertView:(UIAlertView *)anAlertView clickedButtonAtIndex:(NSInteger)anIndex
{
if (anIndex == 0)
{
dismissed = YES;
}else if (anIndex==1) {
NSLog(@"continue");
}
} - (void)validateAndSaveCriticalApplicationData
{ } - (void)handleException:(NSException *)exception
{
[self validateAndSaveCriticalApplicationData]; UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(@"抱歉,程序出现了异常", nil)
message:[NSString stringWithFormat:NSLocalizedString(
@"如果点击继续,程序有可能会出现其他的问题,建议您还是点击退出按钮并重新打开\n\n"
@"异常原因如下:\n%@\n%@", nil),
[exception reason],
[[exception userInfo] objectForKey:UncaughtExceptionHandlerAddressesKey]]
delegate:self
cancelButtonTitle:NSLocalizedString(@"退出", nil)
otherButtonTitles:NSLocalizedString(@"继续", nil), nil];
[alert show]; CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop); while (!dismissed)
{
for (NSString *mode in (__bridge NSArray *)allModes)
{
CFRunLoopRunInMode((CFStringRef)mode, 0.001, false);
}
} CFRelease(allModes); NSSetUncaughtExceptionHandler(NULL);
signal(SIGABRT, SIG_DFL);
signal(SIGILL, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGBUS, SIG_DFL);
signal(SIGPIPE, SIG_DFL); if ([[exception name] isEqual:UncaughtExceptionHandlerSignalExceptionName])
{
kill(getpid(), [[[exception userInfo] objectForKey:UncaughtExceptionHandlerSignalKey] intValue]);
}
else
{
[exception raise];
}
} @end void HandleException(NSException *exception)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
} NSArray *callStack = [JKExceptionHandler backtrace];
NSMutableDictionary *userInfo =
[NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
[userInfo
setObject:callStack
forKey:UncaughtExceptionHandlerAddressesKey]; [[[JKExceptionHandler alloc] init]
performSelectorOnMainThread:@selector(handleException:)
withObject:
[NSException
exceptionWithName:[exception name]
reason:[exception reason]
userInfo:userInfo]
waitUntilDone:YES];
} void SignalHandler(int signal)
{
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
if (exceptionCount > UncaughtExceptionMaximum)
{
return;
} NSMutableDictionary *userInfo =
[NSMutableDictionary
dictionaryWithObject:[NSNumber numberWithInt:signal]
forKey:UncaughtExceptionHandlerSignalKey]; NSArray *callStack = [JKExceptionHandler backtrace];
[userInfo
setObject:callStack
forKey:UncaughtExceptionHandlerAddressesKey]; [[[JKExceptionHandler alloc] init]
performSelectorOnMainThread:@selector(handleException:)
withObject:
[NSException
exceptionWithName:UncaughtExceptionHandlerSignalExceptionName
reason:
[NSString stringWithFormat:
NSLocalizedString(@"Signal %d was raised.", nil),
signal]
userInfo:
[NSDictionary
dictionaryWithObject:[NSNumber numberWithInt:signal]
forKey:UncaughtExceptionHandlerSignalKey]]
waitUntilDone:YES];
} void InstallUncaughtExceptionHandler(void)
{
NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);
} #pragma clang diagnostic pop
iOS崩溃报告获取二的更多相关文章
- iOS崩溃报告获取一
在AppDelegate.m文件中实现函数 void UncaughtExceptionHandler(NSException *exception) { /** * 获取异常崩溃信息 */ NSAr ...
- 【译】理解与分析ios应用的崩溃报告
源网址: http://developer.apple.com/library/ios/#technotes/tn2151/_index.html 当一个应用程序崩溃时,创建一份“崩溃报告”对于理解崩 ...
- 转 理解与分析ios应用的崩溃报告
理解与分析ios应用的崩溃报告 源网址: http://developer.apple.com/library/ios/#technotes/tn2151/_index.html 当一个应用程序崩溃时 ...
- 常用获取Android崩溃日志和IOS崩溃日志的几种方法
一:前言 在日常测试app时,经常会遇到崩溃问题,测试快速抓取到崩溃日志可以有效方便开发进行定位,快速解决问题所在测试做到测试分析,定位是非常重要的,这也是判断一个测试能力指标的一大维度. 二:And ...
- iOS错误报告中关于崩溃地址的分析
http://blog.csdn.net/gaoyp/article/details/46912753 一.错误报告中的三种地址:stack addressload addresssymbol add ...
- iOS崩溃日志分析-b
1名词解释 1.1. UUID 一个字符串,在iOS上每个可执行文件或库文件都包含至少一个UUID,目的是为了唯一识别这个文件. 1.2. dwarfdump 苹果提供的命令行工具,其中一些功能就是查 ...
- 如何看iOS崩溃日志
重点:Triggered by Thread这句话后边的线程号,快速定位问题出现在那个线程,是否是你的锅:Triggered by Thread所指的线程表示导致异常.崩溃的线程 下边内容转自简书 简 ...
- Xcode查看iOS崩溃与崩溃日志分析
一.造成崩溃的原因 1.代码中存在bug 2.Watchdog 超时机制 3.用户强制退出 4.低内存终止 5.其他违法系统规则的操作,大部分是内存问题 二.崩溃的类型 1.信号错误类 (1)EXC_ ...
- (转)直接拿来用!最火的iOS开源项目(二)
“每一次的改变总意味着新的开始.”这句话用在iOS上可谓是再合适不过的了.GitHub上的iOS开源项目数不胜数,iOS每一次的改变,总会引发iOS开源项目的演变,从iOS 1.x到如今的iOS 7, ...
随机推荐
- Delphi 7下使用Log4Delphi 0.8日志组件
Log4Delphi是一个开放源码项目,旨在制作用于Borland的Delphi高质量实用的日志套件,是基于Apache Software Foundation的log4j包. 安装: ...
- Eclipse SVN插件安装与使用(2014.12.27——by小赞)
安装参考:http://www.cnblogs.com/xdp-gacl/p/3497016.html 用法参考:http://blog.sina.com.cn/s/blog_8a3d83320100 ...
- Codeforces 294E Shaass the Great
树形DP.由于n只有5000,可以直接枚举边. 枚举边,将树分成两个子树,然后从每个子树中选出一个点分别为u,v,那么答案就是: 子树1中任意两点距离总和+子树2中任意两点距离总和+子树1中任意一点到 ...
- Oracle创建表空间、创建用户、授权用户、导入dmp备份语句
create tablespace TOPSCF_CHS_TS datafile 'D:\TableSpace\TOPSCF_CHS_TS.dbf' size 512M extent managem ...
- html自定义checkbox、radio、select —— checkbox、radio篇
前些日子,所在公司项目的UI做了大改,前端全部改用 Bootstrap 框架,Bootstrap的优缺点在此就不详述了,网上一大堆相关资料. 前端的设计就交给我和另一个同事[LV,大学同班同学,毕业后 ...
- php分页类代码和使用
在这要说的一点就是如果你做的分页是有搜索条件的,那么就可以用下面的代码,然后调用之后在new Page()里面把连接加进去就可以了.例如: $href="http://www.***.cn/ ...
- mvc分层的原理
首先这是现在最基本的分层方式,结合了SSH架构.1.modle层就是对应的数据库表的实体类.2.Dao层是使用了hibernate连接数据库.操作数据库(增删改查).3.Service层:引用对应的D ...
- docker rancher 负载均衡做路由跳转
介绍 我们要实现的目的是 根据负载均衡 跳转到指定的应用容器中 负载均衡中配置好 跳转的地址 当执行URL 请求的时候会自动跳转 测试方法 curl -v --header 'Host:mu.03in ...
- Java JDBC批处理插入数据操作(转)
在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...
- java程序员从笨鸟到菜鸟系列
http://blog.csdn.net/csh624366188/article/category/888600