-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use sigsetjmp / siglongjmp instead so that signal mask behavior is de…
…fined consistently across platforms (back port from loladiro fork). should help with #1216, but doesn't yet fix it
- Loading branch information
Showing
3 changed files
with
24 additions
and
16 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
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
b842bf4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't this be handled by resetting the signal mask in e.g.
segv_handler
like we do now? What else do we do that changes the signal mask? Can you confirm that this fixes something? If so, it would need to be changed in the code generator too.b842bf4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently it probably could be. But sigsetjmp / siglongjmp are just a few extra assembly instructions more then their less well defined (and older) counterparts setjmp / longjmp so it's not really a significantly change. I've contemplated altering the signal mask during atomic operations (including things like uv_write) that would be bad to have interrupted. I had trouble with libuv modifying the signal mask when I didn't expect it, so I wanted to at least keep those changes limited to a single context while we try to eliminate them. Tracking those is easier if the errors occur in the same threading context as the libuv calls.
Since readline (and other libraries / user code) may also alter the signal mask, I wasn't sure it was safe to simply clear them (plus that would require more function calls during a context switch).
But right, the code generator does this too in the try catch blocks! With that patched too, this change seems to fix #1216
b842bf4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'm much more convinced if it actually fixes #1216 :)
Doesn't
sigprocmask
require a system call though?We have
JL_SIGATOMIC
, which uses a lighter-weight mechanism than changing the signal mask.Readline might mess with signals, but since the problem also happened in the basic repl can we conclude it is caused by libuv?
b842bf4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find
try
is about 3x slower, and throw+catch is about 50% slower. Of course try/catch is usually a tiny fraction of runtime, but it would be nice if we could skip the sigprocmask by stopping the problem at the source.b842bf4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was almost definitely caused by libuv. The internal libev tries to install a signal mask for everything that it was not told to handle. The call to (void)uv_default_loop() forces this to happen early and at a known time, then restore_signals() only needs to be called once to clean up from that. I had tried to just completely disable it, but it is required for spawning child processes now. It may be possible to disable using hacks into the libev backend.
I think I will eventually try to start wrapping the calls to uv_write with JL_SIGATOMIC then (since uv will assert(0) when you try to re-enter that function -- i.e. if the user sends an interrupt while the program is pouring out text). sigprocmask did seem a bit too heavy for that, but it's possible other libraries will eventually want (or need) to make use of it (i assume the syscall doesn't do much more than update a similar variable to JL_SIGATOMIC, and thus it's probably a bit faster method for when the signal is getting raised often relative to the calls to sigprocmask)
b842bf4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I didn't see that they could be so different. On Mac,
setjmp == sigsetjmp(*,1)
but_setjmp == sigsetjmp(*,0)
I would like to keep using sigsetjmp since it is more consistently defined across architectures. However once we can get libuv to behave and not mess up the signal mask, we can change the second argument to 0 to skip the syscall for sigprocmask
b842bf4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get
(even after make clean)
I'm on latest Ubuntu, 64bit, using gcc 4.6.
Anything I could do?