如何读取 Xcode 6.1 Instruments .trace 文件?

Posted

技术标签:

【中文标题】如何读取 Xcode 6.1 Instruments .trace 文件?【英文标题】:How to read a Xcode 6.1 Instruments .trace file? 【发布时间】:2015-01-14 20:03:59 【问题描述】:

我一直在尝试读取 .trace 文件,该文件是我使用 custom 工具模板生成的(工具:AutomatorAllocations泄漏)使用Instruments。

我在这个*** answer 中找到了最好的帮助。基本上,author 创建了一个自定义 Objective-C 程序(Traced)来读取特定类型的 Apples .trace 文件(仪器:OpenGL ES 驱动程序)。他的回答是针对 XCode 4.6

代码仍然适用于 XCode 6.1,但跟踪文件似乎略有变化。您必须在.trace 包中找到*.run.zip 文件并将其解压缩。在提取的文件夹中,您现在必须找到 *.run 文件。 .trace 包中有几个 *.run.zip 文件;每个使用过的乐器一个。

只需运行Traced 程序就会得到uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** class error for 'XRObjectAllocRun'-error。

这个错误最初很容易发现。我所要做的就是实现缺失的类XRObjectAllocRun;与XRRun.m 中的示例XRRunXRVideoCardRun 类平行。

这是我走了多远以及卡住的地方:

#import "XRObjectAllocRun.h"

@implementation XRObjectAllocRun
- (id)initWithCoder:(NSCoder *)decoder

    if((self = [super init]))
       
        NSObject *a = [decoder decodeObject];
        NSObject *b = [decoder decodeObject];
        NSObject *c = [decoder decodeObject];
        NSObject *d = [decoder decodeObject];
        NSObject *e = [decoder decodeObject];
        NSObject *f = [decoder decodeObject];
        NSObject *g = [decoder decodeObject];
        NSObject *h = [decoder decodeObject];
        NSObject *i = [decoder decodeObject];
//        NSObject *j = [decoder decodeObject];
//        NSObject *k = [decoder decodeObject];   
        NSLog(@"test");
    
    return self;

@end

基本上我被困在逆向工程 XRObjectAllocRun 类。但无论我解码多少对象,我总是收到以下异常:uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** NSUnarchiver: inconsistency between written and read data for object 0x100112750'

如果取消注释最后两个 decode 语句,程序将崩溃并出现以下异常:uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** file inconsistency: read 'i', expecting '@''

有人知道Apples XRObjectAllocRun 类的签名吗?此类用于 Allocations 工具。

任何帮助都会很棒!

更新

我使用 Swift 并翻译了整个 *.trace-reader - 它失败并出现完全相同的错误:

import Foundation
import Cocoa

@objc(XRObjectAllocRun)
class XRObjectAllocRun: NSObject 
    func initWithCoder(decoder:NSCoder)
        var x = decoder.decodeObject()
        // this is where things start breaking...
    


@objc(XRRun)
class XRRun: NSObject 
    // to be implemented    


@objc(XRTrackSegment)
class XRTrackSegment: NSObject 
    func initWithCoder(decoder:NSCoder)->NSString
        var a = decoder.decodeObject()?.integerValue
        var b = decoder.decodeObject()?.integerValue
        var c = decoder.decodeObject()?.integerValue
        var d = decoder.decodeObject()?.integerValue
        var e = decoder.decodeObject()

        return "test"
    


@objc(PFTTrackSegment)
class PFTTrackSegment: NSObject 
    func initWithCoder(decoder:NSCoder)
        var a = decoder.decodeObject()?.integerValue
        var b = decoder.decodeObject()?.integerValue
        var c = decoder.decodeObject()?.integerValue
        var d = decoder.decodeObject()?.integerValue
        var e = decoder.decodeObject()?.integerValue
        var f = decoder.decodeObject()?.integerValue
    


// parse command line
var traceFilePath = Process.arguments[1]
println("input: \(traceFilePath)")

var traceFile = NSURL(fileURLWithPath: traceFilePath)
var error:NSError?

// check if the file exists
if (traceFile?.checkResourceIsReachableAndReturnError(&error) == false)
    // file does not exist or cannot be accessed
    println("\(error)")
    exit(1)


var rawData = NSData(contentsOfURL: traceFile!)
var data = NSUnarchiver(forReadingWithData: rawData!)
var decodedObject: AnyObject? = data?.decodeObject()
println("\(decodedObject)")

【问题讨论】:

尝试看这里:github.com/JustSid/Traced 和这里:***.com/questions/16737621/… 希望对您有所帮助! 谢谢,但这是我开始的地方。我正在使用代码示例并描述如何调整它。不幸的是,我无法像JustSid 那样弄清楚签名。 @MarcoPashkov 你有没有想过如何解析分配跟踪?我也遇到了同样的例外情况。 不幸的是还没有。我在 swift 方面取得了更多进展 - 但还没有。一旦我弄清楚了,我会发布答案。另外,由于我不是全职工作在这个问题上,我不能保证很快就会解决。 【参考方案1】:

这是XRObjectAllocRun类的签名

#import "XRRun.h"

#import "SymbolAwareRun.h"
#import "XRCallTreeDataSource.h"
#import "XRSourceQuery.h"

@class NSMutableArray, NSMutableDictionary, NSString, XRHeapGeneration, XROAEventSummary, XRObjectAllocRunSharedData;

@interface XRObjectAllocRun : XRRun <SymbolAwareRun, XRSourceQuery, XRCallTreeDataSource>

    XRObjectAllocRunSharedData *_sharedData;
    NSMutableArray *_allStats;
    NSMutableDictionary *_statsForCategory;
    NSMutableDictionary *_categoryIDForName;
    XROAEventSummary *_scaleStats;
    NSMutableArray *_generations;
    struct XRTimeRange _filterTimeRange;
    unsigned int _filterMinEventID;
    unsigned int _filterMaxEventID;
    unsigned long long _nextGenNumber;
    NSMutableDictionary *_samplesByCategoryNumber;
    unsigned long long _catNumIndex;
    struct XRTimeRange _currentStatsFilterRange;
    int _lifecycleFilter;
    int _allocationTypeFilter;
    unsigned int *_quickEventCacheIds;
    id *_quickEventCache;
    XRHeapGeneration *_activeGeneration;


+ (void)initialize;
- (id)operation:(id)arg1 commentsForSymbol:(id)arg2 inSourceManager:(id)arg3 callTreeInformation:(id)arg4;
- (id)provideCategories;
- (id)backtracesForCategory:(id)arg1 timeRange:(struct XRTimeRange)arg2 savedIndex:(unsigned long long *)arg3;
- (void)_configureCallTreeForAllocationType:(int)arg1;
- (id)symbolsForEvent:(id)arg1 reverseOrder:(BOOL)arg2;
- (id)backtraceRepository;
- (BOOL)eventIsLiveInCurrentTimeRange:(id)arg1;
- (unsigned int)uncategorizedCount;
- (unsigned int)countOfObjectEventsForCategory:(unsigned int)arg1;
- (void)enumerateObjectEventsForCategory:(unsigned int)arg1 skipToIndex:(unsigned int)arg2 withBlock:(CDUnknownBlockType)arg3;
- (BOOL)_applyLifecycleFilterToEvent:(id)arg1;
- (id)zombieEvent;
- (id)eventForIdentifier:(unsigned int)arg1;
- (BOOL)loadDTPerformanceSessionDataFromPaths:(id)arg1 error:(id *)arg2;
- (void)updateGenerations;
- (void)deleteGeneration:(id)arg1;
- (void)moveGeneration:(id)arg1 toTime:(unsigned long long)arg2;
- (void)setActiveGeneration:(id)arg1;
- (id)generationAtTime:(unsigned long long)arg1;
- (id)generations;
- (id)nextGenerationIdentifier;
- (void)createGenerationAtTime:(unsigned long long)arg1;
- (void)removeFlag:(id)arg1;
- (struct XRTimeRange)_displayTimeFilter;
- (BOOL)_isTimeScoped;
- (BOOL)useTypeFilteringRules:(id)arg1;
- (void)setAllocationTypeFilter:(int)arg1;
- (void)setLifecycleFilter:(int)arg1;
- (struct XRTimeRange)selectedTimeRange;
- (void)setSelectedTimeRange:(struct XRTimeRange)arg1;
- (id)categoryNameForIdentifier:(unsigned int)arg1;
- (id)globalStats;
- (id)scalingStats;
- (void)_clearStats;
- (void)allowEventReuse;
- (void)refreshStatsForActiveTimeFilter;
- (void)_updateStatsWithEventIdentifier:(unsigned int)arg1 category:(unsigned int)arg2 type:(unsigned int)arg3 size:(int)arg4 pastEvent:(unsigned int)arg5 summaryMap:(id *)arg6 maxCat:(unsigned int)arg7;
- (id)_statsObjectForCategoryID:(unsigned int)arg1;
- (void)_changeStatsByTimestampRange:(struct XRTimeRange)arg1 overallRange:(struct XRTimeRange)arg2 startID:(unsigned int)arg3 endID:(unsigned int)arg4;
- (id *)_createCategorySummaryMapWithMaximum:(unsigned int)arg1;
- (void)_validateGlobalStatsForTimeRange:(struct XRTimeRange)arg1;
- (void)_recomputeGlobalStats;
- (BOOL)discardsLifeCycleComplete;
- (unsigned long long)lastTimestamp;
- (id)sharedData;
- (void)setRecordMode:(int)arg1;
- (void)setDiscardsLifeCycleComplete:(BOOL)arg1;
- (void)setTargetDevice:(id)arg1 pid:(int)arg2 repository:(id)arg3;
- (id)initWithCoder:(id)arg1;
- (void)encodeWithCoder:(id)arg1;
- (void)dealloc;
- (id)init;

// Remaining properties
@property(readonly, copy) NSString *debugDescription;
@property(readonly, copy) NSString *description;
@property(readonly) unsigned long long hash;
@property(readonly) Class superclass;

@end

如果你需要的话,我已经上传了其他班级here的签名。

无需在 Swift 中声明所需的类,您可以简单地将头文件从存档导入到桥接头。

【讨论】:

乍一看还不错 - 我会在周末更深入地了解一下! 你在哪里找到的标题? @MarcoPashkov 我使用class-dump 从二进制文件中提取它们。 @MarcoPashkov 你能从跟踪文件中解析分配数据吗?如果是这样,你能给我们一个更新吗?谢谢! 很抱歉,我不得不换档放弃这个项目。但这似乎应该可行,因为 API 可以通过@bzz 建议的工具进行逆向工程。如果包含生成的文件,您应该能够解压缩数据并读取跟踪。【参考方案2】:

我成功了。 Here 是 git 项目。

【讨论】:

以上是关于如何读取 Xcode 6.1 Instruments .trace 文件?的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 4 Memory Leak Instrument如何获取发生泄漏的代码行

录制时 Xcode Instrument 屏幕变黑

检测错误及其解决方案 - Xcode 4.2 - Instrument [Memory Leaks]

Instrument之Core Animation工具

iOS:Xcode 4.2:Leaks Instrument 说我的 NSMutableArray 和 NSMutableDictionary 有泄漏,但我看不到在哪里

如何在构建 IPA 时修复 Xcode 6.1 错误