| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- //
- // ExceptionHandler.m
- // IBOSS
- //
- // Created by ssl on 2018/3/2.
- // Copyright © 2018年 elongtian. All rights reserved.
- //
- #import "ExceptionHandler.h"
- #include <libkern/OSAtomic.h>
- #include <execinfo.h>
- NSString * const ExceptionHandlerSignalExceptionName = @"UncaughtExceptionHandlerSignalExceptionName";
- NSString * const ExceptionHandlerSignalKey = @"UncaughtExceptionHandlerSignalKey";
- NSString * const ExceptionHandlerAddressesKey = @"UncaughtExceptionHandlerAddressesKey";
- volatile int32_t UncaughtExceptionCount = 0;
- const int32_t UncaughtExceptionMaximum = 10;
- const NSInteger ExceptionHandlerSkipAddressCount = 4;
- const NSInteger ExceptionHandlerReportAddressCount = 5;
- @implementation ExceptionHandler
- + (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 = ExceptionHandlerSkipAddressCount;
-
- i < ExceptionHandlerSkipAddressCount +
-
- ExceptionHandlerReportAddressCount;
-
- i++)
-
- {
-
- [backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
-
- }
-
- free(strs);
-
-
-
- return backtrace;
-
- }
- - (void)alertView:(UIAlertView *)anAlertView clickedButtonAtIndex:(NSInteger)anIndex
- {
-
- if (anIndex == 0)
-
- {
-
- dismissed = YES;
-
- }
-
- }
- - (void)validateAndSaveCriticalApplicationData
- {
-
-
- }
- - (void)handleException:(NSException *)exception
- {
-
- [self validateAndSaveCriticalApplicationData];
- // 找到Documents文件夹路径
- NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
- NSString *dataFilePath = [documentsPath stringByAppendingPathComponent:IBOSSERROR];
- NSFileManager *fileManager = [NSFileManager defaultManager];
-
- BOOL isDir = NO;
-
- // fileExistsAtPath 判断一个文件或目录是否有效,isDirectory判断是否一个目录
- BOOL existed = [fileManager fileExistsAtPath:dataFilePath isDirectory:&isDir];
-
- if ( !(isDir == YES && existed == YES) ) {
-
- // 在 Document 目录下创建一个 head 目录
- [fileManager createDirectoryAtPath:dataFilePath withIntermediateDirectories:YES attributes:nil error:nil];
- }
-
-
- NSString *str = [exception reason];
- //需要知道字符串最终存储的地方,所以需要创建一个路径去存储字符串
- NSString *strPath = [dataFilePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.log",[self getCurrentTimes]]];
-
- [str writeToFile:strPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
-
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-
- 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:ExceptionHandlerSignalExceptionName])
-
- {
-
- kill(getpid(), [[[exception userInfo] objectForKey:ExceptionHandlerSignalKey] intValue]);
-
- }
-
- else
-
- {
-
- [exception raise];
-
- }
-
- }
- -(NSString*)getCurrentTimes{
-
- NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
-
- // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
-
- [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
-
- //现在时间,你可以输出来看下是什么格式
-
- NSDate *datenow = [NSDate date];
-
- //----------将nsdate按formatter格式转成nsstring
-
- NSString *currentTimeString = [formatter stringFromDate:datenow];
- return currentTimeString;
-
- }
- @end
- void HandleException(NSException *exception)
- {
-
- int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
-
- if (exceptionCount > UncaughtExceptionMaximum)
-
- {
-
- return;
-
- }
-
-
- NSArray *callStack = [ExceptionHandler backtrace];
-
- NSMutableDictionary *userInfo =
-
- [NSMutableDictionary dictionaryWithDictionary:[exception userInfo]];
-
- [userInfo
-
- setObject:callStack
-
- forKey:ExceptionHandlerAddressesKey];
-
-
- [[[ExceptionHandler 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:ExceptionHandlerSignalKey];
-
-
-
- NSArray *callStack = [ExceptionHandler backtrace];
-
- [userInfo
-
- setObject:callStack
-
- forKey:ExceptionHandlerAddressesKey];
-
-
- [[[ExceptionHandler alloc] init]
-
- performSelectorOnMainThread:@selector(handleException:)
-
- withObject:
-
- [NSException
-
- exceptionWithName:ExceptionHandlerSignalExceptionName
-
- reason:
-
- [NSString stringWithFormat:
-
- NSLocalizedString(@"Signal %d was raised.", nil),
-
- signal]
-
- userInfo:
-
- [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:signal] forKey:ExceptionHandlerSignalKey]]
-
- 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);
-
- }
|