Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stdlib] Error recovery hook #12025

Closed
wants to merge 2 commits into from
Closed

Conversation

johnno1962
Copy link
Contributor

Hi Apple,

I was wondering if you would consider merging this relatively change into master. It gives developers the possibility of creating a custom fatal error handler to intercept a crash and perhaps log it or even unwind the stack to a safe point where the error can be handled. An example of this is Fortify.swift which has been tested with an Xcode toolchain and is portable to Linux and Android. This could form a key component of an effort to make Swift better suited to use in application servers which can not afford to have a failure in one part of the program take the whole process down though it would also have applications for mobile devices.

Cheers.

@johnno1962 johnno1962 changed the title Error recovery hook [stdlib] Error recovery hook Sep 20, 2017
@tkremenek
Copy link
Member

@kubamracek kubamracek self-requested a review September 20, 2017 21:07
@kubamracek
Copy link
Contributor

Hi! Could you be more specific about some potential use cases for this? Generally, fatal errors are meant to be fatal, because they're programmer bugs. When you mention that application servers need to be more stable as an example, we need to consider that servers also must prefer security: In case of a fatal error, like exclusivity violation, it makes sense to prefer a crash rather to risk unwanted code execution and potential vulnerabilities.

What exactly would you like to catch? Forced unwraps of nil? Swift very intentionally doesn't support recovery here. A force unwrap means "this can never ever be nil". If you cannot guarantee that, you should not use the force unwrap.

In any case, I this this needs more discussion on the Swift maillists. Can you move the discussion there?

@johnno1962
Copy link
Contributor Author

Hi, force unwrap errors were the initial target but AssertCommon.swift allows you you intercept almost all errors in one place. Using this hook and Fortify.swift The following can be made to work:

            do {
                try Fortify.exec {
                    var a: String!
                    a = a!
                }
            }
            catch {
                NSLog("Caught exception: \(error)")
            }

I wrote a small summary at this address: http://johnholdsworth.com/fortify.html about what the goals were. The actual implementation of the fallback is up to he user but this patch is the starting point.

@johnno1962
Copy link
Contributor Author

Re-reading your response, which mail list should I send this to? Evolution or developers?

@kubamracek
Copy link
Contributor

You can start with swift-dev.

@jckarter
Copy link
Contributor

This would be a good topic for swift-evolution. There are language design and implementation questions that need to be sorted out here.

@jckarter
Copy link
Contributor

As is, this patch would not be sufficient to respond to all fatal errors, since the compiler can generate traps directly in response to fatal conditions.

@jckarter
Copy link
Contributor

Unrelated, why are you disabling exclusivity checking here?

https://github.com/johnno1962/Fortify/blob/master/Sources/Fortify.swift#L70

If your code is violating inout exclusivity, it has undefined behavior.

@johnno1962
Copy link
Contributor Author

johnno1962 commented Sep 21, 2017

Hi, I’d be lying if I said I knew what the exclusivity checks where about but I had the impression they were a double check and I was getting an assertion failure at Exclusivity.cpp:218 just after the longjmp() so I disabled them. I also had a problem with exclusivity when Swift calls Java which calls Swift which this fixed. I’ve posted to Swift Evolution. No takers yet.

@jckarter
Copy link
Contributor

The exclusivity checks ensure that simultaneous inout accesses don't occur, which led to difficult-to-predict unspecified behavior in Swift 1-3 but is soon to be consider straight-up undefined behavior. If you're passing things with inout syntax &a, then that essentially puts a lock on a. It's likely if trying to use inout-to-pointer interop with things like longjmp is not going to work because you'll have simultaneous exclusive accesses on the Swift value being passed by pointer. If you need memory that can be accessed in an ad-hoc manner, you should allocate it yourself and use the pointer APIs to read and write it.

@johnno1962
Copy link
Contributor Author

I’ve updated https://github.com/johnno1962/Fortify to just trap the SIGILL & SIGABRT signals instead.

@johnno1962 johnno1962 closed this Apr 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants