| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- //
- // LPExceptionHandler.m
- // Mach-O UUID
- //
- // Created by Jack on 2018/8/1.
- // Copyright © 2018年 emerys. All rights reserved.
- //
- #import "RAExceptionHandler.h"
- #import <UIKit/UIDevice.h>
- #import <sys/utsname.h>
- // Mach-O UUID
- #import <mach-o/ldsyms.h>
- // CPU arch
- #import <mach-o/arch.h>
- // Slide Address
- #include <mach-o/dyld.h>
- @interface RAExceptionHandler ()
- @property (nonatomic,copy) void (^handler)(NSString *);
- + (instancetype)sharedHanlder;
- @end
- #pragma mark - dSYM UUID
- // 获取主执行Image UUID,此UUID要和dSYM文件UUID相同
- NSString *mach_oUUID() {
- const uint8_t *command = (const uint8_t *)(&_mh_execute_header + 1);
- for (uint32_t idx = 0; idx < _mh_execute_header.ncmds; ++idx) {
- if (((const struct load_command *)command)->cmd == LC_UUID) {
- command += sizeof(struct load_command);
- // return [NSString stringWithFormat:@"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
- // command[0], command[1], command[2], command[3],
- // command[4], command[5],
- // command[6], command[7],
- // command[8], command[9],
- // command[10], command[11], command[12], command[13], command[14], command[15]];
-
- CFUUIDRef uuidRef = CFUUIDCreateFromUUIDBytes(NULL, *((CFUUIDBytes*)command));
- NSString* uuidStr = (__bridge_transfer NSString*)CFUUIDCreateString(NULL, uuidRef);
-
- return uuidStr;
-
- } else {
- command += ((const struct load_command *)command)->cmdsize;
- }
- }
- return nil;
- }
- #pragma mark - CPU Type
- const char *byteOrder(enum NXByteOrder BO) {
- switch (BO) {
- case NX_LittleEndian: return ("Little-Endian");
- case NX_BigEndian: return ("Big-Endian");
- case NX_UnknownByteOrder: return "Unknow";
- default: return ("!?!");
- }
- }
- void testGetAllArch () {
-
- const NXArchInfo *known = NXGetAllArchInfos();
-
- while (known && known->description) {
- printf("known: %s\t%x/%x\t%s\n", known->description,
- known->cputype,
- known->cpusubtype,
- byteOrder(known->byteorder));
- known++;
- }
- }
- // 获取CPU架构类型
- NSString *localCPUType() {
- const NXArchInfo *local = NXGetLocalArchInfo();
-
-
- if (local) {
- printf("Local - %s\t%x/%x\t%s\n", local->description,
- local->cputype,
- local->cpusubtype,
- byteOrder(local->byteorder));
-
- return [NSString stringWithUTF8String:local->description];
- }
- return @"unknown";
- }
- #pragma mark - Slide Address
- //获取基地址
- uintptr_t loadAddress() {
- const struct mach_header *exe_header = NULL;
- for (uint32_t i = 0; i < _dyld_image_count(); i++) {
- const struct mach_header *header = _dyld_get_image_header(i);
- if (header->filetype == MH_EXECUTE) {
- exe_header = header;
- break;
- }
- }
-
- //返回值即为加载地址
- return (uintptr_t)exe_header;
- }
- // 获取偏移地址
- uintptr_t slideAddress() {
-
- uintptr_t vmaddr_slide = 0;
- for (uint32_t i = 0; i < _dyld_image_count(); i++) {
- const struct mach_header *header = _dyld_get_image_header(i);
- if (header->filetype == MH_EXECUTE) {
- vmaddr_slide = _dyld_get_image_vmaddr_slide(i);
- break;
- }
- }
-
- return (uintptr_t)vmaddr_slide;
- }
- #pragma mark - Binary Image
- NSString *binaryImageName() {
-
- for (uint32_t i = 0; i < _dyld_image_count(); i++) {
- const struct mach_header *header = _dyld_get_image_header(i);
- if (header->filetype == MH_EXECUTE) {
-
- const char *path = _dyld_get_image_name((unsigned)i);
- NSString *imagePath = [NSString stringWithUTF8String:path];
- NSArray *array = [imagePath componentsSeparatedByString:@"/"];
- NSString *imageName = array[array.count - 1];
- return imageName;
-
- break;
- }
- }
-
- return nil;
- }
- #pragma mark - Caught Exception
- void UncaughtExceptionHandler(NSException *exception) {
-
- NSMutableString *exceptionStr = [NSMutableString string];
-
- UIDevice *device = [UIDevice currentDevice];
- NSString *modle = device.model;
- NSString *os = device.systemName;
- NSString *ver = device.systemVersion;
-
- struct utsname systeminfo;
- uname(&systeminfo);
- NSString *deviceString = [NSString stringWithCString:systeminfo.machine encoding:NSUTF8StringEncoding];
-
- [exceptionStr appendFormat:@"Device: %@\n",modle];
- [exceptionStr appendFormat:@"OS: %@ %@\n",os,ver];
- [exceptionStr appendFormat:@"Hardware: %@\n",deviceString];
-
- NSDictionary* infoDict =[[NSBundle mainBundle] infoDictionary];
- NSString* build =[infoDict objectForKey:@"CFBundleVersion"];
- NSString* version =[infoDict objectForKey:@"CFBundleShortVersionString"];
- NSString *bundleID = [infoDict objectForKey:@"CFBundleIdentifier"];
- NSString *bundleName = [infoDict objectForKey:@"CFBundleName"];
-
- [exceptionStr appendFormat:@"Bundle Name: %@\n",bundleName];
- [exceptionStr appendFormat:@"build: %@\n",build];
- [exceptionStr appendFormat:@"version: %@\n",version];
- [exceptionStr appendFormat:@"identifier: %@\n",bundleID];
-
- NSDate *date = [NSDate date];
- NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
- [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
- NSString *dateStr = [formatter stringFromDate:date];
-
- [exceptionStr appendFormat:@"Date/Time: %@\n\n",dateStr];
-
- NSArray *callStack = [exception callStackSymbols];
- NSString *reason = [exception reason];
- NSString *name = [exception name];
-
- [exceptionStr appendFormat:@"%@\n%@\n\n%@\n\n",name,reason,callStack];
- [exceptionStr appendFormat:@"dSYM UUID: %@\n",mach_oUUID()];
- [exceptionStr appendFormat:@"CPU Type: %@\n",localCPUType()];
- [exceptionStr appendFormat:@"Slide Address: 0x%lx\n",slideAddress()];
- [exceptionStr appendFormat:@"Binary Image: %@\n",binaryImageName()];
- [exceptionStr appendFormat:@"Base Address: 0x%lx\n",loadAddress()];
-
- NSLog(@"exception:\n%@",exceptionStr);
-
- if ([RAExceptionHandler sharedHanlder].handler) {
- [RAExceptionHandler sharedHanlder].handler(exceptionStr);
- }
- }
- #pragma mark - Handler
- @implementation RAExceptionHandler
- + (instancetype)sharedHanlder {
- static RAExceptionHandler *handler = nil;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- handler = [[RAExceptionHandler alloc] init];
- });
- return handler;
- }
- + (void)registHandler:(void (^)(NSString *))handler {
- [[RAExceptionHandler sharedHanlder] registExceptionHandler:handler];
- }
- - (void)registExceptionHandler:(void (^)(NSString *))handler {
- NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
- self.handler = handler;
- }
- @end
|