背景

当我们打包app时,可以选择生成对应的符号表,其保存 16 进制函数地址映射信息,通过给定的函数起始地址和偏移量,可以对应函数具体信息以供分析。

所以我们拿到测试给的闪退日志(.crash)时,需要找到打包时对应生成的符号表(.dSYM)作为钥匙解析。具体分为下面几个步骤

  1. dwarfdump --uuid 命令获取 .dSYMuuid

  2. 打开 .crash 文件,在特定位置找到 uuid

  3. 根据 arm 版本比对两者是否一致

  4. Xcode 目录下寻找 symbolicatecrash 工具

    不同版本文件路径不同,具体版本请谷歌。Xcode9路径是/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/

  5. 设置终端环境变量

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

  6. 使用 symbolicatecrash 工具解析日志

    symbolicatecrash .crash .dsym > a.out

虽然过程不复杂,但是每次都需要手动执行一次检查与命令,过于繁琐,所以决定用脚本化提高效率。


步骤实现

输入Crash日志

#要求输入crash文件路径
inputFile 'Please Input Crash File' 'crash'
crashPath=$filePath

由于需要输入两种不同后缀的文件路径,且都需要检查,因此统一定义一个方法。

#定义全局变量
filePath=
#输入文件路径
inputFile() {
readSuccess=false
#首先清空变量值
filePath=
while [ $readSuccess = false ]; do
echo $1
#读取到变量中
read -a filePath
if [[ ! -e $filePath || ${filePath##*.} != $2 ]]; then
echo "Input file is not ."$2
else
readSuccess=true
fi
done
}

.dSYM 是文件夹路径,所以这里简单的判断了路径是否存在,如果不存在就继续让用户输入。

Shell命令中判断分为[]与[[]],后者比前者更通用,可以使用 || 正则运算等。

判断中,-f表示检查是否存在该文件,-d表示检查是否存在文件夹,-e表示检查是否存在该路径

输入dSYM符号表

dsymSuccess=false
while [ $dsymSuccess = false ]; do
#要求输入dSYM文件路径
inputFile 'Please Input dSYM File' 'dSYM'
dsymPath=$filePath
#检查是否匹配
checkUUID "$crashPath" "$dsymPath"
match=$?
if [ $match -eq 0 ]; then
echo 'UUID not match!'
else
dsymSuccess=true
fi
done

循环获取匹配 UUIDdSYM ,这里使用了另一种方法获取方法返回值,具体之后章节会总结。

查找symbolicatecrash工具

Xcode 文件夹指定路径下查找工具,加快效率,如果没找到就停止运行。

# 查找symbolicatecrash解析工具,内置在Xcode的库文件中
toolPath=`find /Applications/Xcode.app/Contents/SharedFrameworks -name symbolicatecrash | head -n 1`
if [ ! -f $toolPath ]; then
echo "Symbolicatecrash not exist!"
exit 0
fi

执行解析命令

#先设置环境变量
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
#指定解析结果路径
crashName=`basename $crashPath`
afterPath="$(dirname "$crashPath")"/"${crashName%%.*}""_after.crash"
#开始解析
$toolPath "$crashPath" "$dsymPath" > "$afterPath" 2> /dev/null

这里我将错误信息导流到 /dev/null,保证解析文件没有杂乱信息。


遇到的问题

怎么获取函数返回值?

之前没有处理过需要返回数值的方法,所以一开始有点懵,查询资料后最终采用了两种方式实现了效果,现在做一些总结。

全局变量记录

#定义全局变量
filePath=
inputFile() {
#读取到变量中
read -a filePath
}
inputFile
crashPath=$filePath

通过 inputFile 方法来了解一下,首先定义一个全局变量为 filePath,在方法中重新赋值,方法结束后读取全局变量中的数据。

这种方法的好处是可以自定义返回参数类型和个数,缺点是容易和其他变量搞混。

Return返回值

类似与C语言中的用法,脚本也支持 retrun 0 返回结果并停止运行。

checkUUID() {
grep "$arm64id" "$1"
if [ $? -ne 0 ]; then
return 1;
fi
return 0;
}
checkUUID "$crashPath" "$dsymPath"
match=$?

获取结果的方式为 $?,其能够返回环境中最后一个指令结果,也就是之前执行的checkUUID的结果。

优点是简洁明了,符合编码习惯,缺点是返回值只能是 0-255 的数字,不能返回其他类型的数据。

获取打印值

还有一种方法其实平时一直在使用,只不过并不了解其运行方式。

crashName=`basename $crashPath`

print() {
echo "Hello World"
}
text=$(print)

运行系统预设的方法或者自定义方法,将执行命令用 $() 的方式使用,就可以获取该命令中所有打印的信息,赋值到变量就可以拿到需要的返回值。

优点是功能全效率高,使用字符串的方式可以传递定制化信息,缺点是不可预期返回结果,需要通过字符串查找等命令辅助。

循环输入合法路径

在我的设想中,需要用户输入匹配的 dSYM 文件路径,如果不匹配,则重新输入,直到合法。为了支持嵌套,需要定义局部变量控制循环,具体代码如下

dsymSuccess=false
while [ $dsymSuccess = false ]; do
#要求输入dSYM文件路径
inputFile 'Please Input dSYM File' 'dSYM'
dsymPath=$filePath
#检查是否匹配
checkUUID "$crashPath" "$dsymPath"
match=$?
if [ $match -eq 0 ]; then
echo 'UUID not match!'
else
dsymSuccess=true
fi
done

处理字符串

获取到 UUID 所有输出信息后,需要截取出对应平台的信息,处理还是不太熟悉,特地整理如下

#原始信息
UUID: 92E495AA-C2D4-3E9F-A759-A50AAEF446CD (armv7) /Volumes/.dSYM/Contents/Resources/DWARF/app
UUID: 536527A8-0243-34DB-AE08-F1F64ACA4351 (arm64) /Volumes/.dSYM/Contents/Resources/DWARF/app #去除中间间隔-
uuid=${uuid//-/} #从后往前找第一个匹配 \(arm64的,并且都删除
arm64id=${uuid% \(arm64*}
#处理后
UUID: 92E495AAC2D43E9FA759A50AAEF446CD (armv7) /Volumes/.dSYM/Contents/Resources/DWARF/app
UUID: 536527A8024334DBAE08F1F64ACA4351 #从前往后找最后一个UUID: ,并删除
arm64id=${arm64id##*UUID: }
#处理后
536527A8024334DBAE08F1F64ACA4351

总结

看似简单的脚本,也花了一天时间编写,总体还是不太熟练,仍需努力联系。

这次特地尝试了与上次不同的参数输入方法,使用提示输入的方式,果然遇到了新的问题。好在都查资料解决了,结果还算满意。

脚本我提交到了Github,欢迎大家指教共同进步!给个关注最好啦~

脚本处理iOS的Crash日志的更多相关文章

  1. iOS解析crash日志:

    iOS解析crash日志:我们在ios开发中会碰到的很多crash问题,如果Debug调试模式的话,我们可以往往很容易的根据log的输出定位到导致crash的原因,但对于已经上线的应用,或者是rele ...

  2. 查看iOS应用crash日志

    基本操作: 1.电脑安装好Xcode,连接好手机设备 2.打开Xcode,点击Window-Devices and Simulators 3.选中手机设备,点击View Device Logs,即可查 ...

  3. Crash日志分析

    从Crash文件出发解决bug的一般步骤,分三步: a, 获取设备上的崩溃日志. b, 分析崩溃日志,找到报错位置(定位到函数和代码行数). c, 打开代码,改bug. 1, 获取设备日志 1. 在可 ...

  4. ios crash的原因与抓取crash日志的方法

    首先我们经常会闪退的异常有哪些呢?crash的产生来源于两种问题:违反iOS策略被干掉,以及自身的代码bug. 1.IOS策略 1.1 低内存闪退 前面提到大多数crash日志都包含着执行线程的栈调用 ...

  5. iOS Crash日志

    Understanding Crash Reports on iPhone OS https://developer.apple.com/videos/wwdc/2010/?id=317 http:/ ...

  6. iOS:crash崩溃日志分析

    一.前言: 作为一个合格的iOS开发者,除了具有规范强悍的编码能力外,还应该具有过硬的查错纠错能力.在项目运行时,程序崩溃是不可避免的,遇到这个问题,有时会出现一大堆的crash日志,艹,貌似看不懂呀 ...

  7. iOS应用的crash日志的分析基础

        Outline如何获得crash日志如何解析crash日志如何分析crash日志     1. iOS策略相关     2. 常见错误标识     3. 代码bug 一.如何获得crash日志 ...

  8. iOS crash日志分析

    iOS crash日志分析 一. 寻找crash文件:手机崩溃后的ips或者crash文件(ips文件可以直接修改成crash文件,直接改后缀名就可以了),这里说下如何拿到crash文件 1. 把运行 ...

  9. iOS symbolicatecrash工具crash日志分析

    若一个App没有加入Crashlytics或者Buggly这些崩溃日志监控,那么我们在App崩溃的时候如何获取崩溃信息呢? 此时我们可以通过symbolicatecrash工具对手机日志来进行分析定位 ...

随机推荐

  1. SDWC补题计划

    2018的寒假去了SD的冬令营,因为一班二班难度悬殊,对我很不友好,几乎什么也没学会,但是我把两个班的课件都存了下来,现在慢慢把两个班的例题以及课后题都补一补(毕竟冬令营的钱不能白花). 这些题目横跨 ...

  2. Linux - 搭建FastDFS分布式文件系统

    1. FastDFS简介 说明:FastDFS简介部分的理论知识全部来自于博主bojiangzhou的 <用FastDFS一步步搭建文件管理系统>,在此感谢博主的无私分享.当然最最要感谢的 ...

  3. virtualbox+vagrant学习-2(command cli)-5-vagrant halt命令

    Halt 格式: vagrant halt [options] [name|id] 该命令关闭vagrant管理的正在运行的机器. userdeMacBook-Pro:~ user$ vagrant ...

  4. 初识TCP/IP协议

    初识TCP/IP协议 TCP/IP 全称是(Transmission Control Protocol / Internet Protocol),传输控制协议/网际协议.TCP/IP定义了电子设备(比 ...

  5. windows下安装redis并设置自启动

    一.下载windows版本的Redis 去官网找了很久,发现原来在官网上可以下载的windows版本的,现在官网以及没有下载地址,只能在github上下载,官网只提供linux版本的下载 官网下载地址 ...

  6. 解决JS在url中传递参数时参数包含中文乱码的问题

    1.传参页面JavaScript代码: function go_mark(id,jobname,headimgurl,nickname){ window.location.href = "m ...

  7. P1437 [HNOI2004]敲砖块

    题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示. 14 15 4 3 23 33 33 7 ...

  8. 最简单的ASP.Net连接查询Oracle,输出查询数据到表格中

    VS2012中新建Windows窗体应用程序.Oracle中建测试数据表Test.(此处需要环境已配好情况下进行操作) 用到的数据表 向Windows窗体应用程序,设计界面托一个按钮和一个数据表格视图 ...

  9. JQuery Validate插件与实现

    菜鸟拙见,望请纠正 一:效果展示:以下是两个注册表单验证,左边使用Jquery validate插件实现,右边是自己用JQuery实现,效果差不多,但个人推荐用插件,毕竟前人栽了树而且长大了后人当然好 ...

  10. iOS裁剪,缩放图片白边问题解决办法

    几年没来了,感觉还是要写点啥,以后碰见问题 解决就写这吧,当是一个随时的笔记也好. iOS裁剪,缩放图片的代码网上也很多了,但是笔者出现了右边和下边出现白边的情况.出现白边的原因是给的size中的CG ...