//
// 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崩溃报告获取二的更多相关文章

  1. iOS崩溃报告获取一

    在AppDelegate.m文件中实现函数 void UncaughtExceptionHandler(NSException *exception) { /** * 获取异常崩溃信息 */ NSAr ...

  2. 【译】理解与分析ios应用的崩溃报告

    源网址: http://developer.apple.com/library/ios/#technotes/tn2151/_index.html 当一个应用程序崩溃时,创建一份“崩溃报告”对于理解崩 ...

  3. 转 理解与分析ios应用的崩溃报告

    理解与分析ios应用的崩溃报告 源网址: http://developer.apple.com/library/ios/#technotes/tn2151/_index.html 当一个应用程序崩溃时 ...

  4. 常用获取Android崩溃日志和IOS崩溃日志的几种方法

    一:前言 在日常测试app时,经常会遇到崩溃问题,测试快速抓取到崩溃日志可以有效方便开发进行定位,快速解决问题所在测试做到测试分析,定位是非常重要的,这也是判断一个测试能力指标的一大维度. 二:And ...

  5. iOS错误报告中关于崩溃地址的分析

    http://blog.csdn.net/gaoyp/article/details/46912753 一.错误报告中的三种地址:stack addressload addresssymbol add ...

  6. iOS崩溃日志分析-b

    1名词解释 1.1. UUID 一个字符串,在iOS上每个可执行文件或库文件都包含至少一个UUID,目的是为了唯一识别这个文件. 1.2. dwarfdump 苹果提供的命令行工具,其中一些功能就是查 ...

  7. 如何看iOS崩溃日志

    重点:Triggered by Thread这句话后边的线程号,快速定位问题出现在那个线程,是否是你的锅:Triggered by Thread所指的线程表示导致异常.崩溃的线程 下边内容转自简书 简 ...

  8. Xcode查看iOS崩溃与崩溃日志分析

    一.造成崩溃的原因 1.代码中存在bug 2.Watchdog 超时机制 3.用户强制退出 4.低内存终止 5.其他违法系统规则的操作,大部分是内存问题 二.崩溃的类型 1.信号错误类 (1)EXC_ ...

  9. (转)直接拿来用!最火的iOS开源项目(二)

    “每一次的改变总意味着新的开始.”这句话用在iOS上可谓是再合适不过的了.GitHub上的iOS开源项目数不胜数,iOS每一次的改变,总会引发iOS开源项目的演变,从iOS 1.x到如今的iOS 7, ...

随机推荐

  1. suse系统卸载数据库实例

    1.停止数据库: 2.执行以下命令: find $ORACLE_BASE/* -name '*[Tt][Ee][Ss][Tt]*'  其中TEST为数据库的实例名: 删除存在的文件: 3.删除/etc ...

  2. 水leetcode 爬楼梯

    public class Solution { public int climbStairs(int n) { if(n==1) return 1; if(n==2) return 2; int pr ...

  3. HTML5 Canvas核心技术—图形、动画与游戏开发.pdf1

    canvas元素可以说是HTML5元素中功能最强大的一个,它真正的能力是通过Canvas的context对象(绘图上下文)表现出来的 fillText()方法使用fillStyle属性来填充文本中的字 ...

  4. ubuntu遇到包依赖问题出错的解决方法

    更新时遇到了libc6包依赖错误,甚至“sudo apt-get -f install“也会报错, 这时候可以使用下列命令删除包后重新安装dpkg -r --force-all 包名称 然后再sudo ...

  5. 云之讯融合通讯开放平台_提供融合语音,短信,VoIP,视频和IM等通讯API及SDK。

    云之讯融合通讯开放平台_提供融合语音,短信,VoIP,视频和IM等通讯API及SDK. undefined 全明星之极验证 - SendCloud undefined [转载]国内外几个主流的在线开发 ...

  6. 循环中continue和break的区别

    continue是指跳出本次循环 进入下次循环 再来一次 break是指循环结束 再也不来了 可以用一个广告来解释这个区别 这是continue 房:Hi 郭:是你啊 房:我订的书到了吗 房:啊!对了 ...

  7. linux系统下安装apache与tomcat

    apache的安装 把安装包放到/soft 下 [root@localhost ~]#cd /soft [root@localhost soft]#tar jxvf httpd-2.2.25.tar. ...

  8. jbpm6 开发环境搭建

     一.软件下载 1. eclipse       下载地址:http://www.eclipse.org/downloads/ 2.jbpm6.2 Installer       下载地址: ht ...

  9. (linux shell)第一章--小试牛刀(上)

    来源:(linux shell)第一章--小试牛刀(上) 从今天開始,我们一起来学习<linux shell脚本攻略>这本书. 1.1简单介绍 shell脚本一般是一个以#!起始的文本文件 ...

  10. 在Eclipse中怎样公布创建的JavaWebproject

    博客<在Eclipse中怎样创建JavaWebproject>中图文并茂的说明了Eclipse中创建JavaWebproject的方法:博客<怎样为Eclipse开发工具中创建的Ja ...