-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
trap ctrl-C in the repl #26
Comments
Is there an efficient and reliable way to do this? Continuing after handling an asynchronous signal can leave the system in an inconsistent state. |
OK, the only thing I can think of is to block SIGINT around anything that temporarily violates invariants. |
Either that or set a flag and check it at various safe checkpoints. This is not just a repl issue: any "real" programming langage needs to be able to trap and handle signals reliably. Maybe we can look into how other languages handle this. |
There is no shortage of debate around asynchronous signals (e.g. FPE, SEGV, INT). Everybody wants to trap them and handle them gracefully but POSIX simply won't let you do it. Of course everybody does it anyway and it usually works. |
Would blocking signals during the critical sections (i.e. when the process could be left in an incoherent state) solve the problem? Doing some reading, it seems that POSIX signals sent while signals are blocked should be delivered immediately after the signals become unblocked. |
Maybe. We have relatively few places that do non-atomic updates to global state, but I would worry about library calls like malloc(). |
Can we provide our own malloc so that users and libraries can't call libc malloc directly? Agreed that you have to let users decide ultimately, but the default should be safe first, and hopefully also with relatively little overhead. The @sigatomic macro is an excellent addition. Most people will never have to use it, but we can provide the ability, which is key. |
Safe yes, but against what? Handling signals is not part of most applications' normal operation. I hate to add overhead just for the 1 time a week you want to hit ctrl-C, but I guess it can't be helped and hopefully won't even be measurable. |
Ruby handles these things well, whereas Perl, for example is notoriously bad at it (although fast). |
I think it is important to architect the system for ctrl-c. It's a real pain in the cloud environment, if you are in a native code computation, and ctrl-c just doesn't become effective. I would even be ok with leaking memory, as a user. I used to frequently want to hit ctrl-c when using Star-P, and it was really painful as it just didn't do anything useful. Also, I don't think ctrl-c should quit the client. That is what ctrl-d does. |
Agree --- even though I don't really believe in ctrl-c, it's one of those perceptual things that people expect and just feels nice. |
a few more things probably need to be made signal safe, but it is usable now with the caveat that you shouldn't trust the system too much after hitting ctrl-C.
This issue seems adequately addressed to me at this point. Can we close it? |
We probably need more signal-atomic sections. I haven't dealt with malloc, free, and realloc, and task switching, and who knows, maybe more. It's annoying though because all those sigatomic sections are like lisa simpson's tiger-repelling rock; you can't really be sure it's working. |
Brilliant analogy. |
Add stub inline and noinline macros
Use ⊻ instead of $ and bump Compat requirement
no precompilation remark, add pkg3 clone, pkg dir
Fix indentation to follow guide rules
It's possible for PiNodes to effectively imply statically the condition of a Core.ifelse. For example: ```julia 23 ─ %60 = Core.ifelse(%47, false, true)::Bool │ %61 = Core.ifelse(%47, %58, false)::Union{Missing, Bool} 25 ─ goto JuliaLang#27 if not %60 26 ─ %65 = π (%61, Bool) └─── ... ``` In basic block JuliaLang#26, the PiNode gives us enough information to conclude that `%47 === false` if control flow reaches that point. The previous code incorrectly assumed that this kind of pruning would only be done for PhiNodes. Resolves JuliaLang#50276.
It's possible for PiNodes to effectively imply statically the condition of a Core.ifelse. For example: ```julia 23 ─ %60 = Core.ifelse(%47, false, true)::Bool │ %61 = Core.ifelse(%47, %58, false)::Union{Missing, Bool} 25 ─ goto JuliaLang#27 if not %60 26 ─ %65 = π (%61, Bool) └─── ... ``` In basic block JuliaLang#26, the PiNode gives us enough information to conclude that `%47 === false` if control flow reaches that point. The previous code incorrectly assumed that this kind of pruning would only be done for PhiNodes. Resolves JuliaLang#50276.
It's possible for PiNodes to effectively imply statically the condition of a Core.ifelse. For example: ```julia 23 ─ %60 = Core.ifelse(%47, false, true)::Bool │ %61 = Core.ifelse(%47, %58, false)::Union{Missing, Bool} 25 ─ goto JuliaLang#27 if not %60 26 ─ %65 = π (%61, Bool) └─── ... ``` In basic block JuliaLang#26, the PiNode gives us enough information to conclude that `%47 === false` if control flow reaches that point. The previous code incorrectly assumed that this kind of pruning would only be done for PhiNodes. Resolves JuliaLang#50276.
It's possible for PiNodes to effectively imply statically the condition of a Core.ifelse. For example: ```julia 23 ─ %60 = Core.ifelse(%47, false, true)::Bool │ %61 = Core.ifelse(%47, %58, false)::Union{Missing, Bool} 25 ─ goto JuliaLang#27 if not %60 26 ─ %65 = π (%61, Bool) └─── ... ``` In basic block JuliaLang#26, the PiNode gives us enough information to conclude that `%47 === false` if control flow reaches that point. The previous code incorrectly assumed that this kind of pruning would only be done for PhiNodes. Resolves JuliaLang#50276.
It's possible for PiNodes to effectively imply statically the condition of a Core.ifelse. For example: ```julia 23 ─ %60 = Core.ifelse(%47, false, true)::Bool │ %61 = Core.ifelse(%47, %58, false)::Union{Missing, Bool} 25 ─ goto JuliaLang#27 if not %60 26 ─ %65 = π (%61, Bool) └─── ... ``` In basic block JuliaLang#26, the PiNode gives us enough information to conclude that `%47 === false` if control flow reaches that point. The previous code incorrectly assumed that this kind of pruning would only be done for PhiNodes. Resolves JuliaLang#50276.
It's possible for PiNodes to effectively imply statically the condition of a Core.ifelse. For example: ```julia 23 ─ %60 = Core.ifelse(%47, false, true)::Bool │ %61 = Core.ifelse(%47, %58, false)::Union{Missing, Bool} 25 ─ goto #27 if not %60 26 ─ %65 = π (%61, Bool) └─── ... ``` In basic block #26, the PiNode gives us enough information to conclude that `%47 === false` if control flow reaches that point. The previous code incorrectly assumed that this kind of pruning would only be done for PhiNodes. Resolves #50276
Ctrl-C currently kills the repl, which is very annoying. It should abort the current computation as quickly as possible.
The text was updated successfully, but these errors were encountered: