前言

已很少写文章,不过这次感觉有必要写一下。因为:

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文件解析方案的更多相关文章

  1. IOS的XML文件解析,利用了NSData和NSFileHandle

    如果需要了解关于文档对象模型和XML的介绍,参看 http://www.cnblogs.com/xinchrome/p/4890723.html 读取XML 上代码: NSFileHandle *fi ...

  2. [IOS微信] PList文件解析,boost数据读取

    最近在解析IOS版微信数据中的 mmsetting.archive 文件时,第一次接触到PList文件. 注:mmsetting.archive  不是一个标准的PList文件,其中含有汉字,并且很多 ...

  3. iOS崩溃日志ips文件解析

    iOS崩溃日志ips文件解析  一 简介 测试组的同事在进行稳定性测试时,通常会遇到一些崩溃,然后他们会将这些崩溃日志(一般是ips格式的文件)反馈给开发进行分析,但是这些ips文件中的内容通常是如下 ...

  4. IOS 文件解析

    import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java ...

  5. JSON解析方案

    在iOS中,JSON的常见解析方案有4种 第三方框架:JSONKit,SBJson,TouchJSON(性能从左到右,越差) 苹果原生(自带):NSJSONSerialization(性能最好) JS ...

  6. iOS网络-02-数据解析(JSON与XML)

    数据交互格式 服务器返回给用户的数据,通常是以下两种方式: JSON XML JSON 一种轻量级的数据数据格式,体积比XML小,是服务器返回给移动端通常采用的格式 用使用JSON文件中的数据,需要对 ...

  7. iOS - - JSON 和 XML解析

    JSON 和 XML 一.JSON 1.什么是JSON JSON是一种轻量级的数据格式,一般用于数据交互 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) 2.JSON的格 ...

  8. [转载]iOS 10 UserNotifications 框架解析

    活久见的重构 - iOS 10 UserNotifications 框架解析 TL;DR iOS 10 中以前杂乱的和通知相关的 API 都被统一了,现在开发者可以使用独立的 UserNotifica ...

  9. Oracle 10046 trace文件分析

    生成10046 trace文件: SQL> create table t10046 as select * from dba_objects; Table created. SQL> se ...

随机推荐

  1. OD使用教程12

    载入程序输入关键字: 双击进入程序 仔细看发现并没有跳转直接跳到这个mov,往上看发现retn上面有一个push,在这种编写手法当中这种组合相当于一个jmp, 跳到离它最近的一个值(在这就是004A5 ...

  2. c#下载共享文件夹下的文件并记录错误日志

    public void Run() { //获取目标文件列表 string _ErrorMessage = ""; string _ErrorMessageFile = " ...

  3. Php 笔记

    php基本简介 为何要学习php 通过上网查资料,了解了基本的php知识,并知道了php的优缺点.php是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于学习,使用广泛,主要适用 ...

  4. eclipse快速移动项目到另一台机器_步骤

    ​快速移动项目到另一台机器_步骤 1.设置好eclipse的编码,必须对应个人项目文件的编码{ window--preferences--general--workspace-text file en ...

  5. IE 浏览器 如何关闭令人讨厌的“此网站需要运行以下加载项:XXX。如果您信任该网站和该加载项并允许运行该加载项,请单击这里...

    1.运行gpedit.msc 2.在打开的组策略中打开用户配置——管理模板——Windows组件——Internet Explorer 3.选择“关闭ActiveX选择启用提示”,将其状态改为“已启用 ...

  6. 60行以内写mvc

    标题党.几天前看到一个30行写mvc的文章,东施效颦,也动手写了个60行的,功能上略微扩充一些,记录下来,后面有时间可以继续优化. mvc其实是一个观察者模式.view来监听model,所以当mode ...

  7. 【转】Backbone使用总结

    转自  http://www.pchou.info/javascript/2014/06/26/backbone-summary-01.html 开始在项目中大规模使用backbone,一路磕磕碰碰, ...

  8. loading动画效果记录

    看到好多网页都有一个炫酷的loading动画,以前不知道怎么实现的.今天学习了一下,发现其实也很简单. 首先在学习的时候偶然遇到一个pace.js的库,非常好用.优点是,不需要挂接到任何代码,自动检测 ...

  9. misc

    1.对于给定的二维码图片不能直接扫描出来的可以进行反色在进行扫描,反色可以直接选中图片然后就会进行反色.2.局域网中抓取的数据包的加密方式可能是aes加密.3.凯撒加密可能是变种的凯撒加密,可能奇数偶 ...

  10. day13---堡垒机

    1.业务需求 兼顾业务安全目标与用户体验,堡垒机部署后,不应使用户访问业务系统的访问变的复杂,否则工作将很难推进,因为没人喜欢改变现状,尤其是改变后生活变得更艰难 保证堡垒机稳定安全运行, 没有100 ...