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

3
我一直在尝试阅读一个.trace文件,这个文件是我使用一个自定义工具模板(instruments: Automator, Allocations, Leaks)生成的,使用了Instruments。在这个stackoverflow answer中,我找到了最好的帮助。基本上,author创建了一个自定义的Objective-C程序(Traced),用于读取特定类型的苹果.trace文件(工具:OpenGL ES Driver)。他的答案面向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:对象0x100112750的写入和读取数据不一致'
如果取消注释最后两个decode语句,程序将崩溃并显示此异常:uncaught exception 'NSArchiverArchiveInconsistency',reason: '***文件不一致:读取'i',期望'@''
有人知道苹果的XRObjectAllocRun类的签名吗?此类用于“分配”仪器。
任何帮助都将非常感激!
更新
我尝试了Swift并翻译了整个*.trace阅读器——它以完全相同的错误失败:
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)")

请尝试查看以下链接:https://github.com/JustSid/Traced 和 https://dev59.com/p2Qn5IYBdhLWcg3wj3zz 希望这能帮到你! - weso
谢谢,但这就是我开始的地方。我正在使用代码示例并描述如何进行适应。不幸的是,我无法像JustSid那样找出签名。 - user2210287
@MarcoPashkov,你有没有想过如何解析分配跟踪?我也遇到了同样的异常问题。 - Ricardo B.
很遗憾,还没有。我在 swift 上取得了一些进展,但还没有达到目标。一旦我弄清楚了,我会发布答案。另外,由于我没有全职处理这个问题,我不能保证很快解决它。 - user2210287
2个回答

0
这是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中,你可以通过从归档中导入头文件到桥接头文件来代替声明所需的类。


初步看起来很不错 - 我会在周末深入研究! - user2210287
你在哪里找到这些头文件的? - user2210287
1
@MarcoPashkov 我使用了class-dump从二进制文件中提取它们。 - bzz
@MarcoPashkov,你能够解析跟踪文件中的分配数据吗?如果可以的话,能否给我们更新一下?谢谢! - Ricardo B.
非常抱歉,但我不得不调整方向并放弃这个项目。但这似乎应该是可行的,因为API可以通过@bzz建议的工具进行反向工程。如果您包含生成的文件,则应能够解压缩数据并读取跟踪信息。 - user2210287

0

我让它工作了。这里是Git项目。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接