iOS查看系统闪退日志

一、使用dysm查看手机闪退日志一、使用dysm查看手机闪退日志

我们在ios开发中会碰到的很多crash问题,如果Debug调试模式的话,我们可以往往很容易的根据log的输出定位到导致crash的原因,但对于已经上线的应用,或者是release环境包导致的crash,我们就需要一些特殊的手段来通过crash log进行分析定位了。

通过参考网上的一些资料,总结了一下,下面介绍一下通过dSYM文件以及crash log分析定位的方法。

1.导出crash log

通过Xcode的Organizer查看某台iphone设备的DeviceLog,选择需要的crash log,导出XXX.crash文件。

2.找到对应的app文件

找到当前iphone设备上安装的ipa文件,更改文件后缀名为zip,解压后得到Payload文件夹,你需要的app文件就在其中了。

3.找到对应build版本的dSYM文件

dSYM文件是iOS编译后保存16进制函数地址映射信息的文件,每次应用程序build后,都会生成对应的xxx.app, xxx.app.dSYM文件。

4.确定dSYM、app以及crash文件的关系

每一个xx.app, xxx.app.dSYM文件都拥有相应的uuid,crash文件也有uuid,只有三者uuid一至才表明之三者可以解析出正确的日志文件。

查看xx.app文件的uuid的方法,在terminal中输入命令:

dwarfdump --uuid xxx.app/xxx (xxx工程名)

查看xx.app.dSYM文件的uuid的方法,在terminal中输入命令:

dwarfdump --uuid xxx.app.dSYM (xxx工程名)

而.crash的uuid位于,crash日志中的Binary Images:中的第一行尖括号内。如:

armv7 <8bdeaf1a0b233ac199728c2a0ebb4165>

将对应的xxx.app.dSYM文件以及xxx.app文件以及xxx.crash文件拷贝到同一文件夹中,如:~/Desktop/DebugLog。

5.通过symbolicatecrash分析crash文件

Xcode有自带的symbolicatecrash工具,可以通过dSYM文件将crash文件中的16进制地址转换成可读的函数地址。symbolicatecrash工具位于:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKit.framework/Versions/A/Resources/symbolicatecrash(Xcode 4.5)

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash(Xcode 5.0)

该文件是隐藏文件,可以通过如下命令查找并拷贝到系统目录下,并建立快捷方式。

1)打开终端,进入到symbolicatecrash工具所在的文件夹目录

cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/

2)查找确认是否存在symbolicatecrash

ls -al | grep symbolicatecrash

3)将symbolicatecrash工具拷贝到/usr/bin目录下

sudo cp symbolicatecrash /usr/bin/symbolicatecrash

4)设置DEVELOPER_DIR系统变量

cd ~/

vi .bash_profile

并输入如下内容

export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"

保存并退出

source .bash_profile

5)重启终端,确认是否已正确设置DEVELOPER_DIR系统变量

echo $DEVELOPER_DIR

查看输出结果是否为/Applications/Xcode.app/Contents/Developer

6)查看PATH系统变量是否存在如下路径/usr/bin

echo $PATH

7)如果PATH不存在如下路径/usr/bin,可在~/.bash_profile中添加如下代码

export PATH="/usr/bin:$PATH"

保存并退出

source .bash_profile

8)上述准备工作完成后,进入dSYM和crash文件对应的文件夹目录,如

cd ~/Desktop/DebugLog

9)执行如下命令,即可正确解析crash文件

symbolicatecrash xxx.crash xxx.app.dSYM > test.txt

注意:symbolicatecrash的参数顺序,否则会报类似如下错误

Use of uninitialized value $data in substitution (s///) at /usr/bin/symbolicatecrash line 678.

Use of uninitialized value $data in substitution (s///) at /usr/bin/symbolicatecrash line 681.

Use of uninitialized value $data in substitution (s///) at /usr/bin/symbolicatecrash line 685.

Use of uninitialized value in pattern match (m//) at /usr/bin/symbolicatecrash line 404.

Use of uninitialized value in scalar assignment at /usr/bin/symbolicatecrash line 418.

No crash report version in XXX.app.dSYM/ at /usr/bin/symbolicatecrash line 954.

二、捕获闪退事件上报服务器

.h文件

#import@interface NSException (bpExtension)

@property (readonly, nonatomic) NSString *formatDescription;

@end

@interface BPCrashManager : NSObject

/**

*  构造方法,单例

*/

+ (instancetype)sharedManager;

/**

*  注册捕获异常方法

*

*  @param callback 捕获异常回调

*/

- (void)startWithCallback:(void(^)(NSException *exception))callback;

/**

*  回调

*/

@property (copy, nonatomic) void (^callback)(NSException *);

/**

*  是否打印日志

*/

@property (assign, nonatomic) BOOL enableCrashLog;

@end

.m文件

#import "BPCrashManager.h"

@class BPCrashManager;

void unCaughtExceptionHandler(NSException *exception) {


    BPCrashManager *manager = [BPCrashManager sharedManager];

    BOOL enableLog = [manager enableCrashLog];


    if (enableLog) {

      // NSLog(@"crash info:\n %@", exception.formatDescription);

    }


    if (manager.callback) {

        manager.callback(exception);

    }

}

@implementation NSException (bpExtension)

- (NSString *)formatDescription

{

    NSString *fmtDate = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterLongStyle];


    NSString *fmt = @"\n\nDate:\n%@\nCrash:\n%@\nStack Trace\n%@\n";

    NSString *fmtDesc = [NSString stringWithFormat:fmt,

                        fmtDate, self.description, self.callStackSymbols];

    return fmtDesc;

}

@end

@implementation BPCrashManager

+ (instancetype)sharedManager

{

    static BPCrashManager *_manager = nil;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _manager = [[BPCrashManager allocWithZone:NULL] init];

    });

    return _manager;

}

- (void)startWithCallback:(void (^)(NSException *))callback

{

    self.callback = callback;

    NSSetUncaughtExceptionHandler(&unCaughtExceptionHandler);

}

@end

使用方法:

__weak typeof(self) wkSelf = self;

    self.crashReporter = [[BPCrashReporter alloc] init];

    [BPCrashManager sharedManager].enableCrashLog = YES;

    [[BPCrashManager sharedManager] startWithCallback:^(NSException *exception) {

        [wkSelf.crashReporter saveCrashLog:exception.formatDescription toFilepath:CrashLogFilepath()];

    }];

其中删除线的地方,你可以把闪退日志上传,或者写到本地文件。

三、读取本地闪退文件

这边可以自己创建一个textview 在app中某个特定位置设计连点3次或者摇晃,弹出该textview,从而展示闪退日志。

你可能感兴趣的:(iOS查看系统闪退日志)