app ios 不崩溃 卡屏
2017-12-18 10:01:46 ZuoZhiHen 阅读数 178

最近脑子开始不好用了,现在开始记录下一些走过的坑,

这次发布ios app 在测试环境没有问题,结果发布到苹果商店通过审核后,出现了app闪退的情况

问题原因是debug和release版本的问题。release版本有更多的要求,解决办法是去xcode里面的项目里面 和pods配置里面修改2处(一共4处)

code generation和swift compiler中都有设置第三方的optimiztion level 因为有这 设置了 debug和 release的不一样导致了。生产环境闪退问题。把他们都改成none就行了


另外如果不知道问题在哪的话。推荐方法是找生产环境如何查找ios崩溃日志,关键字:查看ios release崩溃日志

留着以后看

http://blog.csdn.net/hmh007/article/details/54350273

http://blog.sina.com.cn/s/blog_6dce99b10101atr3.html

http://www.cocoachina.com/ios/20170703/19707.html

http://www.jianshu.com/p/5119f76d93d6

2015-05-20 09:50:52 garr_odie 阅读数 638

转自点击打开链接 

作者:Matthijs Hollemans 

为了说明问题,我写了一个带Bug的Demo。

这个是Demo下载链接 : 点击打开链接 (ps:在Xcode 4.3 下写的这个demo特意留了几个bug和warming)

运行这个Demo需要在模拟器上面,在真机上也可以,只是展现的bug问题的顺序不一定一样。如图:


看吧,程序运行以后crash了。iOS 中crash主要分两种:SIGABRT(也叫EXC_CRASH) 和 EXC_BAD_ACCESS(他也可能会显示在SIGBUS或SIGSEGV下)。

SIGABRT型的crash相对容易排查,他是一种可控的crash。app在这个地方crash是因为系统识别出这非app想做的事。

而EXC_BAD_ACCESS型的crash相对难排查,因为他只在app, 通常是内存管理的问题。

可喜的是,这个Demo的是SIGABRT型的(后面还有bug,别急)。SIGABRT型的crash一般都会在Xcode的Debug输出栏(找不到Debug输出栏的同纸私聊)带有error描述(Xcode的右下方).就像下面所写:

Problems[14465:f803] -[UINavigationController setList:]: unrecognized selector sent to
instance 0x6a33840
Problems[14465:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[UINavigationController setList:]: unrecognized selector sent to instance 0x6a33840'
*** First throw call stack:
(0x13ba052 0x154bd0a 0x13bbced 0x1320f00 0x1320ce2 0x29ef 0xf9d6 0x108a6 0x1f743
0x201f8 0x13aa9 0x12a4fa9 0x138e1c5 0x12f3022 0x12f190a 0x12f0db4 0x12f0ccb 0x102a7
0x11a9b 0x2792 0x2705)
terminate called throwing an exception
这个Debug输出栏的信息很重要,他提供了非常重要的Bug发生的位置的线索,比如这句:

[UINavigationController setList:]: unrecognized selector sent to instance 0x6a33840
这条错误信息"unrecognized selector sent to instance XXX",意思是app想调用的这个方法不存在,这通常是由这个方法被错误的对象调用了。

这里的问题是UINavigationController(在内存地址为0x6a33840)调用的方法是 setList:

知道了crash引起的原因非常不错,但是你第一步要做的是找到crash发生的具体位置。



待续。。。。



2016-02-17 11:17:03 casun_li 阅读数 953

1.  友盟  http://www.umeng.com/ 

     但现在还只支持oc ,不支持swift ,如果是swift代码有问题,捕捉不到问题

   MobClick.setCrashReportEnabled(true)
   MobClick.setLogEnabled(true)
   let version:String = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String
   MobClick.setAppVersion(version)
   MobClick.startWithAppkey("", reportPolicy: REALTIME, channelId: nil)

2. NSSetUncaughtExceptionHandler 也是不支持swift

MyUncaughtExceptionHandler.h :  

#import <Foundation/Foundation.h>

@interface MyUncaughtExceptionHandler : NSObject

+ (void)setDefaultHandler;
+ (NSUncaughtExceptionHandler *)getHandler;
+ (void)TakeException:(NSException *) exception;

@end


MyUncaughtExceptionHandler.m :  

#import "MyUncaughtExceptionHandler.h"

NSString * applicationDocumentsDirectory()
{
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

void UncaughtExceptionHandler(NSException * exception)
{
    NSArray * arr = [exception callStackSymbols];
    NSString * reason = [exception reason];
    NSString * name = [exception name];
    NSString * url = [NSString stringWithFormat:@"========异常错误报告========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[arr componentsJoinedByString:@"\n"]];
    NSString * path = [applicationDocumentsDirectory() stringByAppendingPathComponent:@"Exception.txt"];
    [url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"%s:%d %@", __FUNCTION__, __LINE__, url);
	//NSString *urlStr = [NSString stringWithFormat:@"mailto:wy@91goal.com?subject=客户端bug报告&body=很抱歉应用出现故障,感谢您的配合!发送这封邮件可协助我们改善此应用<br>"
	//					"错误详情:<br>%@<br>--------------------------<br>%@<br>---------------------<br>%@",
	//					name,reason,[arr componentsJoinedByString:@"<br>"]];
	
	//NSURL *url2 = [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
	//[[UIApplication sharedApplication] openURL:url2];
}

@implementation MyUncaughtExceptionHandler

-(NSString *)applicationDocumentsDirectory
{
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

+ (void)setDefaultHandler
{
    NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
}

+ (NSUncaughtExceptionHandler *)getHandler
{
    return NSGetUncaughtExceptionHandler();
}

+ (void)TakeException:(NSException *)exception
{
    NSArray * arr = [exception callStackSymbols];
    NSString * reason = [exception reason];
    NSString * name = [exception name];
    NSString * url = [NSString stringWithFormat:@"========异常错误报告========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[arr componentsJoinedByString:@"\n"]];
    NSString * path = [applicationDocumentsDirectory() stringByAppendingPathComponent:@"Exception.txt"];
    [url writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];

    NSLog(@"%s:%d %@", __FUNCTION__, __LINE__, url);
}

@end

 

在didFinishLaunchingWithOptions方法中:

//        NSSetUncaughtExceptionHandler({
//            ex in
//            print("-------------UncaughtExceptionHandler---------------")
//            print(ex)
//        })
        MyUncaughtExceptionHandler.setDefaultHandler()



3. bugly : 支持swift   http://bugly.qq.com/iosfast#access


4. 漫谈iOS Crash收集框架  http://www.cocoachina.com/ios/20150701/12301.html


5 iOS自带的崩溃日志bug收集功能  :a . 从xcode找到devices 选项中的view devices logs

                                                          b.  应用提交到app store后可从 iTunes Connect 获取

                                                          c. 请用户将设备与电脑上的iTunes Store同步后,系统会将崩溃日志保存在电脑上,让用户email发送给开发者


    参考文档(案例分析):http://www.cocoachina.com/industry/20130725/6677.html
2015-08-24 10:11:57 Johnkui 阅读数 2970

APP新版本上线之前,一般都会经过测试团队的反复测试,确认无bug后才会发布。发布那刻作为开发人员的你,估计欣喜若狂吧,自豪吧!!。发布后线上运行好长一段时间,均安然无恙,可突然有一天你们家CEO说,自家APP崩了,出现闪退了。那一刻在CEO面前感觉弱爆了的感觉有木有啊?着急了吧,抓狂了吧,F**K it, 怎么解决呢?君不必太过忧伤,且听我给你细说。

获取iOS APP崩溃日志

你造吗,iOS系统会生成各APP闪退的崩溃日志?“哦,在哪里?长什么样?”要过去iOS系统生成的Crash日志,请将发生崩溃异常的Apple设备连接到你的Mac电脑,打开Xcode->Window->Devices菜单,出现如下界面:
这里写图片描述
点击View Device Logs按钮可以查看接入手机中所有的Crash日志,选择相应APP的某条Crash日志点击右键导出该日志并命名为myCrash.crash

这里写图片描述

查找该日志对应的dSYM文件和APP包

刚才导出的日志有如天书般让人云里雾里,要想将其翻译成易懂的文字,我们需要两个文件的帮助,该日志对应的dSYM文件和该App ipa文件,根据导出日志里的App 版本号可以从你的XcodeArchive记录里可以找到当时发布该版本的xcarchive文件:
这里写图片描述

选择相应的xcarchive文件,右键在Finder中显示,接着右键显示包内容:
这里写图片描述
将该dSYM拷贝到myCrash.crash同目录下;同理将该Products下的XXX.app拷贝到myCrash.crash同目录下:
这里写图片描述
文件汇总如下图:

这里写图片描述

将Crash日志Symbolicate

1)确定三个文件的UUID一致
使用dwarfdump命令可以查看XXX.app以及dSYM文件的UUID:

crash Johnkui$ dwarfdump --uuid XXX.app/XXX 
UUID: 9E4C94C4-DBA8-3E13-AE4D-75654E1FEC18 (armv7) XXX.app/XXX
UUID: 956EA55D-0CF2-335D-8DAC-7537216DDD78 (arm64) XXX.app/XXX
crash Johnkui$ dwarfdump --uuid XXX.app.dSYM/
UUID: 9E4C94C4-DBA8-3E13-AE4D-75654E1FEC18 (armv7) XXX.app.dSYM/Contents/Resources/DWARF/XXX
UUID: 956EA55D-0CF2-335D-8DAC-7537216DDD78 (arm64) XXX.app.dSYM/Contents/Resources/DWARF/XXX

崩溃日志myCrash.crash的UUID可以在日志文件里的Binary Images:中第一行尖括号内,
arm64 <956ea55d0cf2335d8dac7537216ddd78>,和上面两个文件的UUID匹配,因此三者UUID一致。

2)使用symbolicatecrash工具
Xcode有自带的symbolicatecrash工具,可以通过dSYM文件将crash文件中的16进制地址转换成可读的函数地址,在Xcode中,搜索该工具的位置,不同版本的Xcode该工具的位置不太一样:

crash Johnkui$  find /Applications/Xcode.app/ -name symbolicatecrash

Xcode 8位于:

/Applications/Xcode.app//Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

将该工具拷贝到/urs/bin/目录下,但是Mac OS 11后系统关闭了root权限,可以通过重新启动Mac,同事按住Command+R,然后打开Terminal, 输入csrutil disable开启root权限,然后重启设置DEVELOPER_DIR系统变量:

crash Johnkui$ cd ~/
~ Johnkui$ vi .bash_profile
输入:
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
保存后:
~ Johnkui$ source .bash_profile 
...
crash Johnkui$ symbolicatecrash XXX.crash XXX.app.dSYM>XXX.txt

最后打开该XXX.txt文件,即可查看bug出现在哪行代码了。

2016-06-28 15:49:00 weixin_34204722 阅读数 4

iOS中App崩溃问题是在所难免的,那如何在崩溃之前给用户一些提示,或是可以将这些崩溃信息发送给自己,以便于自己修正呢?前段时间做项目时,一直没添加这方面的功能,这两天没事从网上看了些资料,顺便自己做了个Demo测试了一下,今天把我了解的东西整理一下。

IOS SDK中提供了一个现成的函数NSSetUncaughtExceptionHandler 用来做异常处理,但功能非常有限,而引起崩溃的大多数原因如:内存访问错误,重复释放等错误就无能为力了,因为这种错误它抛出的是Signal,所以必须要专门做Signal处理。

Demo运行环境:Xcode7.3, iOS9.3

步骤一:定义一个UncaughtExceptionHandler类

UncaughtExceptionHandler.h内容:

#import <UIKit/UIKit.h>

@interface UncaughtExceptionHandler : NSObject
{
  BOOL dismissed;
}

@end

void InstallUncaughtExceptionHandler();

UncaughtExceptionHandler.m内容:

#import "UncaughtExceptionHandler.h"
#include <libkern/OSAtomic.h>
#include <execinfo.h>

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 UncaughtExceptionHandler

+ (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;
    }
}

- (void)handleException:(NSException *)exception
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"程序出现问题啦", nil) message:[NSString stringWithFormat:NSLocalizedString(@"崩溃信息\n"@"%@\n%@", nil), [exception reason], [[exception userInfo] objectForKey:UncaughtExceptionHandlerAddressesKey]] delegate:self cancelButtonTitle:NSLocalizedString(@"离开", nil) otherButtonTitles: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


NSString* getAppInfo()
{
    NSString *appInfo = [NSString stringWithFormat:@"App : %@ %@(%@)\nDevice : %@\nOS Version : %@ %@\n",
                         [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"],
                         [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"],
                         [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"],
                         [UIDevice currentDevice].model,
                         [UIDevice currentDevice].systemName,
                         [UIDevice currentDevice].systemVersion];
    NSLog(@"Crash!!!! %@", appInfo);
    return appInfo;
}

void MySignalHandler(int signal)
{
    int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
    if (exceptionCount > UncaughtExceptionMaximum)
    {
        return;
    }
    NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:signal] forKey:UncaughtExceptionHandlerSignalKey];
    NSArray *callStack = [UncaughtExceptionHandler backtrace];
    [userInfo setObject:callStack forKey:UncaughtExceptionHandlerAddressesKey];
    // 创建一个OC异常对象
    NSException *ex = [NSException exceptionWithName:UncaughtExceptionHandlerSignalExceptionName reason:[NSString stringWithFormat:NSLocalizedString(@"Signal %d was raised.\n"@"%@", nil), signal, getAppInfo()] userInfo:userInfo];
    // 处理异常消息
    [[[UncaughtExceptionHandler alloc] init] performSelectorOnMainThread:@selector(handleException:) withObject:ex waitUntilDone:YES];
}

void InstallUncaughtExceptionHandler()
{
    signal(SIGABRT, MySignalHandler);
    signal(SIGILL, MySignalHandler);
    signal(SIGSEGV, MySignalHandler);
    signal(SIGFPE, MySignalHandler);
    signal(SIGBUS, MySignalHandler);
    signal(SIGPIPE, MySignalHandler);
}
步骤二:在AppDelegate中导入本类
#import "UncaughtExceptionHandler.h"

- (void)installUncaughtExceptionHandler
{
    InstallUncaughtExceptionHandler();
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self installUncaughtExceptionHandler];
    return YES;
}
效果图如下:
1520559-526eb4215c860ce0.png
崩溃截图.png

当然,也可以把这些崩溃信息通过邮箱发送给自己,这个根据项目需求来自定义。

[参考]http://www.111cn.net/sj/ios8/89772.htm

转载于:https://www.jianshu.com/p/a273e6de8ebd

iOS app崩溃捕获

阅读数 4

iOS 9.2 App崩溃

阅读数 10

没有更多推荐了,返回首页