-
-
Notifications
You must be signed in to change notification settings - Fork 594
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #472 from Quick/update-CwlPreconditionTesting
Update CwlPreconditionTesting
- Loading branch information
Showing
29 changed files
with
385 additions
and
311 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ included: | |
- Tests | ||
|
||
excluded: | ||
- Sources/Lib | ||
- Carthage/Checkouts | ||
|
||
trailing_comma: | ||
mandatory_comma: true | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
github "mattgallagher/CwlPreconditionTesting" "1.1.0-beta.12" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
github "mattgallagher/CwlCatchException" "b14c111e9b33cd142bd4bc75c482cfd5c3490923" | ||
github "mattgallagher/CwlPreconditionTesting" "1.1.0-beta.12" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Copyright © 2017 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted, provided that the above | ||
copyright notice and this permission notice appear in all copies. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR | ||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "CwlCatchException", | ||
targets: [ | ||
Target(name: "CwlCatchException", dependencies: ["CwlCatchExceptionSupport"]), | ||
Target(name: "CwlCatchExceptionSupport") | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# CwlCatchException | ||
A simple Swift wrapper around an Objective-C `@try`/`@catch` statement that selectively catches Objective-C exceptions by `NSException` subtype, rethrowing if any caught exception is not the expected subtype. | ||
|
||
Look at [CwlCatchExceptionTests.swift](https://github.com/mattgallagher/CwlCatchException/blob/master/CwlCatchExceptionTests/CwlCatchExceptionTests.swift?ts=4) for syntax. | ||
|
||
## Adding to your project | ||
|
||
This project can be used by direct inclusion in your projects or through any of the Swift Package Manager, CocoaPods or Carthage. | ||
|
||
Minimum requirements are iOS 8 or macOS 10.9. | ||
|
||
### Manual inclusion | ||
|
||
1. In a subdirectory of your project's directory, run `git clone https://github.com/mattgallagher/CwlCatchException.git` | ||
2. Drag the "CwlCatchException.xcodeproj" file from the Finder into your own project's file tree in Xcode | ||
3. Add the "CwlCatchException.framework" from the "Products" folder of the CwlCatchException project's file tree to the "Copy Files (Frameworks)" build phases of any target that you want to include this module. | ||
|
||
That third step is a little tricky if you're unfamiliar with Xcode but it involves: | ||
|
||
a. click on your project in the file tree | ||
b. click on the target to whih you want to add this module | ||
c. select the "Build Phases" tab | ||
d. if you don't already have a "Copy File" build phase with a "Destination: Frameworks", add one using the "+" button in the top left of the tab | ||
e. click the "+" within the "Copy File (Frameworks)" phase and from the list that appears, select the "CwlCatchException.framework" (if there are multiple frameworks with the same name, look for the one that appears *above* the corresponding macOS or iOS CwlCatchException testing target). | ||
|
||
### Swift Package Manager | ||
|
||
Add the following to the `dependencies` array in your "Package.swift" file: | ||
|
||
.Package(url: "https://github.com/mattgallagher/CwlCatchException.git", majorVersion: 1), | ||
|
||
Or, if you're using the `swift-tools-version:4.0` package manager, add the following to the `dependencies` array in your "Package.swift" file: | ||
|
||
.package(url: "https://github.com/mattgallagher/CwlCatchException.git", majorVersion: 1) | ||
|
||
### CocoaPods | ||
|
||
Add the following to your target in your "Podfile": | ||
|
||
pod 'CwlCatchException', :git => 'https://github.com/mattgallagher/CwlCatchException.git' | ||
|
||
### Carthage | ||
|
||
Add the following line to your Cartfile: | ||
|
||
git "https://github.com/mattgallagher/CwlCatchException.git" "master" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Copyright © 2017 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted, provided that the above | ||
copyright notice and this permission notice appear in all copies. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR | ||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "CwlPreconditionTesting", | ||
targets: [ | ||
Target(name: "CwlPreconditionTesting", dependencies: [ | ||
"CwlMachBadInstructionHandler" | ||
]), | ||
Target(name: "CwlMachBadInstructionHandler") | ||
], | ||
dependencies: [ | ||
.Package(url: "https://github.com/mattgallagher/CwlCatchException.git", Version(1, 0, 2, prereleaseIdentifiers: ["beta", "3"])), | ||
], | ||
exclude: [ | ||
"Sources/CwlPreconditionTesting/Mach/CwlPreconditionTesting.h", | ||
"Sources/CwlPreconditionTesting/Posix/CwlPreconditionTesting.h", | ||
"Sources/CwlPreconditionTesting/CwlCatchBadInstructionPosix.swift", | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# 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](http://cocoawithlove.com/blog/2016/02/02/partial-functions-part-two-catching-precondition-failures.html) | ||
|
||
## Adding to your project | ||
|
||
This project can be used by manual inclusion in your projects or through any of the Swift Package Manager, CocoaPods or Carthage. | ||
|
||
Minimum requirements are iOS 8 (simulator-only) or macOS 10.9. The project includes tvOS 9 and POSIX targets but these aren't regularly tested. | ||
|
||
### Manual inclusion | ||
|
||
1. In a subdirectory of your project's directory, run `git clone https://github.com/mattgallagher/CwlPreconditionTesting.git` | ||
2. Drag the "CwlPreconditionTesting.xcodeproj" file from the Finder into your own project's file tree in Xcode | ||
3. Add the "CwlPreconditionTesting.framework" from the "Products" folder of the CwlPreconditionTesting project's file tree to the "Copy Files (Frameworks)" build phases of any target that you want to include this module. | ||
4. Drag the "CwlCatchException.framework" from the "Dependencies" group (within the CwlPreconditionTesting project's file tree) onto the same "Copy Files (Frameworks)" build phase (this item may be red but that shouldn't be a problem). | ||
|
||
That third step is a little tricky if you're unfamiliar with Xcode but it involves: | ||
|
||
a. click on your project in the file tree | ||
b. click on the target to whih you want to add this module | ||
c. select the "Build Phases" tab | ||
d. if you don't already have a "Copy File" build phase with a "Destination: Frameworks", add one using the "+" button in the top left of the tab | ||
e. click the "+" within the "Copy File (Frameworks)" phase and from the list that appears, select the "CwlPreconditionTesting.framework" (if there are multiple frameworks with the same name, look for the one that appears *above* the corresponding macOS or iOS CwlPreconditionTesting testing target). | ||
|
||
When building using this approach, the "FetchDependencies" target will use the Swift Package Manager to download the "CwlCatchException" project from github. The download is stored in the "Build intermediates" directory for your project. Normally, you can ignore its existence but if you get any errors from the "FetchDependencies" target, you might need to clean the build folder (Hold "Option" key while selecting "Product" → "Clean Build Folder..." from the Xcode menubar). | ||
|
||
You can use the "Package.swift" to manage the behavior of the Swift Package Manager or if you want to download dependencies manually (instead of using this behind-the-scenes use of the Swift package manager), you should delete the "FetchDependencies" target and replace the "CwlCatchException" targets with alternatives that build the dependencies in accordance with your manual download. | ||
|
||
### Swift Package Manager | ||
|
||
Add the following to the `dependencies` array in your "Package.swift" file: | ||
|
||
.Package(url: "https://github.com/mattgallagher/CwlPreconditionTesting.git", majorVersion: 1), | ||
|
||
Or, if you're using the `swift-tools-version:4.0` package manager, add the following to the `dependencies` array in your "Package.swift" file: | ||
|
||
.package(url: "https://github.com/mattgallagher/CwlPreconditionTesting.git", majorVersion: 1) | ||
|
||
### CocoaPods | ||
|
||
Add the following lines to your target in your "Podfile": | ||
|
||
pod 'CwlPreconditionTesting', :git => 'https://github.com/mattgallagher/CwlPreconditionTesting.git' | ||
pod 'CwlCatchException', :git => 'https://github.com/mattgallagher/CwlCatchException.git' | ||
|
||
### Carthage | ||
|
||
Add the following line to your Cartfile: | ||
|
||
git "https://github.com/mattgallagher/CwlPreconditionTesting.git" "master" | ||
|
||
## Using POSIX signals and setjmp/longjmp | ||
|
||
For comparison or for anyone running this code on a platform without Mach exceptions or the Objective-C runtime, I've added a proof-of-concept implementation of `catchBadInstruction` that uses a POSIX SIGILL `sigaction` and `setjmp`/`longjmp` to perform the throw. | ||
|
||
In Xcode, you can simply select the CwlPreconditionTesting_POSIX target (instead of the OSX or iOS targets). If you're building without Xcode: all you need is the CwlCatchBadInstructionPOSIX.swift file (compared to the Mach exception handler, the code is tiny doesn't have any weird Objective-C/MiG file dependencies). | ||
|
||
**Warning No. 1**: on OS X, this approach can't be used when lldb is attached since lldb's Mach exception handler blocks the SIGILL from ever occurring (I've disabled the "Debug Executable" setting for the tests in Xcode - re-enable it to witness the problem). | ||
|
||
**Warning No. 2**: if you're switching between the CwlPreconditionTesting_OSX and CwlPreconditionTesting_POSIX targets, Xcode (as of Xcode 7.2.1) will not detect the change and will not remove the old framework correctly so you'll need to *clean your project* otherwise the old framework will hang around. | ||
|
||
Additional problems in decreasing severity include: | ||
|
||
* the signal handler is whole process (rather than correctly scoped to the thread where the "catch" occurs) | ||
* the signal handler doesn't deal with re-entrancy whereas the mach exception handler remains deterministic in the face of multiple fatal errors | ||
* the signal handler overwrites the "[red zone](https://en.wikipedia.org/wiki/Red_zone_(computing))" which is technically frowned upon in signal handlers (although unlikely to cause problems here) |
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
...er/include/CwlMachBadInstructionHandler.h → ...er/include/CwlMachBadInstructionHandler.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.