GithubHelp home page GithubHelp logo

mattgallagher / cwlpreconditiontesting Goto Github PK

View Code? Open in Web Editor NEW
174.0 9.0 45.0 258 KB

A Mach exception handler that allows Swift precondition failures to be caught and tested.

License: ISC License

Objective-C 23.31% Swift 41.63% C 30.77% Ruby 4.30%

cwlpreconditiontesting's Introduction

CwlPreconditionTesting

A Mach exception handler, written in Swift and Objective-C, that allows EXC_BAD_INSTRUCTION (as raised by Swift's assertionFailure/preconditionFailure/fatalError) to be caught and tested.

NOTE: the iOS code runs in the simulator only. It is for logic testing and cannot be deployed to the device due to the Mach exception API being private on iOS.

For an extended discussion of this code, please see the Cocoa with Love article:

Partial functions in Swift, Part 2: Catching precondition failures

Requirements

From version 2.0.0-beta.1, building CwlPreconditionTesting requires Swift 5 or newer and the Swift Package Manager, or CocoaPods.

For use with older versions of Swift or other package managers, use version 1.2.0 or older.

Adding to your project

Swift Package Manager

Add the following to the dependencies array in your "Package.swift" file:

 .package(url: "https://github.com/mattgallagher/CwlPreconditionTesting.git", from: Version("2.0.0"))

Or by adding https://github.com/mattgallagher/CwlPreconditionTesting.git, version 2.0.0 or later, to the list of Swift packages for any project in Xcode.

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate CwlPreconditionTesting into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'CwlPreconditionTesting', '~> 2.0'

Usage

On macOS and iOS you can use the regular version:

import CwlPreconditionTesting

let e = catchBadInstruction {
	precondition(false, "THIS PRECONDITION FAILURE IS EXPECTED")
}

on tvOS, Linux and other platforms, you can use the POSIX version:

import CwlPosixPreconditionTesting

let e = catchBadInstruction {
	precondition(false, "THIS PRECONDITION FAILURE IS EXPECTED")
}

Warning: this POSIX version can't be used when lldb is attached since lldb's Mach exception handler blocks the SIGILL from ever occurring. You should disable the "Debug Executable" setting for the tests in Xcode. The POSIX version of the signal handler is also whole process (rather than correctly scoped to the thread where the "catch" occurs).

Thanks

Includes contributions from @abbeycode, @dnkoutso, @jeffh and @ikesyo. Extra thanks to @saagarjha for help with the ARM64 additions.

cwlpreconditiontesting's People

Contributors

aaron-foreflight avatar abbeycode avatar dnkoutso avatar ikesyo avatar jeffh avatar lowammo avatar mattgallagher avatar mseijas avatar saagarjha avatar skumor-foreflight avatar stonko1994 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cwlpreconditiontesting's Issues

Doesn't build with iOS 13.1 SDK

Seems to have a problem compiling with the iOS 13.1 SDK in place.

public let x86_THREAD_STATE64_COUNT = UInt32(MemoryLayout<x86_thread_state64_t>.size / MemoryLayout<Int32>.size)
                                                          ^~~~~~~~~~~~~~~~~~~~
/Users/woolie/Library/Developer/Xcode/DerivedData/Crushroom-gcriwdpohkxdulcyaqptkqvtrnch/SourcePackages/checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlBadInstructionException.swift:63:47: error: use of unresolved identifier 'x86_thread_state64_t'
                var state = old_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { return $0.pointee }
                                                            ^~~~~~~~~~~~~~~~~~~~
/Users/woolie/Library/Developer/Xcode/DerivedData/Crushroom-gcriwdpohkxdulcyaqptkqvtrnch/SourcePackages/checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlBadInstructionException.swift:82:35: error: use of unresolved identifier 'x86_thread_state64_t'
                new_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { $0.pointee = state }

Runtime crash occurs on Xcode 10 beta 1

Test Case '-[NimbleTests.ThrowAssertionTest testNegativeMessage]' started.
Fatal error: : file /Users/ikesyo/.ghq/github.com/Quick/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift, line 46
2018-06-06 17:27:05.902357-0700 xctest[79915:24107707] Fatal error: : file /Users/ikesyo/.ghq/github.com/Quick/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift, line 46
0    Nimble                             0x0000000103ef01c0 catchReturnTypeConverter<A>(_:block:) + 306
1    Nimble                             0x0000000103ef03b0 static NSException.catchException(in:) + 58
2    Nimble                             0x0000000103ec4ef0 closure #4 in catchBadInstruction(in:) + 172
3    Nimble                             0x0000000103ec5030 partial apply for closure #4 in catchBadInstruction(in:) + 35
4    Nimble                             0x0000000103ec5070 thunk for @callee_guaranteed (@unowned UnsafeMutablePointer<MachContext>) -> (@error @owned Error) + 22
5    Nimble                             0x0000000103ec50f0 partial apply for thunk for @callee_guaranteed (@unowned UnsafeMutablePointer<MachContext>) -> (@error @owned Error) + 27
6    libswiftCore.dylib                 0x0000000107337530 withUnsafePointer<A, B>(to:_:) + 12
7    libswiftCore.dylib                 0x00000001074f7ed0 withUnsafeMutablePointer<A, B>(to:_:) + 9
8    Nimble                             0x0000000103ec4170 catchBadInstruction(in:) + 954
9    Nimble                             0x0000000103ef04c0 closure #1 in throwAssertion() + 324
10   Nimble                             0x0000000103efed30 closure #1 in static Predicate.fromDeprecatedClosure(_:) + 120
11   Nimble                             0x0000000103effc60 partial apply for closure #1 in static Predicate.fromDeprecatedClosure(_:) + 38
12   Nimble                             0x0000000103efd8c0 Predicate.satisfies(_:) + 90
13   Nimble                             0x0000000103e7da40 run #1 <A>() in execute<A>(_:_:_:to:description:captureExceptions:) + 520
14   Nimble                             0x0000000103e7e640 closure #2 in execute<A>(_:_:_:to:description:captureExceptions:) + 152
15   Nimble                             0x0000000103e7e850 partial apply for closure #2 in execute<A>(_:_:_:to:description:captureExceptions:) + 83
16   Nimble                             0x0000000103e7e8b0 thunk for @escaping @callee_guaranteed () -> () + 45
17   Nimble                             0x0000000103e6c520 -[NMBExceptionCapture tryBlock:] + 56
18   Nimble                             0x0000000103e7d530 execute<A>(_:_:_:to:description:captureExceptions:) + 876
19   Nimble                             0x0000000103e7f290 Expectation.toNot(_:description:) + 300
20   NimbleTests                        0x0000000103c85420 closure #1 in ThrowAssertionTest.testNegativeMessage() + 358
21   Nimble                             0x0000000103ea1f70 closure #2 in withAssertionHandler(_:closure:) + 34
22   Nimble                             0x0000000103ea2010 partial apply for closure #2 in withAssertionHandler(_:closure:) + 17
23   Nimble                             0x0000000103e7e8b0 thunk for @escaping @callee_guaranteed () -> () + 45
24   Nimble                             0x0000000103e6c520 -[NMBExceptionCapture tryBlock:] + 56
25   Nimble                             0x0000000103ea1b60 withAssertionHandler(_:closure:) + 612
26   NimbleTests                        0x0000000103c1d020 failsWithErrorMessage(_:file:line:preferOriginalSourceLocation:closure:) + 376
27   NimbleTests                        0x0000000103c1eaf0 failsWithErrorMessage(_:file:line:preferOriginalSourceLocation:closure:) + 291
28   NimbleTests                        0x0000000103c85370 ThrowAssertionTest.testNegativeMessage() + 138
29   NimbleTests                        0x0000000103c85650 @objc ThrowAssertionTest.testNegativeMessage() + 36
30   CoreFoundation                     0x00007fff39778bb0 __invoking___ + 140
31   CoreFoundation                     0x00007fff397789d0 -[NSInvocation invoke] + 320
32   XCTest                             0x00000001003761c7 __24-[XCTestCase invokeTest]_block_invoke_2.195 + 65
33   XCTest                             0x00000001003e5008 -[XCTMemoryChecker _assertInvalidObjectsDeallocatedAfterScope:] + 51
34   XCTest                             0x000000010037f11a -[XCTestCase assertInvalidObjectsDeallocatedAfterScope:] + 116
35   XCTest                             0x00000001003760c8 __24-[XCTestCase invokeTest]_block_invoke.189 + 207
36   XCTest                             0x00000001003d4466 +[XCTestCase(Failures) performFailableBlock:shouldInterruptTest:] + 36
37   XCTest                             0x00000001003d439e -[XCTestCase(Failures) _performTurningExceptionsIntoFailuresInterruptAfterHandling:block:] + 54
38   XCTest                             0x0000000100375a7c __24-[XCTestCase invokeTest]_block_invoke + 855
39   XCTest                             0x00000001003d931f -[XCUITestContext performInScope:] + 237
40   XCTest                             0x000000010037596c -[XCTestCase testContextPerformInScope:] + 87
41   XCTest                             0x00000001003759e6 -[XCTestCase invokeTest] + 137
42   XCTest                             0x0000000100377702 __26-[XCTestCase performTest:]_block_invoke_2 + 43
43   XCTest                             0x00000001003d4466 +[XCTestCase(Failures) performFailableBlock:shouldInterruptTest:] + 36
44   XCTest                             0x00000001003d439e -[XCTestCase(Failures) _performTurningExceptionsIntoFailuresInterruptAfterHandling:block:] + 54
45   XCTest                             0x00000001003775ec __26-[XCTestCase performTest:]_block_invoke.334 + 88
46   XCTest                             0x00000001003e1050 +[XCTContext runInContextForTestCase:block:] + 225
47   XCTest                             0x0000000100376ab1 -[XCTestCase performTest:] + 675
48   XCTest                             0x00000001003bb616 -[XCTest runTest] + 57
49   XCTest                             0x0000000100371ba3 __27-[XCTestSuite performTest:]_block_invoke + 365
50   XCTest                             0x00000001003714af -[XCTestSuite _performProtectedSectionForTest:testSection:] + 55
51   XCTest                             0x0000000100371683 -[XCTestSuite performTest:] + 296
52   XCTest                             0x00000001003bb616 -[XCTest runTest] + 57
53   XCTest                             0x0000000100371ba3 __27-[XCTestSuite performTest:]_block_invoke + 365
54   XCTest                             0x00000001003714af -[XCTestSuite _performProtectedSectionForTest:testSection:] + 55
55   XCTest                             0x0000000100371683 -[XCTestSuite performTest:] + 296
56   XCTest                             0x00000001003bb616 -[XCTest runTest] + 57
57   XCTest                             0x0000000100371ba3 __27-[XCTestSuite performTest:]_block_invoke + 365
58   XCTest                             0x00000001003714af -[XCTestSuite _performProtectedSectionForTest:testSection:] + 55
59   XCTest                             0x0000000100371683 -[XCTestSuite performTest:] + 296
60   XCTest                             0x00000001003bb616 -[XCTest runTest] + 57
61   XCTest                             0x00000001003f5a98 __44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke + 171
62   XCTest                             0x00000001003f5c20 __44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke.78 + 68
63   XCTest                             0x00000001003948f0 -[XCTestObservationCenter _observeTestExecutionForBlock:] + 600
64   XCTest                             0x00000001003f5637 -[XCTTestRunSession runTestsAndReturnError:] + 639
65   XCTest                             0x0000000100357226 -[XCTestDriver runTestsAndReturnError:] + 424
66   XCTest                             0x00000001003dd6bd _XCTestMain + 1493
67   xctest                             0x00000001000022b8 main + 266
68   libdyld.dylib                      0x00007fff61a95014 start + 1
closure argument passed as @noescape to Objective-C has escaped: file /Users/ikesyo/.ghq/github.com/Quick/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchException/CwlCatchException.swift, line 28, column 36 
2018-06-06 17:27:06.180223-0700 xctest[79915:24107707] closure argument passed as @noescape to Objective-C has escaped: file /Users/ikesyo/.ghq/github.com/Quick/Nimble/Carthage/Checkouts/CwlCatchException/Sources/CwlCatchException/CwlCatchException.swift, line 28, column 36

This is rdar://40857699 which is originally found in Quick/Nimble#530.

Build Warning With Xcode 14 - 'mach_port_destroy' was deprecated in iOS 15.0

Just a deprecation working.

Seeing it in CwlCatchBadInstruction, line 174 -

	defer {
		// 7. Cleanup the mach port
		mach_port_destroy(mach_task_self_, context.currentExceptionPort)
	}

The warning for Xcode -
"'mach_port_destroy' was deprecated in iOS 15.0: Inherently unsafe API: instead manage rights with mach_port_destruct(), mach_port_deallocate() or mach_port_mod_refs()"

Undefined symbols for architecture x86_64: "_catchExceptionOfKind"

Hi,

From time to time I'm facing the following issue when building the Tests target that uses catchBadInstruction { } from CwlPreconditionTesting.

import XCTest
import CwlPreconditionTesting
import CarPlay

final class Tests: XCTestCase {
    func testFiresFatalError {
        let catchedFatalError = catchBadInstruction { }

        XCTAssertNotNil(catchedFatalError)
    }
}

Xcode build log:

Undefined symbols for architecture x86_64:
  "_catchExceptionOfKind", referenced from:
      CwlCatchException.(catchReturnTypeConverter in _841BEC3F94220F0DFD4EA4E9DDB3DC93)<A where A: __C.NSException>(_: A.Type, block: () -> ()) -> A? in libCwlCatchException.a(CwlCatchException-b635c7ceaebf0fe95fbf8ddcf7fc6874546dd0ad373c125772be5cdf73ff33d0.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Environment:

  • Xcode 10.2.1
  • Swift 4.2

Used versions:

  • CwlCatchException (1.0.2)
  • CwlPreconditionTesting (1.1.1)

CwlPreconditionTesting.framework/Modules/module.modulemap:9:12: Header 'CwlPreconditionTesting-Swift.h' not found

I can't compile the project because of this error:
screen shot 2018-12-03 at 10 18 55
I noticed an issue when installing pods:
My podfile:
pod 'CwlPreconditionTesting', :git => 'https://github.com/mattgallagher/CwlPreconditionTesting.git' pod 'CwlCatchException', :git => 'https://github.com/mattgallagher/CwlCatchException.git'
The result of installation:
Installing CwlCatchException 1.0.2 Installing CwlPreconditionTesting 1.1.0

Both are no using the same version 1.1.0, it's the cause of the problem ?

Can't be built for real devices (iOS and tvOS)

fd66a0b the commit did break the builds for real iOS and tvOS devices whose arch is not x86_64. It should be possible to run a test suite on real devices (e.g. in AWS Device Farm or Firebase Test Lab) including this library with excluding the usages (gated with #if arch(x86_64)). Is it okay to re-add #if arch(x86_64) check?

Intermittent: undeclared identifier 'BadInstructionException'

Sometimes, but not all the time, this error comes up (use of undeclared identifier 'BadInstructionException'):

..../CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m:34:13: error: use of undeclared identifier 'BadInstructionException'
    return [BadInstructionException catch_mach_exception_raise_state:exception_port exception:exception code:code codeCnt:codeCnt flavor:flavor old_state:old_state old_stateCnt:old_stateCnt new_state:new_state new_stateCnt:new_stateCnt];
            ^
1 error generated.

The Nimble team and I are looking into what's going on.

Xcode 16 Build Warnings

Getting some build warnings when building CwlPreconditionTesting

 Pods/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlBadInstructionException.swift:35:14: warning: class 'BadInstructionException' must restate inherited '@unchecked Sendable' conformance
 public class BadInstructionException: NSException {
              ^

I can try to put together a Pull Request to fix this...but might be a few days.

Just trying to eliminate all build warnings - doesn't seem to currently cause any real issues when building with the current Xcode 16 Beta (Beta 5).

master branch unavailable

Just as title described , code on master branch can't pass building and branch swift2.3 can be used with swift 2.2 。

macOS 10.11.6 / Xcode 7.3 & 8.2 test ~

Apple Silicon under Rosetta

Looks like assertion is still raised if run on M1 under Rosetta. This could happen if target simulator is less then iOS 13.7 or by checking "Open with Rosetta" on Xcode app.

image showing EXC_BAD_INSTRUCTION

I have too little knowledge to try and fix it myself, is it even possible to address? It compiles sources with x86_64 architecture and I'm not sure how to differentiate Intel vs Apple Silicon

Maybe you have any suggestions where to start?
Thank you!

Unwind (upd'd)

Is there a way to unwind call to change some value? E.x. if I've got out of range err. then change idx to lower value or a skip this one and proceed with others?

Occasional crashes when running tests

Not entirely sure that this library is the cause, but it seems likely. Here's a partial crash log from one instance:

Process:               xctest [10244]
Path:                  /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Agents/xctest
Identifier:            xctest
Version:               13764
Code Type:             X86-64 (Native)
Parent Process:        launchd_sim [10207]
Responsible:           xctest [10244]
User ID:               501

Date/Time:             2018-03-26 10:35:53.690 +0200
OS Version:            Mac OS X 10.13.3 (17D47)
Report Version:        12
Bridge OS Version:     3.0 (14Y661)
Anonymous UUID:        1ADB661F-7E9B-F1CE-C84B-B4201B79CF67

Sleep/Wake UUID:       824E7AA5-8794-4169-800A-3FEC2F0BEF0D

Time Awake Since Boot: 920000 seconds
Time Since Wake:       7700 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x00007f7d4925e670
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

VM Regions Near 0x7f7d4925e670:
    Stack                  000070000bad5000-000070000bb57000 [  520K] rw-/rwx SM=COW  thread 3
-->
    MALLOC_TINY            00007f9d47400000-00007f9d47800000 [ 4096K] rw-/rwx SM=PRV

Application Specific Information:
CoreSimulator 494.33 - Device: iPhone 6 - Runtime: iOS 11.2 (15C107) - DeviceType: iPhone 6
Fatal error: cannot add connections when disposed: file /Users/petter/swift/Mobius.swift/MobiusCore/Sources/ConnectablePublisher.swift, line 43
Fatal error: cannot accept values when disposed: file /Users/petter/swift/Mobius.swift/MobiusCore/Sources/ConnectablePublisher.swift, line 34


Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_malloc.dylib              0x00000001141dd0ab tiny_malloc_from_free_list + 148
1   libsystem_malloc.dylib              0x00000001141cbf13 szone_malloc_should_clear + 384
2   libsystem_malloc.dylib              0x00000001141d1fa9 malloc_zone_malloc + 103
3   libsystem_malloc.dylib              0x00000001141d421d malloc + 24
4   libxpc.dylib                        0x0000000114325308 _xpc_malloc + 47
5   libxpc.dylib                        0x0000000114318dd9 _xpc_dictionary_insert + 345
6   libxpc.dylib                        0x00000001143195b6 xpc_dictionary_set_uuid + 41
7   libsystem_trace.dylib               0x00000001142ddce0 _os_activity_stream_entry_encode + 980
8   libsystem_trace.dylib               0x00000001142dd736 _os_activity_stream_reflect + 310
9   libsystem_trace.dylib               0x00000001142e9c8a _os_log_impl_stream + 301
10  libsystem_trace.dylib               0x00000001142e9226 _os_log_impl_flatten_and_send + 4596
11  libsystem_trace.dylib               0x00000001142ea528 _os_log_with_args_impl + 449
12  libsystem_asl.dylib                 0x0000000114012eed asl_log + 258
13  libswiftCore.dylib                  0x0000000122f13960 swift_reportError + 64
14  libswiftCore.dylib                  0x0000000122f54060 _swift_stdlib_reportFatalErrorInFile + 224
15  libswiftCore.dylib                  0x0000000122c1b9bc closure #1 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 284
16  libswiftCore.dylib                  0x0000000122ef0301 partial apply for closure #1 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 97
17  libswiftCore.dylib                  0x0000000122f07269 closure #1 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:)partial apply + 9
18  libswiftCore.dylib                  0x0000000122c1b1eb specialized StaticString.withUTF8Buffer<A>(_:) + 187
19  libswiftCore.dylib                  0x0000000122e573c4 specialized closure #1 in _assertionFailure(_:_:file:line:flags:) + 180
20  libswiftCore.dylib                  0x0000000122ea419f partial apply for closure #1 in _assertionFailure(_:_:file:line:flags:) + 127
21  libswiftCore.dylib                  0x0000000122c1b1eb specialized StaticString.withUTF8Buffer<A>(_:) + 187
22  libswiftCore.dylib                  0x0000000122dd7e70 specialized _assertionFailure(_:_:file:line:flags:) + 144
23  com.spotify.mobius.core             0x0000000122b8d00d MobiusController.connect<A>(_:) + 845
24  com.spotify.MobiusTests             0x000000011ff24e35 closure #1 in closure #1 in closure #2 in closure #2 in closure #1 in MobiusControllerTests.spec() + 405
25  com.spotify.MobiusTests             0x000000011ff2eb83 partial apply for closure #1 in closure #1 in closure #2 in closure #2 in closure #1 in MobiusControllerTests.spec() + 67
26  com.spotify.MobiusTests             0x000000011fefe48a thunk for @callee_owned () -> (@unowned ()?, @error @owned Error) + 26
27  com.spotify.MobiusTests             0x000000011ff2ec23 thunk for @callee_owned () -> (@unowned ()?, @error @owned Error)partial apply + 83
28  net.jeffhui.Nimble                  0x0000000122a3df98 closure #1 in memoizedClosure<A>(_:) + 280 (Expression.swift:9)
29  net.jeffhui.Nimble                  0x0000000122a3ec11 partial apply for closure #1 in memoizedClosure<A>(_:) + 97
30  net.jeffhui.Nimble                  0x0000000122a47fad specialized closure #1 in closure #1 in throwAssertion() + 61 (ThrowAssertion.swift:29)
31  net.jeffhui.Nimble                  0x0000000122a47f45 partial apply for closure #1 in closure #1 in throwAssertion() + 101
32  net.jeffhui.Nimble                  0x0000000122a319d0 thunk for @callee_owned () -> () + 32
33  net.jeffhui.Nimble                  0x00000001229d4651 catchExceptionOfKind + 31
34  net.jeffhui.Nimble                  0x0000000122a36986 specialized catchReturnTypeConverter<A>(_:block:) + 118 (CwlCatchException.swift:29)
35  net.jeffhui.Nimble                  0x0000000122a368ee static NSException.catchException(in:) + 30 (CwlCatchException.swift:33)
36  net.jeffhui.Nimble                  0x0000000122a1f12b specialized catchBadInstruction(in:) + 379 (CwlCatchBadInstruction.swift:185)
37  net.jeffhui.Nimble                  0x0000000122a47e5d specialized closure #1 in throwAssertion() + 285 (ThrowAssertion.swift:34)

and another thread:

Thread 3:
0   libsystem_kernel.dylib              0x00000001143d37c2 mach_msg_trap + 10
1   libsystem_kernel.dylib              0x00000001143d2cdc mach_msg + 60
2   net.jeffhui.Nimble                  0x0000000122a1ea92 machMessageHandler(_:) + 178 (CwlCatchBadInstruction.swift:102)
3   net.jeffhui.Nimble                  0x0000000122a1efa9 @objc machMessageHandler(_:) + 9
4   libsystem_pthread.dylib             0x00000001144136c1 _pthread_body + 340
5   libsystem_pthread.dylib             0x000000011441356d _pthread_start + 377
6   libsystem_pthread.dylib             0x0000000114412c5d thread_start + 13

It feels like malloc shouldn't be crashe-able from a pure Swift application like the one that's being tested. And there are two different threads running CwlCatchBadInstruction code - is it possible that there's a threading issue somewhere? The code being tested uses a custom concurrent DispatchQueue.

Preconditions under Task with Swift Concurrency is not handled

The sample package below reproduces the issue. If a precondition fails while running under Swift Concurrency it does not trap the signal which kills the process. The tests cover a couple of functions. One uses a closure and the other is done with async. The unit tests show how precondition is not caught when run as a Task.

Xcode 15 hangs indefinitely when an exception is catched

The unit tests that take advantage of the catchBadInstruction method run indefinitely using Xcode 15, making the IDE unresponsive (in some aspects* ). I am left having to force quit and try again.

In the example below, "Reached point 1" prints to the console, but not the second one.

        let keyDecoder = JSONDecoder.KeyDecodingStrategy.customKeyDecoder

        guard case .custom(let block) = keyDecoder else {
            XCTFail("customKeyDecoder should be custom")
            return
        }

        let result = catchBadInstruction {
           print("Reached point 1")
            _ = block([])
           print("Reached point 2")
       }

The expectation is for result to hold the exception thrown.

  • Xcode as a software still runs fine, in the sense that it's not "beach balling". I can click on "Stop" button to interrupt unit tests, but nothing happens. No buttons have an effect until I restart.

Darwin.framework in Xcode 11.4 is missing symbols

Building a test project with Nimble and CwlPreconditionTesting on Xcode 11.4 (iOS 13 target) generates some new errors due to missing symbols:

public let x86_THREAD_STATE64_COUNT = UInt32(MemoryLayout<x86_thread_state64_t>.size / MemoryLayout<Int32>.size)
                                                          ^~~~~~~~~~~~~~~~~~~~
/Users/steve/Library/Developer/Xcode/DerivedData/.../SourcePackages/checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlBadInstructionException.swift:63:47: error: use of unresolved identifier 'x86_thread_state64_t'
                var state = old_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { return $0.pointee }
                                                            ^~~~~~~~~~~~~~~~~~~~
/Users/steve/Library/Developer/Xcode/DerivedData/.../SourcePackages/checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlBadInstructionException.swift:82:35: error: use of unresolved identifier 'x86_thread_state64_t'
                new_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { $0.pointee = state }
                                                ^~~~~~~~~~~~~~~~~~~~
/Users/steve/Library/Developer/Xcode/DerivedData/.../SourcePackages/checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlCatchBadInstruction.swift:185:166: error: use of unresolved identifier 'x86_THREAD_STATE64'
                        thread_swap_exception_ports(mach_thread_self(), EXC_MASK_BAD_INSTRUCTION, currentExceptionPtr, Int32(bitPattern: UInt32(EXCEPTION_STATE) | MACH_EXCEPTION_CODES), x86_THREAD_STATE64, masksPtr, countPtr, portsPtr, behaviorsPtr, flavorsPtr)
                                                                                                                                                                                          ^~~~~~~~~~~~~~~~~~
/Users/steve/Library/Developer/Xcode/DerivedData/.../SourcePackages/checkouts/CwlPreconditionTesting/Sources/CwlPreconditionTesting/CwlDarwinDefinitions.swift:44:59: error: use of undeclared type 'x86_thread_state64_t'
public let x86_THREAD_STATE64_COUNT = UInt32(MemoryLayout<x86_thread_state64_t>.size / MemoryLayout<Int32>.size)
                                                          ^~~~~~~~~~~~~~~~~~~~

Add the assertion message to returned exception

Is there a way to retrieve the message from the assertion failure, in order to validate it? I can't see it on the returned NSException. It would be great if it were available in the exception's userInfo or reason property.

Under Xcode 9.3 catchBadInstruction no longer handles FatalError()

You've probably heard this, but I thought I'd log it anyway. Under Xcode 9.3, catchBadInstruction() is no longer catching Swift FatalError()s. This is effecting any tests which are attempting to deal with code that executes this command and frameworks which support catching fatals (Nimble's throwAssertion()).

The only known workaround is to turn off debugging the executable, however this kills debugging tests and is also the default setting.

So I'm hoping you can find some magic to work around the problem. I've included a simple test project which shows the problem. Just run the single unit test in Xcode 9.3 and you'll see the debugger halt on the FatalError() instead of returning to the unit test.

test.zip

Return of the intermittent "undeclared identifier 'BadInstructionException'" error

Hi!

When my iOS app builds Nimble as part of our test suite, it often fails out with this error:

/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift:48:16: error: use of unresolved identifier 'bad_instruction_exception_reply_t'
                        var reply = bad_instruction_exception_reply_t(exception_port: 0, exception: 0, code: nil, codeCnt: 0, flavor: nil, old_state: nil, old_stateCnt: 0, new_state: nil, new_stateCnt: nil)
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I'd say this happens 15-20% of the time on our Jenkins box, and a bit less frequently (but still non-zero) locally.

#5 and #6 suggest this was a known issue, but also that it's theoretically been fixed. Is this known to still be an issue? Is there a workaround that simply needs better documentation/visibility?

(I'm not sure whether this should be opened here or in Nimble, and am opening issues in both places. My apologies if this is the wrong place, and feel free to delete/close as appropriate!)

Add tvOS support

I'm working on adding assertion validation to Nimble, which supports tvOS. I'm getting errors for that target, though, so I figured I'd try adding a tvOS framework to this library directly and flush out the issues. I'll be pushing a branch with the tvOS targets shortly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.