Last active
August 8, 2018 10:53
-
-
Save wuchuwuyou/fdd20f64510e7652c7d95f5a22b7d988 to your computer and use it in GitHub Desktop.
crash report 崩溃记录
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { | |
InstallSignalHandler(); | |
InstallUncaughtExceptionHandler(); | |
} | |
typedef struct Test | |
{ | |
int a; | |
int b; | |
}Test; | |
- (void)signalCrash { | |
Test *pTest = {1,2}; | |
free(pTest);//导致SIGABRT的错误,因为内存中根本就没有这个空间,哪来的free,就在栈中的对象而已 | |
pTest->a = 5; | |
} | |
- (void)expCrash { | |
NSArray *array= @[@"tom",@"xxx",@"ooo"]; | |
[array objectAtIndex:5]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void InstallSignalHandler(void); | |
void InstallUncaughtExceptionHandler(void); | |
@interface LBUncaughtExceptionHandler : NSObject | |
@end | |
@interface LBUncaughtException : NSObject | |
//- (void)installUncaughtExceptionHandler; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "LBUncaughtExceptionHandler.h" | |
#include <libkern/OSAtomic.h> | |
#include <execinfo.h> | |
@implementation LBUncaughtExceptionHandler | |
NSString *applicationDocumentsDirectory() { | |
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; | |
} | |
void UncaughtExceptionHandler(NSException *exception) { | |
NSArray *arr = [exception callStackSymbols]; | |
NSString *reason = [exception reason]; | |
NSString *name = [exception name]; | |
NSDictionary *userInfo = [exception userInfo]; | |
NSString *dataString = [NSString stringWithFormat:@"=============异常崩溃报告=============\nname:\n%@\nreason:\n%@\ncallStackSymbols:\n%@\nuserInfo:%@\n", | |
name,reason,[arr componentsJoinedByString:@"\n"],userInfo]; | |
NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding]; | |
writInfo(data); | |
} | |
void writInfo(NSData *data) { | |
NSString *fileName = [NSString stringWithFormat:@"%0.0f.crash",[[NSDate date] timeIntervalSince1970]*1000]; | |
NSString *filePath = [NSString stringWithFormat:@"/aaa/bbb/Crash/%@",fileName]; | |
NSString *path = [applicationDocumentsDirectory() stringByAppendingPathComponent:filePath]; | |
writeInfoWithPath(data, path); | |
} | |
void writeInfoWithPath(NSData *data,NSString *path) { | |
NSFileManager *fileManager = [NSFileManager defaultManager]; | |
if (![fileManager fileExistsAtPath:[path stringByDeletingLastPathComponent]]) { | |
[fileManager createDirectoryAtPath:[path stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil]; | |
} | |
[fileManager createFileAtPath:path contents:data attributes:nil]; | |
} | |
@end | |
@implementation LBUncaughtException | |
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; | |
void InstallSignalHandler() { | |
signal(SIGABRT, LBSignalHandler); | |
signal(SIGILL, LBSignalHandler); | |
signal(SIGSEGV, LBSignalHandler); | |
signal(SIGFPE, LBSignalHandler); | |
signal(SIGBUS, LBSignalHandler); | |
signal(SIGPIPE, LBSignalHandler); | |
} | |
void InstallUncaughtExceptionHandler(){ | |
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler); | |
} | |
+ (NSArray *)getBacktrace { | |
void *callStack[128];//堆栈方法数组 | |
int frames=backtrace(callStack, 128);//从iOS的方法backtrace中获取错误堆栈方法指针数组,返回数目 | |
char **strs=backtrace_symbols(callStack, frames);//符号化 | |
int i; | |
NSMutableArray *symbolsBackTrace=[NSMutableArray arrayWithCapacity:frames]; | |
for (i=0; i<frames; i++) { | |
[symbolsBackTrace addObject:[NSString stringWithUTF8String:strs[i]]]; | |
} | |
free(strs); | |
return symbolsBackTrace; | |
} | |
void handleSignalException(NSException *exception) { | |
CFRunLoopRef runLoop = CFRunLoopGetCurrent(); | |
CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop); | |
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]) { | |
UncaughtExceptionHandler(exception); | |
kill(getpid(), [[[exception userInfo] objectForKey:UncaughtExceptionHandlerSignalKey] intValue]); | |
} else { | |
[exception raise]; | |
} | |
} | |
NSString* getAppInfo() { | |
NSString *appInfo = [NSString stringWithFormat:@"App : %@ %@(%@)\n", | |
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"], | |
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"], | |
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]; | |
NSLog(@"Crash!!!! %@", appInfo); | |
return appInfo; | |
} | |
void LBSignalHandler(int signal) { | |
int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount); | |
if (exceptionCount > UncaughtExceptionMaximum) { | |
return; | |
} | |
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:signal] forKey:UncaughtExceptionHandlerSignalKey]; | |
NSArray *callStack = [LBUncaughtException getBacktrace]; | |
[userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey]; | |
NSException *signalException=[NSException exceptionWithName:UncaughtExceptionHandlerSignalExceptionName reason:[NSString stringWithFormat:@"Signal %d was raised.",signal] userInfo:userInfo]; | |
// UncaughtExceptionHandler(signalException); | |
handleSignalException(signalException); | |
// NSArray *callStack = [LBUncaughtException getBacktrace]; | |
// NSString *content = [callStack componentsJoinedByString:@"\n"]; | |
// writInfo([content dataUsingEncoding:NSUTF8StringEncoding]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment