如何读取 Xcode 6.1 Instruments .trace 文件?
How to read a Xcode 6.1 Instruments .trace file?
我一直在尝试读取 .trace
文件,该文件是我使用 custom 工具模板生成的(工具:Automator, Allocations, Leaks) 使用 Instruments.
我在这个 Whosebug answer. Basically the author created a custom Objective-C program(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'
-错误。
最初很容易找出这个错误。我所要做的就是实现缺失的 class XRObjectAllocRun
;平行于 XRRun
或 XRVideoCardRun
class 中的示例 XRRun.m.
这是我的进展和卡住的地方:
#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
class。但无论我解码多少对象或小对象,我总是会收到以下异常: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 class 的签名吗?此 class 用于 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)")
这里是XRObjectAllocRun
class
的签名
#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
如果您需要,我已经上传了其他 classes here 的签名。
无需在 Swift 中声明必需的 classes,您只需将 headers 从存档导入桥接 header.
我成功了。 Here 是 git 项目。
我一直在尝试读取 .trace
文件,该文件是我使用 custom 工具模板生成的(工具:Automator, Allocations, Leaks) 使用 Instruments.
我在这个 Whosebug answer. Basically the author created a custom Objective-C program(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'
-错误。
最初很容易找出这个错误。我所要做的就是实现缺失的 class XRObjectAllocRun
;平行于 XRRun
或 XRVideoCardRun
class 中的示例 XRRun.m.
这是我的进展和卡住的地方:
#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
class。但无论我解码多少对象或小对象,我总是会收到以下异常: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 class 的签名吗?此 class 用于 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)")
这里是XRObjectAllocRun
class
#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
如果您需要,我已经上传了其他 classes here 的签名。
无需在 Swift 中声明必需的 classes,您只需将 headers 从存档导入桥接 header.
我成功了。 Here 是 git 项目。