-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
[RFC] signal_init: Always unblock SIGCHLD. #5243
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
Conversation
Sorry, I'm confused, why does vim not need to do this? edit: I understand now, the key difference is epoll. |
macos gcc failure is weird:
|
62874f7
to
a71dea1
Compare
@@ -45,6 +46,14 @@ void signal_init(void) | |||
signal_watcher_init(&main_loop, &spwr, NULL); | |||
signal_watcher_start(&spwr, on_signal, SIGPWR); | |||
#endif | |||
|
|||
#ifdef SIGCHLD |
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.
Not that it matters too much in this, but to indicate that this should be more like a "clean slate", it might be better to move this code to the top of the function.
LGTM |
a71dea1
to
222f498
Compare
The macos gcc error seems insane. |
I think I see where the OS X error is coming from: from signal.h: int sigaddset(sigset_t *, int);
#define sigaddset(set, signo) (*(set) |= __sigbits(signo), 0) from sys/_types/_sigset.h:
and from sys/_types.h:
So it seems, OS X said sigset_t is unsigned, but then ORs in an int, mixing the types. So GCC seems correct here... sadly. |
Something weird is definitely going on. OSX clang (the default compiler) with #include <stdio.h>
#include <signal.h>
int main() {
sigset_t s;
sigemptyset(&s);
sigaddset(&s, SIGCHLD);
return 0;
} But gcc (6) does.
Perhaps it's using different |
Something is suppressing those warnings. Running the preprocessor with both Still, the code looked like it should warn, so I did:
Hah! I got you, clang, you conniving compiler... |
So the system header is broken. Is the |
I kinda want to know how Apple is avoiding those warnings. But I can't find it... |
Inherited signal mask may block SIGCHLD, which causes libuv to hang at epoll_wait. Closes neovim#5230 Helped-by: Nicolas Hillegeer <nicolas@hillegeer.com> Helped-by: John Szakmeister <john@szakmeister.net> Note: the #pragma gymnastics are a workaround for broken system headers on macOS. signal.h: int sigaddset(sigset_t *, int); #define sigaddset(set, signo) (*(set) |= __sigbits(signo), 0) sys/_types/_sigset.h: typedef __darwin_sigset_t sigset_t; sys/_types.h: typedef __uint32_t __darwin_sigset_t; /* [???] signal set */ sigset_t is defined as unsigned int, but the sigaddset() ORs it with an int, mixing the types. So GCC generates a sign-conversion warning: sig.c:9:13: warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-Wsign-conversion] (*(&s) |= __sigbits((sigset_t) 20), 0); ~~ ^~~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. System headers are normally ignored when the compiler generates warnings: https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html > GCC gives code found in system headers special treatment. All warnings, > other than those generated by ‘#warning’ (see Diagnostics), are suppressed > while GCC is processing a system header. Macros defined in a system header > are immune to a few warnings wherever they are expanded. This immunity is > granted on an ad-hoc basis, when we find that a warning generates lots of > false positives because of code in macros defined in system headers. Instead of the #pragma workaround, we could cast the sigset_t pointer: # if defined(__APPLE__) sigaddset((int *)&mask, SIGCHLD); # else sigaddset(&mask, SIGCHLD); # endif but that could break if the headers are later fixed.
So, I really can't find any pragmas. But I encountered this in the GCC docs:
And
Which implies that system headers are usually automatically warning-free. But the case is different for macro's. Macro's in system headers are not exempt from all warnings. Perhaps That would explain why this happens:
...in the second case, the code is inlined, and no longer in a system header. |
...and another reference from the Clang devs from 2012. Still no word on where to find exactly which warnings/macro's are considered: http://clang-developers.42468.n3.nabble.com/Warnings-from-macro-expansions-vs-system-headers-td4028109.html |
Man, that pragma solution is unbelievably ugly, but it's starting to look like the only way. libuv doesn't have the same warning levels as us, AFAIK. Perhaps we should file a bug to the GCC devs to make an exception for this one. Or... a rdar:// bug for the Apple folks, but something tells me they'll be less than responsive. |
Given that we know how this is generated under OS X, we could maybe just cast the argument under OS X: sigaddset(&s, (sigset_t) SIGCHLD); It's not great either, but less ugly than the pragma stuff and a decent comment would help future readers know why we're doing. Just a thought. @aktau I've filed several development related bugs in the past for similar, and they're very unresponsive to them. :-( |
@jszakmeister see the first smurf commit. That did not seem to work. |
@jszakmeister as @justinmk mentioned, you cannot get around it with a cast. The problem is in the implementation of
Thre return value of NOTE: SIGCHLD = 20. |
I tried it with gcc-5 before making the suggestion, but it looks like I just missed the warning. Sorry for the noise. I also didn't see the __sigbits() in there to help screw up that trick. Oh well.
Right... I wasn't trying to say it was, I just missed __sigbits being in there. It is, however, trying to OR an int and an unsigned int, and it was that which I was hoping to avoid. :-) |
You could go the other way... since it's the mask that it's being OR'd into, you could cast it instead. That seems to get rid of the warning: sigaddset((int *) &mask, SIGCHLD); |
Ok, we still need to detect when this should be done. Because for systems that don't have such headers we could end up with the reverse problem.... |
Very clever!
Exactly. |
I would guess that will break if Apple fixes their headers. So I think disabling the warning for that single line is the least costly approach. |
3e79757
to
897092f
Compare
Updated, including notes from this discussion in the commit message. Will merge after build. |
897092f
to
de20bf4
Compare
Indeed that would be the idea. At that point we'll know they fixed their headers and we can adjust the |
@@ -29,6 +32,9 @@ static bool rejecting_deadly; | |||
|
|||
void signal_init(void) | |||
{ | |||
// Ensure that SIGCHLD is unblocked, else libuv (epoll_wait) may hang. |
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.
You could probably make a direct reference to the issue that caused it here.
(unsure what project policy is w.r.t that in this day and age.)
Said another way. if we go with the current way (pragmas), we might never know when Apple fixes this, and we might get stuck with technical debt forever. I believe this is how Vim reached its current state as well. Eternal manual vigilance vs automatic machine vigilance and a bit of fixer-upping. I know which one I'd chose. |
As discussed on neovim#5243. The goal is to cleanup the code (temporarily ignoring warnings is really ugly) _and_ to find out when Apple fixes their headers. This code will start to warn whenever they do so. Thanks go to John Szakmeister for the idea. Helped-by: John Szakmeister <john@szakmeister.net>
As discussed on neovim#5243 and neovim#5283. Helped-by: John Szakmeister <john@szakmeister.net> Helped-by: Justin M. Keyes <justinkz@gmail.com>
FEATURES: 0b5a7e4 neovim#4432 API: external UIs can render custom popupmenu c6ac4f8 neovim#4934 API: call any API method from vimscript 31df051 neovim#4568 API: nvim_call_atomic(): multiple calls in a single request b268ba3 neovim#5424 API: nvim_win_get_number(), nvim_tabpage_get_number() e7e2844 has("nvim-1.2.3") checks for a specific Nvim version 522b885 neovim#5295, neovim#5493 `:CheckHealth` checks tmux, terminfo, performance 719dae2 neovim#5384 events: allow event processing in getchar() f25797f neovim#5386 API: metadata: Nvim version & API level 22dfe69 neovim#5389 API: metadata: "since", "deprecated_since" 605e743 Added QuickFixLine highlight group CHANGES: 4af6ec7 neovim#5253 perf: Disable clipboard in do_cmdline() 6e9f329 neovim#5299 perf: Skip foldUpdate() in insert-mode. 9d4fcec neovim#5426 perf: Do not auto-update folds for some foldmethods. eeec0ca neovim#5419 tui: Default to normal-mode cursor shape. FIXES: e838452 neovim#5436 tui: Fix "weird characters" / "bleeding termcodes" 10a54ad neovim#5243 signal_init: Always unblock SIGCHLD. bccb49b neovim#5316 eval.c: Fix memory leak for detached pty job 626065d neovim#5227 tchdir: New tab should inherit CWD. cd321b7 neovim#5292 getcwd(): Return empty string if CWD is invalid. 6127eae shada: Fix non-writeable ShaDa directory handling ca65514 neovim#2789 system(): Respect shellxescape, shellxquote 2daf54e neovim#4874 Restore vim-like tab dragging 0c536b5 neovim#5319 syntax.c: Support bg/fg special color-names. 3c53371 neovim#4972 from justinmk/schedule-ui_refresh 68bcb32 neovim#4789 tui.c: Do not wait for tui loop on teardown. c8b6ec2 neovim#5409 v:count broken in command-line window 6bc3bce neovim#5461 fix emoji display 51937e1 neovim#5470 fix :terminal with :argadd, :argu 79d77da neovim#5481 external UIs: opening multiple files from command-line 657ba62 neovim#5501 rplugin: resolve paths in manifest file 6a6f188 neovim#5502 system('foo &', 'bar'): Show error, don't crash. 1ff162c neovim#5515 os_nodetype: open fd with O_NONBLOCK 2a6c5bb neovim#5450 modeline: Handle version number overflow. 0ade1bb neovim#5225 CI tests now run against Windows!
FEATURES: 0b5a7e4 neovim#4432 API: external UIs can render custom popupmenu c6ac4f8 neovim#4934 API: call any API method from vimscript 31df051 neovim#4568 API: nvim_call_atomic(): multiple calls in a single request b268ba3 neovim#5424 API: nvim_win_get_number(), nvim_tabpage_get_number() e7e2844 has("nvim-1.2.3") checks for a specific Nvim version 522b885 neovim#5295, neovim#5493 `:CheckHealth` checks tmux, terminfo, performance 719dae2 neovim#5384 events: allow event processing in getchar() f25797f neovim#5386 API: metadata: Nvim version & API level 22dfe69 neovim#5389 API: metadata: "since", "deprecated_since" 605e743 Added QuickFixLine highlight group CHANGES: 4af6ec7 neovim#5253 perf: Disable clipboard in do_cmdline() 6e9f329 neovim#5299 perf: Skip foldUpdate() in insert-mode. 9d4fcec neovim#5426 perf: Do not auto-update folds for some foldmethods. eeec0ca neovim#5419 tui: Default to normal-mode cursor shape. FIXES: e838452 neovim#5436 tui: Fix "weird characters" / "bleeding termcodes" 10a54ad neovim#5243 signal_init: Always unblock SIGCHLD. bccb49b neovim#5316 eval.c: Fix memory leak for detached pty job 626065d neovim#5227 tchdir: New tab should inherit CWD. cd321b7 neovim#5292 getcwd(): Return empty string if CWD is invalid. 6127eae shada: Fix non-writeable ShaDa directory handling ca65514 neovim#2789 system(): Respect shellxescape, shellxquote 2daf54e neovim#4874 Restore vim-like tab dragging 0c536b5 neovim#5319 syntax.c: Support bg/fg special color-names. 3c53371 neovim#4972 from justinmk/schedule-ui_refresh 68bcb32 neovim#4789 tui.c: Do not wait for tui loop on teardown. c8b6ec2 neovim#5409 v:count broken in command-line window 6bc3bce neovim#5461 fix emoji display 51937e1 neovim#5470 fix :terminal with :argadd, :argu 79d77da neovim#5481 external UIs: opening multiple files from command-line 657ba62 neovim#5501 rplugin: resolve paths in manifest file 6a6f188 neovim#5502 system('foo &', 'bar'): Show error, don't crash. 1ff162c neovim#5515 os_nodetype: open fd with O_NONBLOCK 2a6c5bb neovim#5450 modeline: Handle version number overflow. 0ade1bb neovim#5225 CI tests now run against Windows!
Inherited signal mask may block SIGCHLD, which causes libuv to hang at
epoll_wait.
Closes #5230