Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >iOS如何获取崩溃日志

iOS如何获取崩溃日志

作者头像
测试加
发布于 2022-12-05 04:19:27
发布于 2022-12-05 04:19:27
3.4K00
代码可运行
举报
运行总次数:0
代码可运行

前言

在日常测试iOS中会经常遇到App崩溃的情况,然后给研发提bug。如果就提bug就有一两句话描述,研发很难精准排查问题,所以作为测试人员需要提供崩溃日志或者崩溃堆栈辅助研发排查问题。

本文介绍几种常用获取崩溃日志的方法,可以帮助大家在工作中提高工作效率和协作效率。

iOS获取日志方法

Xcode工具

先来介绍一种最简单的方式使用Xcode工具方式,手机和mac连接后,打开Xcode选择window进入Organizer,在Organizer窗口上,选中Devices 标签栏。

image

在左侧的导航面板上,选中View Device Logs,如下图所示:

Logs菜单就可以看到mac曾经同步过的iOS设备的崩溃日志。

libimobiledevice工具

可能有些同学电脑并没有安装Xcode工具,Xcode的安装下载和安装比较麻烦。这里介绍一种使用第三方工具libimobiledevice的方法。

libimobiledevice是什么?

libimobiledevice又称libiphone,是一个开源包,可以让Linux支持连接iPhone/iPod Touch等iOS设备。

ideviceinstaller是libimobiledevice中的一个命令行工具,ideviceinstaller可以实现安装app,卸载app查看当前电脑连接的设备等操作,和Android的adb命令相似。

libimobiledevice安装

  • brew update
  • brew install libimobiledevice libimobiledevice中并不包含ipa的安装命令,所以还需要安装
  • brew install ideviceinstaller
  • 卸载 brew uninstall libimobiledevice

ideviceinstaller常用命令

命令安装一个ipa文件到手机上,如果是企业签名的,非越狱机器也可以直接安装了。

  • 安装ipa包,卸载应用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ideviceinstaller -i xxx.ipa
  • 命令卸载应用,需要知道此应用的bundleID
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ideviceinstaller -U [bundleID]
  • 查看系统日志
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
idevicesyslog
  • 查看当前电脑连接的设备
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
idevice_id --list
打印出来的是udid
  • 屏幕截屏
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
idevicescreenshot
  • 获取设备时间
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
idevicedate
  • 获取设备名称
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
idevicename

idevicecrashrepor崩溃日志

libimobiledevice中的idevicecrashreport工具可以导出真机crash日志,工具位置在tools下。

参数介绍:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-e, --extract        extract raw crash report into separate '.crash' file

-k, --keep        copy but do not remove crash reports from device
保存到本地文件夹中,需要先手动创建

-d, --debug        enable communication debugging

-u, --udid UDID    target specific device by its 40-digit device UDID
设备的udid

-h, --help        prints usage information

用法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
idevicecrashreport -u 86616cbaa40e52d3f9236ec982dd6f1e933a44bd -e -k /Users/xinxi/Desktop/crash

idevicecrashrepor工具有个缺点在,本地文件夹中导出手机所有的crash日志,没有过滤自定包名的功能、导出的数据量太大了,不方便查看。

但是可以通过修改源码可以增加grep包名功能,导出自定包名的crash日志,如果需要源代码可以关注公众号回复"崩溃日志"即可获取。

过滤包名用法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
idevicecrashreport -u 25228488f97b79c515ab32a2792b83e24ee022de -e  -g LuoJiFM -k /Users/xinxi/Desktop/crashnew

文件格式: LuoJiFM-IOS-2017-05-18-180437.ips.synced,然后把.synced去掉。

崩溃日志符号解析

通过上面两种方式,我们可以拿到crash后的文件。但是crash日志包含很多字符是16进制的,无法看到具体的类名和方法名,所以需要通过把crash文件符号化。

准备工作:

创建一个crashlog的文件夹

转化符号工具:

dsym(符号表文件)

相当于类名和方法名的参考表,Xcode打包的时候会自动产生,我本地的路径在:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
~/Build/Products/ONLINE-iphonesimulator/LuoJiFMIOS.app.dSYM

崩溃日志

用idevicecrashreport工具导出,或者用xcode查看

symbolicatecarsh

symbolicatecarsh是xcode自带解析crash的工具,一般会在xcode安装包下

搜索本地symbolicatecarsh文件

命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
find /Applications/Xcode.app -name symbolicatecrash -type f

我本地的文件地址:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/Applications/Xcode.app/Contents/Developer/Platforms/WatchSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash

给symbolicatecarsh文件权限

命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer

把这三个都放到crashlog文件夹中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cd crashlog的文件夹下

转化执行命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
./symbolicatecrash LuoJiFM-IOS-2017-04-26-152505.crash LuoJiFMIOS.app.dSYM > newcrash.log

执行过程有出现个warning,可以忽略

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Warning: Unable to symbolicate from required binary: /Users/xinxi/Library/Developer/Xcode/iOS DeviceSupport/10.3.1 (14E304)/Symbols/System/Library/Frameworks/CoreMotion.framework/CoreMotion

手动制造一个崩溃

在启动的时候的增加一处断言失败

代码片段:

//判断是否点击了随便看看按钮。 if ([FMAccountUtils isAppLogin] || UDBool(kUserDefault_IsCasualLook) == YES){ NSAssert(1 == 2, @"NSAssert test"); NSLog(@"NSAssert test",1); //断言崩溃 return; }

崩溃日志分析

crash文件文件: LuoJiFMIOS_2018-04-14-211457_xinxideMacBook-Pro.crash

崩溃日志片段

进程信息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Process:              
LuoJiFMIOS [49850]
Path:                  /Users/USER/Library/Developer/CoreSimulator/Devices/DDAC13B0-786D-4DC7-A920-4BEAF56CD616/data/Containers/Bundle/Application/75271871-1E72-4F00-94E0-DC7A353C939B/LuoJiFMIOS.app/LuoJiFMIOS
Identifier:            LuoJiFMIOS
Version:               3.1.9 (3.2.3)
Code Type:             X86-64 (Native)
Parent Process:        launchd_sim [49410]
Responsible:           LuoJiFMIOS [49850]
User ID:               501
设备信息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Date/Time:             2018-04-14 21:10:43.057 +0800
OS Version:            Mac OS X 10.13.2 (17C88)
Report Version:        12
Bridge OS Version:     3.0 (14Y661)
Anonymous UUID:        B687F0B1-763A-73D8-85CC-AD93B3C9F5D8

Sleep/Wake UUID:       E387E09E-8D4A-413B-B96F-01861A8A0708

Time Awake Since Boot: 53000 seconds
Time Since Wake:       1800 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread
异常
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

原因,其中reason就是具体原因

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Application Specific Information:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSAssert test'
terminating with uncaught exception of type NSException
abort() called
CoreSimulator 494.33 - Device: iPhone SE - Runtime: iOS 11.2 (15C107) - DeviceType: iPhone SE

特定于应用程序的追溯,Application Specific Backtrace 1:

从红框中可以看出在AppDelegate setRootController

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试加 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
一文读懂 Python 值传递和引用传递
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2024/02/26
2.5K9
一文读懂 Python 值传递和引用传递
Python函数参数(补充)
  最近看了几篇文章,介绍函数传参数的,下面一一介绍,希望对你理解Python有帮助。
py3study
2020/01/15
3890
关于函数参数传递,80%人都错了
https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference
Crossin先生
2018/07/24
3880
关于函数参数传递,80%人都错了
【python】函数参数传递
在c++中,我们知道函数参数可以传值,也可以传引用。在python中函数参数到底如何传递的呢?
读书猿
2024/02/05
1700
Python函数
阅读文本大概需要 6 分钟 写在前面 这段时间通过公号写文章结交了许多志同道合的朋友,他们中有和我一样的大学生、研究生、以及已经工作的前辈。虽然处于不同的人生阶段,但彼此聊得很 High ,每个人的成长历程中总有相似的地方,遇到的困惑迷茫也大致相同。通过相互间的交流沟通,可能困扰自己很久的问题于前辈而言只是一个小 Case ,所以说要勤于沟通,去找寻属于自己的圈子,这样你才能提升得更快。 分享给大家一个观点,提升认知优先于积累知识。我的微信个签是「努力固然重要,但请记得选择比努力更重要」因为你做出选择的前
Python技术与生活认知的分享
2018/07/03
1K0
Python学习笔记之函数参数传递 传值还是传引用
在学完Python函数那一章节时,很自然的的就会想到Python中函数传参时传值呢?还是传引用?或者都不是? 
Jetpropelledsnake21
2019/02/15
1.9K0
Python 基础系列--函数
在中学数学中我们知道 y=f(x) 代表着函数,x 是自变量,y 是函数 f(x) 的值,给定 x 可以计算出对应的 y。在程序设计中,函数的功能是一样的,给定输入,返回对应的输结果,变量 x 不在限制为数字,可以为任意的数据类型,比如字符串,列表,字典,对象,或者自定义的对象等,同样地返回值也可以任意的数据类型。函数的作用是对加工细节的一种封装,对外提供统一的接口,使用者无需关心函数对内的细节,是最基本的一种代码抽象方式。
somenzz
2020/12/10
5460
Python 基础系列--函数
Python函数
该文介绍了Python函数的相关知识点,包括函数的定义、参数传递方式、可更改对象和不可更改对象、函数调用时的参数使用、匿名函数、变量作用域等。
企鹅号小编
2018/01/09
1K0
Python函数
Python函数参数传递机制
其中Number、String、Tuple和Sets是不可变类型,List和Dictionary是可变类型。
猫叔Rex
2022/01/24
8550
Python函数参数之全面讲解
Python函数参数 Python函数参数 本文主要介绍Python的函数参数,各种形式的参数。建议动手试试,可以加深理解。 函数参数 定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了。对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂的逻辑被封装起来,调用者无需了解。 Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以
1846122963
2018/03/09
1.4K0
Python 函数(一)
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段;通过函数,可以对特定功能的代码进行封装,实现代码的复用。
AiDBA宝典
2022/02/22
4870
女朋友问我:小松子,你知道Go语言参数传递是传值还是传引用吗?
形式参数:是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。
Golang梦工厂
2022/07/08
3670
女朋友问我:小松子,你知道Go语言参数传递是传值还是传引用吗?
Go语言参数传递是传值还是传引用
其实对于传值和传引用,是一个比较古老的话题,做研发的都有这个概念,但是可能不是非常清楚。对于我们做Go语言开发的来说,也想知道到底是什么传递。
飞雪无情
2018/08/28
2.3K0
Go语言参数传递是传值还是传引用
这么多年,总算搞清楚了 Python 参数是如何传递的
值传递,通常就是拷贝参数的值,然后传递给函数里的新变量。这样,原变量和新变量之间互相独立,互不影响。
Wu_Candy
2023/03/06
6700
这么多年,总算搞清楚了 Python 参数是如何传递的
Python 传值 or 传引用
注:本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
宋天伦
2023/10/20
3170
图解Java 中的参数传递是传值还是传引用?
值传递:传递的是实参的副本(更准确的说是实参引用的副本,因为形参接受的是对象的引用)
九转成圣
2024/04/10
2560
图解Java 中的参数传递是传值还是传引用?
Python基础入门_4函数
第四篇内容,这次介绍下函数的基本用法,包括函数的定义、参数的类型、匿名函数、变量作用域以及从模块导入函数的方法,目录如下所示:
kbsc13
2019/08/16
1.1K0
python传参是传值还是传引用
在此之前先来看看变量和对象的关系:Python 中一切皆为对象,数字是对象,列表是对象,函数也是对象,任何东西都是对象。而变量是对象的一个引用(又称为名字或者标签),对象的操作都是通过引用来完成的。例如,a = []是一个空列表对象,变量 a 是该对象的一个引用 例1 def test(c): c.append("hello world") print(c,id(c)) return list = [1,2] test(list) print(list,id(list)) 输出 [1, 2, 'hel
用户1679793
2018/04/28
3.6K0
Python 传值还是传引用
如果 node =None,相当于node指向一个不可变对象,在调用insert函数时,仅传值。
birdskyws
2018/09/12
2.3K0
相关推荐
一文读懂 Python 值传递和引用传递
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验