如何读取Xcode 6.1仪器.trace文件?

我一直在尝试使用仪器来读取使用自定义乐器模板(乐器: AutomatorAllocationsLeaks )生成的.trace文件。

我在这个stackoverflow答案中find最好的帮助。 基本上, 作者创build了一个自定义的Objective-C程序( 追踪 )来读取特定types的.trace文件(仪器: OpenGL ES驱动程序 )。 他的回答是面向XCode 4.6

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

简单地运行跟踪程序给了我一个uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** class error for 'XRObjectAllocRun'错误uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** class error for 'XRObjectAllocRun'错误。

这个错误最初很容易弄清楚。 我所要做的只是实现缺失的类XRObjectAllocRun ; 与XRRun的示例XRRunXRVideoCardRun类相似 。

这是我得到了多less,我卡在哪里:

 #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类。 但无论解码多less个对象,我总是会收到以下exception: uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** NSUnarchiver: inconsistency between written and read data for object 0x100112750'

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

有谁知道苹果XRObjectAllocRun类的签名? 这个类用于分配工具。

任何帮助将是伟大的!

更新

我玩弄了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)") 

这是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 

如果你需要的话,我已经在这里上传了其他类的签名。

而不是在Swift中声明所需的类,您可以简单地将头文件从归档文件导入桥接头。

我做了它的工作。 这是git项目。