mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-09 22:36:01 +05:45
177 lines
6.1 KiB
Objective-C
177 lines
6.1 KiB
Objective-C
// Copyright 2019 Google
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "Crashlytics/Crashlytics/Unwind/Compact/FIRCLSCompactUnwind.h"
|
|
|
|
#import <Foundation/Foundation.h>
|
|
#import <XCTest/XCTest.h>
|
|
|
|
#import "Crashlytics/Shared/FIRCLSMachO/FIRCLSMachO.h"
|
|
|
|
#include "Crashlytics/Crashlytics/Components/FIRCLSContext.h"
|
|
#include "Crashlytics/Crashlytics/Components/FIRCLSGlobals.h"
|
|
#include "Crashlytics/Crashlytics/Unwind/Compact/FIRCLSCompactUnwind_Private.h"
|
|
#include "Crashlytics/Crashlytics/Unwind/FIRCLSUnwind_x86.h"
|
|
|
|
@interface FIRCLSCompactUnwindTests : XCTestCase
|
|
|
|
@end
|
|
|
|
@implementation FIRCLSCompactUnwindTests
|
|
|
|
- (void)setUp {
|
|
[super setUp];
|
|
|
|
_firclsContext.readonly = malloc(sizeof(FIRCLSReadOnlyContext));
|
|
_firclsContext.readonly->logPath = "/tmp/test.log";
|
|
}
|
|
|
|
- (void)tearDown {
|
|
[super tearDown];
|
|
}
|
|
|
|
- (NSString*)resourcePath {
|
|
return [[NSBundle bundleForClass:[self class]] resourcePath];
|
|
}
|
|
|
|
- (NSString*)pathForResource:(NSString*)name {
|
|
return [[self resourcePath] stringByAppendingPathComponent:name];
|
|
}
|
|
|
|
#if CLS_COMPACT_UNWINDING_SUPPORTED
|
|
|
|
#if !TARGET_OS_IPHONE
|
|
- (void)testParseCompactUnwindInfoForthread_get_state_10_9_4 {
|
|
NSString* dylibPath = [self pathForResource:@"10.9.4_libsystem_kernel.dylib"];
|
|
|
|
struct FIRCLSMachOFile file;
|
|
|
|
XCTAssertTrue(FIRCLSMachOFileInitWithPath(&file, [dylibPath fileSystemRepresentation]), @"");
|
|
|
|
struct FIRCLSMachOSlice slice = FIRCLSMachOFileSliceWithArchitectureName(&file, "x86_64");
|
|
|
|
const void* compactUnwind = NULL;
|
|
const void* ehFrame = NULL;
|
|
|
|
XCTAssert(FIRCLSMachOSliceGetSectionByName(&slice, SEG_TEXT, "__eh_frame", &ehFrame));
|
|
XCTAssert(FIRCLSMachOSliceGetSectionByName(&slice, SEG_TEXT, "__unwind_info", &compactUnwind));
|
|
|
|
XCTAssertTrue(ehFrame != NULL, @"");
|
|
XCTAssertTrue(compactUnwind != NULL, @"");
|
|
|
|
FIRCLSCompactUnwindContext context;
|
|
|
|
// hard-code a load address seen during testing
|
|
uintptr_t loadAddress = 0x7fff94044000;
|
|
XCTAssertTrue(FIRCLSCompactUnwindInit(&context, compactUnwind, ehFrame, loadAddress), @"");
|
|
|
|
FIRCLSCompactUnwindResult result;
|
|
|
|
XCTAssertTrue(FIRCLSCompactUnwindLookup(&context, 0x7fff94051e6c, &result), @"");
|
|
XCTAssertEqual(result.encoding & UNWIND_X86_64_MODE_MASK, UNWIND_X86_64_MODE_RBP_FRAME, @"");
|
|
XCTAssertEqual(result.functionStart, loadAddress + 0x0000DCC1, @"");
|
|
}
|
|
|
|
- (void)testParseCompactUnwindInfoForFunctionInLastIndexEntry {
|
|
NSString* dylibPath = [self pathForResource:@"10.9.4_libsystem_kernel.dylib"];
|
|
|
|
struct FIRCLSMachOFile file;
|
|
|
|
XCTAssertTrue(FIRCLSMachOFileInitWithPath(&file, [dylibPath fileSystemRepresentation]), @"");
|
|
|
|
struct FIRCLSMachOSlice slice = FIRCLSMachOFileSliceWithArchitectureName(&file, "x86_64");
|
|
|
|
const void* compactUnwind = NULL;
|
|
const void* ehFrame = NULL;
|
|
|
|
XCTAssert(FIRCLSMachOSliceGetSectionByName(&slice, SEG_TEXT, "__eh_frame", &ehFrame));
|
|
XCTAssert(FIRCLSMachOSliceGetSectionByName(&slice, SEG_TEXT, "__unwind_info", &compactUnwind));
|
|
|
|
XCTAssertTrue(ehFrame != NULL, @"");
|
|
XCTAssertTrue(compactUnwind != NULL, @"");
|
|
|
|
FIRCLSCompactUnwindContext context;
|
|
|
|
// hard-code a load address seen during testing
|
|
uintptr_t loadAddress = 0x7fff94044000;
|
|
XCTAssertTrue(FIRCLSCompactUnwindInit(&context, compactUnwind, ehFrame, loadAddress), @"");
|
|
|
|
FIRCLSCompactUnwindResult result;
|
|
|
|
// there should be no entry here (0x00016FDE maps to the last index entry, 0x00016FDF)
|
|
XCTAssertFalse(FIRCLSCompactUnwindLookup(&context, loadAddress + 0x00016FDE, &result), @"");
|
|
}
|
|
|
|
- (void)testParseCompactUnwindInfoForBoundaryBetween2ndLevelEntries {
|
|
NSString* dylibPath = [self pathForResource:@"10.9.4_libsystem_kernel.dylib"];
|
|
|
|
struct FIRCLSMachOFile file;
|
|
|
|
XCTAssertTrue(FIRCLSMachOFileInitWithPath(&file, [dylibPath fileSystemRepresentation]), @"");
|
|
|
|
struct FIRCLSMachOSlice slice = FIRCLSMachOFileSliceWithArchitectureName(&file, "x86_64");
|
|
|
|
const void* compactUnwind = NULL;
|
|
const void* ehFrame = NULL;
|
|
|
|
XCTAssert(FIRCLSMachOSliceGetSectionByName(&slice, SEG_TEXT, "__eh_frame", &ehFrame));
|
|
XCTAssert(FIRCLSMachOSliceGetSectionByName(&slice, SEG_TEXT, "__unwind_info", &compactUnwind));
|
|
|
|
XCTAssertTrue(ehFrame != NULL, @"");
|
|
XCTAssertTrue(compactUnwind != NULL, @"");
|
|
|
|
FIRCLSCompactUnwindContext context;
|
|
|
|
// hard-code a load address seen during testing
|
|
uintptr_t loadAddress = 0x7fff94044000;
|
|
XCTAssertTrue(FIRCLSCompactUnwindInit(&context, compactUnwind, ehFrame, loadAddress), @"");
|
|
|
|
FIRCLSCompactUnwindResult result;
|
|
|
|
// funcOffset=0x0000151A _reallocf
|
|
// funcOffset=0x00001558 __pthread_exit_if_canceled
|
|
|
|
// make sure we hit the last byte of _reallocf
|
|
XCTAssertTrue(FIRCLSCompactUnwindLookup(&context, loadAddress + 0x00001557, &result), @"");
|
|
XCTAssertEqual(result.encoding & UNWIND_X86_64_MODE_MASK, UNWIND_X86_64_MODE_RBP_FRAME, @"");
|
|
XCTAssertEqual(result.functionStart, loadAddress + 0x0000151A, @"");
|
|
XCTAssertEqual(result.functionEnd, loadAddress + 0x00001558, @"");
|
|
|
|
// and check the very next value, which should be in __pthread_exit_if_canceled
|
|
XCTAssertTrue(FIRCLSCompactUnwindLookup(&context, loadAddress + 0x00001558, &result), @"");
|
|
XCTAssertEqual(result.encoding & UNWIND_X86_64_MODE_MASK, UNWIND_X86_64_MODE_DWARF, @"");
|
|
XCTAssertEqual(result.functionStart, loadAddress + 0x00001558, @"");
|
|
}
|
|
#endif
|
|
|
|
#if CLS_CPU_X86_64
|
|
- (void)testComputeDirectStackSize {
|
|
const compact_unwind_encoding_t encoding = 0x20a1860;
|
|
const intptr_t functionStart = 0x0;
|
|
|
|
uint32_t stackSize = 0;
|
|
XCTAssertTrue(FIRCLSCompactUnwindComputeStackSize(encoding, functionStart, false, &stackSize),
|
|
@"");
|
|
|
|
// 0x20a1860 & 0x00FF0000 = 0xA0000
|
|
// 0x270000 >> 16 = 0xA
|
|
// 0xA * 8 = 0x50
|
|
XCTAssertEqual(stackSize, 0x50, @"");
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
@end
|