18

I am writing an automated profiling system, to profile different GPU intensive screens in my App. I have been trying to use 'XCode Instruments' for this, with the 'OpenGL ES Driver' instrument that captures the gpu usage data.

My automated system runs Xcode Instruments from the command line which runs the App, profiles and captures the data, and writes the data to a ".trace" file.

I now want to be able to open the trace file, and read the trace data using my automated profiling system, so that I can inform App developers of how the various parts of the App perform.

I cannot however find any way of reading the trace file. It seems to be package which contain various directories, and buried in there is a .zip file which seems to contain some binary data. How is the data in this file parsed?

The Instruments system seems fairly sosphisticated, and I've been suprised how hard it has been to access the trace data that it produces.

Does anyone know how to parse the trace file?

I am currently using XCode 4.6.1

Undo
  • 25,519
  • 37
  • 106
  • 129
georgeparrish
  • 193
  • 1
  • 1
  • 5

4 Answers4

20

Alright, so to answer the main question: The data in the .zip archive is a blob of data that was serialized with the NSArchiver class (they have a fairly distinctive header when being opened with a hex tool (I used hex fiend), so that was the first clue). It's fairly straight forward to read, all you have to do is making a call to NSUnarchiver, at least that's the theory. Before I go in into the details, here is a very simple example app that dumps a few infos: https://github.com/JustSid/Traced

So, the problem with NSArchiver, and NSUnarchiver, is that you first of all need to have all the classes that were archived, and second of all you have to read the data out in the order in that it was archived (that was the tricky bit, I used class-dump to dump the interface for a few of the required classes and then tried to unarchive the data object by object and looking at what I got returned. Luckily, NSArchiver dies with descriptive error messages, if there is a class missing, it will tell you what its name is). The biggest problem that I had was that the Instruments binary and the used frameworks don't contain all the classes that I needed, in particular the archive contains serialized data of a class named XRVideoCardRun. I have the assumption that the .template file inside the .trace bundle contains a dynamic library with the required class (I mean, it's over 300kb in size and contains a lot of blobs (it's btw a binary plist)). I was too lazy to extract the binary data out of it and run class-dump against it, and I was lucky enough that most of the data that came out of the archive was consistent with what I was expecting to see for the superclass, XRRun (which I found in one of the Instruments frameworks), with the exception of an array containing dictionaries, which content looked like the sample data.

So, the rest was just combining everything together. If you look into the sample app, the most interesting part should be the XRRun.m and .h file. They contain a bit of documentation, and some pieces on how to extract the data from the samples, although you probably want to replace this with your own logic for your automation. Hope it helps.

The app thrown agains your sample file outputs this:

Run 1, starting at 24.05.13 17:42:16, running until 24.05.13 17:42:28
Sample 0: FPS: 27 Device: 0% Renderer: 0% Tiler: 0% Timestamp: 1.012740
Sample 1: FPS: 35 Device: 11% Renderer: 10% Tiler: 2% Timestamp: 2.018574
Sample 2: FPS: 34 Device: 33% Renderer: 32% Tiler: 7% Timestamp: 3.026101
Sample 3: FPS: 59 Device: 59% Renderer: 59% Tiler: 16% Timestamp: 4.032030
Sample 4: FPS: 60 Device: 59% Renderer: 58% Tiler: 16% Timestamp: 5.038990
Sample 5: FPS: 59 Device: 59% Renderer: 58% Tiler: 16% Timestamp: 6.046022
Sample 6: FPS: 59 Device: 57% Renderer: 53% Tiler: 17% Timestamp: 7.051187
Sample 7: FPS: 60 Device: 67% Renderer: 66% Tiler: 14% Timestamp: 8.057343
Sample 8: FPS: 59 Device: 64% Renderer: 64% Tiler: 11% Timestamp: 9.064914
Sample 9: FPS: 60 Device: 67% Renderer: 67% Tiler: 11% Timestamp: 10.072592
Sample 10: FPS: 59 Device: 65% Renderer: 65% Tiler: 15% Timestamp: 11.080248

(PS: If the format changes, the app will break as well...)

JustSid
  • 25,168
  • 7
  • 79
  • 97
  • Awesome work Sid :) I'm going to try working through the process that you describe for decoding the data, so that I can do this again if there is a format change. I'm also going to raise a feature request with Apple to ask for a better trace data export option on OpenGLES Driver Instrument. Thanks again, George – georgeparrish May 28 '13 at 10:25
  • @georgeparrish You are welcome! Feel free to ask if you have any questions! (By the way, if this answered your question, you can accept it as the correct answer by clicking the gray checkmark next to it) – JustSid May 28 '13 at 12:10
  • What interface will be for profiling CPU or Memory? Where did you find XRVideoCardRun? – Krzysiek Jun 26 '14 at 12:53
  • 1
    I am also doing some research on the trace documents these days and came across your post. I tried to use the frameworks of Instruments itself and I will post my progress in a separate answer later. –  Sep 10 '15 at 12:47
3

I am trying to parse the .trace document using the undocumented frameworks shipped with Instruments itself. It is now working with Time Profiler and it shouldn't be hard to get it working with other instrument templates as well, with a little more reverse engineering work.

There are quite a few frameworks bundled with Instruments as you can see in /Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/Frameworks.

However we only need to link against these two:

  • DVTInstrumentsFoundation.framework
  • InstrumentsPlugIn.framework

Another thing you should know before starting is that instrument templates are actually plugins in /Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns.

For example, SamplerPlugin.xrplugin is for Time Profiler.

The code is short and commented out: https://github.com/Qusic/TraceUtility

0

You may not be able to analyze the Trace file directly with a script, but they can exported to a CSV file that can be analyzed by a script or put into Excel, Numbers, etc. You may even be able to add the export as a CSV to your automated testing, depending on how it is done.

charleyh
  • 2,033
  • 2
  • 20
  • 32
  • I dont want to be able to view the Trace view using instruments. I want to be able to read the file programatically (e.g. using a shell script) so that i can automatically process the data. The intention is that my automated profile system can post profile data results onto a wiki so that other developers can see these results at a glance, when the App is running slowly. – georgeparrish May 24 '13 at 15:04
  • The only way to parse it programmatically is too write a custom script to do that, and it's a very complicated process. I highly recommend you find a different way to do this. – charleyh May 24 '13 at 15:07
  • Hi glenwayguy. I am happy to write a custom script ( that is my job ), I just need to know the format of the file, do you know where i can find the format? thanks for your response – georgeparrish May 24 '13 at 15:08
  • I'm not sure if you can process the trace file directly, however, you can have instruments export them as a CSV that can by analyzed by a script. You might even be able to add the export to your automated testing workflow so you can get the script working on them straight away. – charleyh May 24 '13 at 15:12
  • I have tried to export data in the Instruments program. The menu option is disabled for the 'OpenGL ES Driver' instrument. It is my understanding that not all instruments support export. Unless there is some way to export data using Instruments from the command line, but I've not found how to do that either :( – georgeparrish May 24 '13 at 15:14
  • Oh, your right, I just saw that. I believe you may be out of luck if you are using OpenGL Drivers. You might try going throught the Trace with a script, but I don't see the format anywhere, so you may have to discover it yourself. You may need to give your developers the Trace file directly if you are using OpenGL. I also recommend this because it can give you code suggestions on making it faster, and those are helpful. – charleyh May 24 '13 at 15:19
  • @JustSid please remove the down vote, I updated my answer to reflect the comments. – charleyh May 24 '13 at 15:20
  • My automated system needs to be able to detect when a screen is running slowly, and notify the developer / graphic artists involved in creating the screens only when the screen is running slowly. I want to post the results on a wiki that they can access to see these results, or be able to automatically email them to say "this screen is taking 17ms to render, it needs to be 10ms". They dont have to care about trace files. – georgeparrish May 24 '13 at 15:24
  • I understand, and I'm saying I would recommend letting them view the traces yourself. As iOS developers, I'm sure they can get lots of pertinent info from viewing the trace themselves, including what you mentioned above. And I know from experience that the trace has coding suggestions that can make a big difference in the speed and ease of development. – charleyh May 24 '13 at 15:28
  • You are missing an important point. I only want to inform a developer that a screen is running slowly when the screen is running slowly. I dont want to disturb the developer when there is nothing wrong with the screen. There is no way for me to know if the screen is running slowly without having to manually open each screen in Instruments. We have hundreds of screens. This is not the automated system we desire. Thanks again. – georgeparrish May 24 '13 at 15:31
  • You are going to have to have someone view the trace file in instruments. Whether it is the developer, you, or someone else, if you are using this instrument you need a person looking at it. You may have to have someone sit there and go through hundreds of screens and check the load times. The only way you can automate this would be to write a custom script, but you would have to find out about the structure yourself. Also, there are no guarantees that this would even be possible. I highly recommend that you let someone view the trace files, because automation won't cut it for this situation. – charleyh May 24 '13 at 15:36
  • @glenwayguy You are missing the point, he asks about the file format and if someone knows how it looks like and how to get the data out of there WITHOUT viewing it in Instruments. There has to be a way to access the data, because Instruments can display it just fine. – JustSid May 24 '13 at 16:00
  • Instruments can display it just fine because it is Apple's proprietary software. If you want to call up Apple and ask them for Instruments file loading code, be my guest. Your developer needs to look at the trace himself or find someone to do it. If it can't be exported, it has to be done manually. – charleyh May 24 '13 at 16:05
  • Just because a file format isn't documented, doesn't mean it's impossible to read. See my answer for more details on how to extract the information out of the file without having to touch Instruments in any way. So I'm still going with -1 here. – JustSid May 24 '13 at 21:33
0

.trace is actually a folder and it has a zip 1.run.zip in .trace/instruments_data/ and after some folders you will find the zip. Unzip it and you will get 1.run. Not sure how to decode that. Best way is to call - instruments .trace - this will open in instruments with the details.

Thejus Krishna
  • 1,755
  • 1
  • 19
  • 28