iOS instruments trace文件解析方案
前言
已很少写文章,不过这次感觉有必要写一下。因为:
1. 这个方案通过debug逆向得来,很有参考意义。
2. iOS这方面资料非常少,做这块时,无论国内外,翻遍了google,baidu都没太多合适的资料。
故此,我觉得把整个流程记录下来,你可以认为这是一次iOS instruments的debug之旅。
问题起因
最近做iOS性能测试,要监控一段时间内App的CPU占用和网络流量。遗憾的是,iOS instruments提供的Activity Monitor和Network模板并不满足我的需求。在UI工具中,Activity Monitor只提供了CPU瞬时值,Network也只提供了总流量,它们均不提供采集样本值。
由于iOS闭源,放出的资料又少,故解决此问题的方案屈指可数:
(1). 设备越狱,通过后台守护进程采集数据。
- 缺陷:新设备无法越狱。
(2). 在产品中嵌入性能数据采集模块。
- 缺陷:我不倾向在产品中嵌入测试模块;另外,该方案对第三方产品也失效。
(3). 从instruments结果文件(.trace)中尝试获取样本值。
- 缺陷:能不能做都不知道…
因方案1,2有硬伤,故选方案3尝试。
其实,我开始时也并不确定trace文件包含样本数据,但instruments可通过trace文件恢复监控过程的柱状图,它给了我继续这个方向的信心。

而从trace文件获取样本值,有2个方向:
(1)分析trace结构,获取明文数据
- trace其实是文件夹,但里面文件内容均为二进制,遂放弃......
(2)通过Undocumented API解析trace文件
- 由于instruments可以解析trace文件,那么(2)方法是一定可行的,问题是怎么找到相关的Undocumented API。
Undocumented API可行性确认
Lucky,我同事发现了这玩意:TraceUtility,它一个是获取Time Profiler样本值的工具(那作者也和我一样遇到这种蛋疼问题......),并且Readme中找到重要线索:
(1)所需的Undocumented API在/Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/Frameworks:
DVTInstrumentsFoundation.framework
InstrumentsPlugIn.framework
(2)Instruments模板以PlugIns形式存在于
/Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns
TraceUtility源码分析
项目就2个文件:
InstrumentsPrivateHeader.h: Undocumented API和Undocumented数据结构声明。
main.m:样本数据提取主流程。

深入Debug分析
然而TraceUtility仅用于获取Time Profiler样本数据,并不能满足我获取CPU和网络流量样本的要求。
我需要解决的问题是:
(1)确定instruments处理类。
(2)从处理类中读出样本数据。
1. 确定instruments处理类
方式很简单,在loadDocument后,debug变量trace._baseInstruments


对比图1、2,XRSamplerInstrument=>XRSamplerRun,XRActivityInstrument=>XRActivityRun?,XRNetworkingInstrument=>XRNetworkingRun?;
在另一个github项目class-dump-o-tron, 搜到了相关信息:XRSamplerRun.h,然而在ActivityPlugin.xrplugin下却没找到XRActivityRun.h,而是XRActivityInstrumentRun.h(大Apple的命名能统一点嘛……);在XRNetworkingPlugIn.xrplugin下,找到了XRNetworkingRun.h;
2. 读取trace样本数据
(1)CPU样本结果
debug变量run._data,发现了样本数据

TraceUtility使用了Undocumented API获取数据,而我在XRActivityInstrumentRun.h没找到相关API,直接通过反射获取吧。

至此,CPU样本数据获取完成。
(2)网络流量样本结果

XRNetworkRun和XRActivityInstrumentRun对象属性不一样,没有_data,但_saveActivityQueries中有段sql,初步预估这玩意用了localdb,但db类型未明。另外,估计_saveInstrumentUUID应该db文件。
然后cat 2A183EAD-5B9C-45DD-B2BA-D63DCD1165D4看下,因为文件可能会在头部加注类型信息,cat结果如下:

捕获SQLite文件一个……接下来的事情就是分析表结构了,没什么难度,不作详述了。至此,网络流量样本数据获取完成。
--------------------我是一条的分割线--------------------
补充部分-20160424
关于以上代码,我的实施是在xcode7.2上,但到了xcode7.3,出现些坑爹问题:
在调用PFTLoadPlugins时候,出现crash,如下:

意思是,在xcode7.3后,PFTLoadPlugins()调用了applicationDirectoryName,但在调用applicationDirectoryName前,必须先调用initializeApplicationDirectoryName。而PFTLoadPlugins没有帮我们做init,所以呢,crash了!!!
解决方案:自己动手调用.....
(1)加载DVTFramework。
位置:/Applications/Xcode.app/Contents/SharedFrameworks
原因:initializeApplicationDirectoryName在该库中...
(2)在.h文件增加
@interface DVTDeveloperPaths : NSObject
+ (void)initializeApplicationDirectoryName:(id)arg1;
@end
(3)在main.m中,PFTLoadPlugins()前增加:
id test = @"../../../../../../../Applications/Xcode.app/";
[DVTDeveloperPaths initializeApplicationDirectoryName:test];
完成以上步骤后,PFTLoadPlugins()可以正常执行!
iOS instruments trace文件解析方案的更多相关文章
- IOS的XML文件解析,利用了NSData和NSFileHandle
如果需要了解关于文档对象模型和XML的介绍,参看 http://www.cnblogs.com/xinchrome/p/4890723.html 读取XML 上代码: NSFileHandle *fi ...
- [IOS微信] PList文件解析,boost数据读取
最近在解析IOS版微信数据中的 mmsetting.archive 文件时,第一次接触到PList文件. 注:mmsetting.archive 不是一个标准的PList文件,其中含有汉字,并且很多 ...
- iOS崩溃日志ips文件解析
iOS崩溃日志ips文件解析 一 简介 测试组的同事在进行稳定性测试时,通常会遇到一些崩溃,然后他们会将这些崩溃日志(一般是ips格式的文件)反馈给开发进行分析,但是这些ips文件中的内容通常是如下 ...
- IOS 文件解析
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java ...
- JSON解析方案
在iOS中,JSON的常见解析方案有4种 第三方框架:JSONKit,SBJson,TouchJSON(性能从左到右,越差) 苹果原生(自带):NSJSONSerialization(性能最好) JS ...
- iOS网络-02-数据解析(JSON与XML)
数据交互格式 服务器返回给用户的数据,通常是以下两种方式: JSON XML JSON 一种轻量级的数据数据格式,体积比XML小,是服务器返回给移动端通常采用的格式 用使用JSON文件中的数据,需要对 ...
- iOS - - JSON 和 XML解析
JSON 和 XML 一.JSON 1.什么是JSON JSON是一种轻量级的数据格式,一般用于数据交互 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) 2.JSON的格 ...
- [转载]iOS 10 UserNotifications 框架解析
活久见的重构 - iOS 10 UserNotifications 框架解析 TL;DR iOS 10 中以前杂乱的和通知相关的 API 都被统一了,现在开发者可以使用独立的 UserNotifica ...
- Oracle 10046 trace文件分析
生成10046 trace文件: SQL> create table t10046 as select * from dba_objects; Table created. SQL> se ...
随机推荐
- archlinux 安装过程记录
2014年安装了一次,使用U盘启动安装的,但是当时网络有问题,断断续续,没有做详细记录. 现在到了杭州,重新来一次. 使用U盘安装 下载ISO :http://mirrors.163.com/arch ...
- oc数据类型
数据类型:基本数据类型.指针数据类型 基本数据类型:数值型.字符型(char).布尔型.空类型(void)指针数据类型:类(class).id数值型:整数类型int.浮点型float.doublec和 ...
- C#中的using和yield return混合使用
最近写代码为了为了省事儿用了几个yield return,因为我不想New一个List<T>或者T[]对象再往里放元素,就直接返回IEnumerable<T>了.我的代码里还有 ...
- HTTP中的POST、GET区别
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP ...
- stm32软件模拟IIC读取PX4FLOW光流传感器数据
这段时间在做全国光电设计大赛,用到了px4的px4flow光流传感器,用软件模拟iic读取数据不定期会导致px4flow死机,查了资料和光流的源码,发现这个光流用了stm32的硬件iic,所以对软件模 ...
- ubuntu14.04上Trac配置记录
系统环境:ubuntu14.04 (并假设Apache2服务可以正常运行) 1. 安装软件: sudo aptitude install trac python-mysqldb 2. 创建数据库Tra ...
- ASP.NET Core 1.0 部署 HTTPS (.NET Framework 4.5.1)
var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...
- Navicat Premium下sql导入中文乱码解决方案
今天帮忙朋友找bug的时候,准备导入她数据库里面的数据,所以我就试图在mysql管理工具Navicat下面导入相应的mysql命令.结果发现导入的中文字符全部变成乱码,所以做了如下这种尝试: 在“连接 ...
- C#中调用python方法
最近因为项目设计,有部分使用Python脚本,因此代码中需要调用python方法. 1.首先,在c#中调用python必须安装IronPython,在 http://ironpython.codepl ...
- 学习django之python中os模块的函数
os.sep可以取代操作系统特定的路径分隔符.windows下为 “\\” os.name字符串指示你正在使用的平台.比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'pos ...