iOS异常捕获和处理
2013年4月份整理的代码,仅作记录:
//先宏定义
//发布和未发布状态的日志切换
#ifdef DEBUG
//异常栈开关
#define STACK_KEY YES
//日志重定向开关
#define STDERR_KEY NO
//调试日志
#define DebugLog(format,...) NSLog(@"{%s,%d}" format, __FUNCTION__,__LINE__,##__VA_ARGS__)
//异常栈日志
#define StackLog(format,...) NSLog(@"{%s,%d}" format, __FUNCTION__,__LINE__,##__VA_ARGS__)
//输出日至
#define DLOG(...) NSLog(__VA_ARGS__)
//输出详细日志
#define DLOGEXT(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
//输出调用
#define DLOGCALL DLOG(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd))
//输出方法
#define DLOGMETHODNSLog(@"[%s] %@", class_getName([self class]), NSStringFromSelector(_cmd));
//输出点
#define DLOGPOINT(p)NSLog(@"%f,%f", p.x, p.y);
//输出大小
#define DLOGSIZE(p)NSLog(@"%f,%f", p.width, p.height);
//输出矩形
#define DLOGRECT(p)NSLog(@"%f,%f %f,%f", p.origin.x, p.origin.y, p.size.width, p.size.height);
#else
#define STACK_KEY YES
#define STDERR_KEY YES
#define DebugLog(format,...)
#define StackLog(format,...)
#define DLOG(...)
#define DLOGEXT(...)
#define DLOGCALL
#define DLOGMETHOD
#define DLOGPOINT(p)
#define DLOGSIZE(p)
#define DLOGRECT(p)
#endif
AppDelegate的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中加入以下代码:
//设置异常日志文件
if (STDERR_KEY) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [paths objectAtIndex:0];
NSString *decyStr = [NSString stringWithFormat:@"decrypt.log"];
NSString *logPath = [documentDir stringByAppendingPathComponent:decyStr];
freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "w+", stderr);
}
//异常栈
if (STACK_KEY) {
//设置处理异常的Handler
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
//signal处理机制
struct sigaction mySigAction;
mySigAction.sa_sigaction = stacktrace;
mySigAction.sa_flags = SA_SIGINFO;
sigemptyset(&mySigAction.sa_mask);
sigaction(SIGQUIT, &mySigAction, NULL);
sigaction(SIGILL , &mySigAction, NULL);
sigaction(SIGTRAP, &mySigAction, NULL);
sigaction(SIGABRT, &mySigAction, NULL);
sigaction(SIGEMT , &mySigAction, NULL);
sigaction(SIGFPE , &mySigAction, NULL);
sigaction(SIGBUS , &mySigAction, NULL);
sigaction(SIGSEGV, &mySigAction, NULL);
sigaction(SIGSYS , &mySigAction, NULL);
sigaction(SIGPIPE, &mySigAction, NULL);
sigaction(SIGALRM, &mySigAction, NULL);
sigaction(SIGXCPU, &mySigAction, NULL);
sigaction(SIGXFSZ, &mySigAction, NULL);
}
并在同个页面中实现以下方法:
//异常处理
#pragma mark - DebugMethods
void UncaughtExceptionHandler(NSException *exception) {
StackLog(@"receive a UncaughtExceptionHandler");
NSArray *arr = [exception callStackSymbols];
NSString *reason = [exception reason];
NSString *name = [exception name];
NSString *syserror = [NSStringstringWithFormat:@"UncaughtExceptionHandlerName:%@\nUncaughtExceptionHandlerReason:%@\nUncaughtExceptionHandlerArray:%@",name, reason, arr];
StackLog(@"%@", syserror);
}
void stacktrace(int sig, siginfo_t *info, void *context)
{
NSMutableString * mstr = [[[NSMutableStringalloc] initWithCapacity:0] autorelease];
[mstr appendString:@"Stack:\n"];
StackLog(@"sig %d",sig);
void* callstack[128];
int i, frameCount = backtrace(callstack, 128);
char** strs = backtrace_symbols(callstack, frameCount);
for (i = 0; i < frameCount; ++i) {
[mstr appendFormat:@"%s\n", strs[i]];
}
StackLog(@"Stack Trace:\r\n%@", mstr);
}