| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- // 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
|