问题描述
我一直在尝试读取.trace文件,该文件是使用 custom 工具模板生成的(仪器: Automator ,分配 >,泄漏),使用仪器.
I have been trying to read a .trace file, which I had generated using a custom instruments template(instruments: Automator, Allocations, Leaks) using Instruments.
在此 stackoverflow答案中找到的最佳帮助.基本上,作者创建了一个自定义的 Objective-C 程序(已跟踪)以读取特定类型的Apples .trace文件(仪器: OpenGL ES驱动程序).他的回答针对的是 XCode 4.6 .
The best help I found in this stackoverflow answer. Basically the author created a custom Objective-C program(Traced) to read a specific type of Apples .trace file(instrument: OpenGL ES Driver). His answer is geared towards XCode 4.6.
该代码仍可与 XCode 6.1 一起使用,但是跟踪文件似乎已略有更改.您必须在.trace包中找到*.run.zip文件并将其解压缩.现在,在解压缩的文件夹中,您必须找到*.run文件. .trace程序包中有几个*.run.zip文件.每个使用过的乐器一个.
The code still works with XCode 6.1, but the trace-file seems to have changed slightly. You have to find the *.run.zip file within the .trace package and unzip it. In the extracted folder you now have to find the *.run file. There are several *.run.zip files in a .trace package; one per used instrument.
仅运行跟踪程序,就会出现uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** class error for 'XRObjectAllocRun'-错误.
Simply running the Traced program got me a uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** class error for 'XRObjectAllocRun'-error.
此错误最初很容易弄清楚.我要做的就是实现缺少的类XRObjectAllocRun;平行于XRRun或XRVideoCardRun类.
This error was initially easy to figure out. All I had to do was implement the missing class XRObjectAllocRun; parallel to the example XRRun or XRVideoCardRun classes in XRRun.m.
这是我走多远,我被困住的地方:
This is how far I got and where I got stuck:
#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'
Basically I am stuck reverse-engineering the XRObjectAllocRun class. But no matter how many or little objects I decode I always receive the following exception: uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** NSUnarchiver: inconsistency between written and read data for object 0x100112750'
如果您取消对最后两个decode语句的注释,程序将因以下异常而崩溃:uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** file inconsistency: read 'i', expecting '@''.
If you uncomment the last two decode statements the program will crash with this exception: uncaught exception 'NSArchiverArchiveInconsistency', reason: '*** file inconsistency: read 'i', expecting '@''.
有人知道Apple XRObjectAllocRun类的签名吗?此类用于分配工具.
Does anyone know the signature of Apples XRObjectAllocRun class? This class is used for the Allocations instrument.
任何帮助都会很棒!
更新
我玩过 Swift 并翻译了整个*.trace -reader-它失败并出现完全相同的错误:
I played around with Swift and translated the entire *.trace-reader - it fails with exactly the same error(s):
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
我已经在此处上传了其他类的签名您需要它们.
I've uploaded signatures of other classes here if you need them.
您无需在Swift中声明必需的类,而只需将头文件从归档文件导入桥接头文件即可.
Instead of declaring required classes in Swift, you can simply import headers from the archive to the bridging header.
这篇关于如何读取Xcode 6.1 Instruments .trace文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!