Thread
Commits
-
Remove redefinitions of SIG_* macros in win32_port.h.
- 0dc9c7d200e5 18.0 landed
-
Convert libpgport's pqsignal() to a void function.
- d4a43b283751 18.0 landed
-
Avoid calling pqsignal() with invalid signals on Windows frontends.
- 5cda4fdb0beb 18.0 landed
-
Avoid symbol collisions between pqsignal.c and legacy-pqsignal.c.
- 9a45a89c38f3 18.0 cited
-
Check that MyProcPid == getpid() in backend signal handlers.
- 3b00fdba9f20 17.0 cited
-
Further refactoring of c.h and nearby files.
- ed9b3606dadb 11.0 cited
-
Here's the latest win32 signals code, this time in the form of a patch
- 50491963cb6e 8.0.0 cited
-
Add C version of initdb, from Andrew Dunstan.
- 279598bb7138 8.0.0 cited
-
Allow Win32 to compile under MinGW. Major changes are:
- 12c942383296 7.4.1 cited
-
convert libpgport's pqsignal() to a void function
Nathan Bossart <nathandbossart@gmail.com> — 2025-01-15T02:45:12Z
(moving to a new thread) On Mon, Jan 13, 2025 at 10:04:31AM -0600, Nathan Bossart wrote: > On Sat, Jan 11, 2025 at 02:04:13PM -0500, Tom Lane wrote: >> BTW, this decouples legacy-pqsignal.c from pqsignal.c enough >> that we could now do what's contemplated in the comments from >> 3b00fdba9: simplify that version by making it return void, >> or perhaps better just a true/false success report. >> I've not touched that point here, though. > > I think it should just return void since AFAICT nobody checks the return > value. But it would probably be a good idea to add some sort of error > checking within the function. I've attached a draft patch that adds some > new assertions. I originally tried to use elog() where it was available, > but besides making the code even more unreadable, I think it's unnecessary > (since AFAICT any problems are likely coding errors). With commit 9a45a89 in place, this is now possible. I've attached a new version of the patch with a more fleshed-out commit message and a small comment fix. For background, the protections added by commit 3b00fdb introduced race conditions to pqsignal() that could lead to bogus return values. That's of little consequence since nobody seems to look at the return values, but it would have been nice to convert it to a void function to avoid any possibility of a bogus return value. Unfortunately, doing so would have required also modifying legacy-pqsignal.c's version of the function, which would've required an SONAME bump, which didn't seem worth it. Or so I thought... Thanks to commit 9a45a89, legacy-pqsignal.c now has its own dedicated extern for pqsignal(), which decouples it enough that we can follow through with changing libpqport's pqsignal() to a void function. Thoughts? -- nathan
-
Re: convert libpgport's pqsignal() to a void function
Tom Lane <tgl@sss.pgh.pa.us> — 2025-01-15T03:02:46Z
Nathan Bossart <nathandbossart@gmail.com> writes: > Thanks to commit 9a45a89, legacy-pqsignal.c now has its own dedicated > extern for pqsignal(), which decouples it enough that we can follow through > with changing libpqport's pqsignal() to a void function. > Thoughts? LGTM, although I don't know enough about Windows to know if the "== SIG_ERR" test in that path is correct. regards, tom lane
-
Re: convert libpgport's pqsignal() to a void function
Nathan Bossart <nathandbossart@gmail.com> — 2025-01-15T03:57:57Z
On Tue, Jan 14, 2025 at 10:02:46PM -0500, Tom Lane wrote: > LGTM, although I don't know enough about Windows to know if the > "== SIG_ERR" test in that path is correct. It's apparently not [0]. :( My guess is that this has something to do with redefining SIG_ERR in win32_port.h. We might be able to use push_macro/pop_macro to keep the old value around, but at the moment I'm leaning towards just removing the assertion in that path. [0] https://cirrus-ci.com/task/6237809813487616 -- nathan
-
Re: convert libpgport's pqsignal() to a void function
Tom Lane <tgl@sss.pgh.pa.us> — 2025-01-15T04:08:05Z
Nathan Bossart <nathandbossart@gmail.com> writes: > On Tue, Jan 14, 2025 at 10:02:46PM -0500, Tom Lane wrote: >> LGTM, although I don't know enough about Windows to know if the >> "== SIG_ERR" test in that path is correct. > It's apparently not [0]. :( Bleah. > My guess is that this has something to do with redefining SIG_ERR in > win32_port.h. We might be able to use push_macro/pop_macro to keep the old > value around, but at the moment I'm leaning towards just removing the > assertion in that path. I wonder why we redefine those values? But I tend to agree that just removing the test is sufficient for now. Given the lack of failure checks in the existing code, and the lack of trouble reports suggesting any problem, it's hard to muster enthusiasm for spending a lot of effort on this. regards, tom lane
-
Re: convert libpgport's pqsignal() to a void function
Nathan Bossart <nathandbossart@gmail.com> — 2025-01-15T19:15:26Z
On Tue, Jan 14, 2025 at 11:08:05PM -0500, Tom Lane wrote: > Nathan Bossart <nathandbossart@gmail.com> writes: >> My guess is that this has something to do with redefining SIG_ERR in >> win32_port.h. We might be able to use push_macro/pop_macro to keep the old >> value around, but at the moment I'm leaning towards just removing the >> assertion in that path. > > I wonder why we redefine those values? I wondered the same. Those redefines have been there since commit 5049196, but I haven't been able to find any real discussion in the archives about it. Maybe I will bug Magnus about it sometime, in case he happens to remember the reason. > But I tend to agree that just > removing the test is sufficient for now. Given the lack of failure > checks in the existing code, and the lack of trouble reports > suggesting any problem, it's hard to muster enthusiasm for spending > a lot of effort on this. Assuming cfbot likes this new version of the patch, I'll commit it shortly. Thanks for reviewing. -- nathan
-
Re: convert libpgport's pqsignal() to a void function
Thomas Munro <thomas.munro@gmail.com> — 2025-01-15T19:21:08Z
On Thu, Jan 16, 2025 at 8:15 AM Nathan Bossart <nathandbossart@gmail.com> wrote: > On Tue, Jan 14, 2025 at 11:08:05PM -0500, Tom Lane wrote: > > Nathan Bossart <nathandbossart@gmail.com> writes: > >> My guess is that this has something to do with redefining SIG_ERR in > >> win32_port.h. We might be able to use push_macro/pop_macro to keep the old > >> value around, but at the moment I'm leaning towards just removing the > >> assertion in that path. > > > > I wonder why we redefine those values? > > I wondered the same. Those redefines have been there since commit 5049196, > but I haven't been able to find any real discussion in the archives about > it. Maybe I will bug Magnus about it sometime, in case he happens to > remember the reason. My guess would be: perhaps some ancient version of MinGW didn't define them? They're defined by MinGW and native signal.h now and they have the same values, so we should remove them I think. Assertion failed: 0, file ../src/port/pqsignal.c, line 147 Could be due to calling native signal() with a signal number other than the 6 values required to work by the C standard?
-
Re: convert libpgport's pqsignal() to a void function
Nathan Bossart <nathandbossart@gmail.com> — 2025-01-15T19:47:18Z
On Thu, Jan 16, 2025 at 08:21:08AM +1300, Thomas Munro wrote: > On Thu, Jan 16, 2025 at 8:15 AM Nathan Bossart <nathandbossart@gmail.com> wrote: >> On Tue, Jan 14, 2025 at 11:08:05PM -0500, Tom Lane wrote: >> > I wonder why we redefine those values? >> >> I wondered the same. Those redefines have been there since commit 5049196, >> but I haven't been able to find any real discussion in the archives about >> it. Maybe I will bug Magnus about it sometime, in case he happens to >> remember the reason. > > My guess would be: perhaps some ancient version of MinGW didn't define > them? They're defined by MinGW and native signal.h now and they have > the same values, so we should remove them I think. Okay. If nothing else, it'd be interesting to see what the buildfarm thinks. > Assertion failed: 0, file ../src/port/pqsignal.c, line 147 > > Could be due to calling native signal() with a signal number other > than the 6 values required to work by the C standard? Looking closer, that probably makes more sense than my SIG_ERR redefinition theory. If that assertion is getting hit, that means signal() _is_ returning SIG_ERR (either the system one or our redefined version), and it looks like it's pretty common to use -1 for SIG_ERR. That'd only affect Windows frontend programs, but it still sounds scary. I'll try getting more details about the error with some custom cfbot runs. -- nathan
-
Re: convert libpgport's pqsignal() to a void function
Nathan Bossart <nathandbossart@gmail.com> — 2025-01-15T20:56:44Z
On Wed, Jan 15, 2025 at 01:47:18PM -0600, Nathan Bossart wrote: > On Thu, Jan 16, 2025 at 08:21:08AM +1300, Thomas Munro wrote: >> Could be due to calling native signal() with a signal number other >> than the 6 values required to work by the C standard? > > Looking closer, that probably makes more sense than my SIG_ERR redefinition > theory. If that assertion is getting hit, that means signal() _is_ > returning SIG_ERR (either the system one or our redefined version), and it > looks like it's pretty common to use -1 for SIG_ERR. That'd only affect > Windows frontend programs, but it still sounds scary. I'll try getting > more details about the error with some custom cfbot runs. I think this is what's happening. cfbot's test failures are caused by initdb's setup_signals(). The call to pqsignal(SIGHUP, trapsig) seems to fail because SIGHUP isn't a real signal number, just something that's made up in win32_port.h. This SIGHUP definition was added by commit 12c9423 in May 2003, then the pqsignal(SIGHUP, ...) call was added in initdb by commit 279598b in November 2003, but it might not have been broken at that time because it doesn't look like initdb.c included the SIGHUP #define. In any case, I think this has been broken since at least commit ed9b360 (November 2017), if not earlier. Perhaps we should surround all those extra signal #defines in win32_port.h with an #ifndef FRONTEND. initdb seems to be good about avoiding pqsignal() calls if the signal doesn't exist, but I wouldn't be surprised if there are other frontend programs that are not so cautious. I'll give it a try on cfbot and see what breaks... -- nathan
-
Re: convert libpgport's pqsignal() to a void function
Thomas Munro <thomas.munro@gmail.com> — 2025-01-15T22:07:41Z
On Thu, Jan 16, 2025 at 8:47 AM Nathan Bossart <nathandbossart@gmail.com> wrote: > On Thu, Jan 16, 2025 at 08:21:08AM +1300, Thomas Munro wrote: > > Could be due to calling native signal() with a signal number other > > than the 6 values required to work by the C standard? > > Looking closer, that probably makes more sense than my SIG_ERR redefinition > theory. If that assertion is getting hit, that means signal() _is_ > returning SIG_ERR (either the system one or our redefined version), and it > looks like it's pretty common to use -1 for SIG_ERR. That'd only affect > Windows frontend programs, but it still sounds scary. I'll try getting > more details about the error with some custom cfbot runs. Windows barely has signals, so I don't think it's too scary... SIGINT works but surprisingly runs the handler in another thread when you press ^C, SIGABRT, SIGFPE, SIGSEGV presumably have the obvious synchronous/exception-trapping implementations but we aren't even trying to catch those*, and SIGTERM, SIGILL are pro forma, never generated by the system. We've basically just invented more pro forma ones that will also never be generated except in the backend's entirely separate fake signal system that I hope to remove. +1 for your idea of not defining them at all outside the backend, it's just confusing noise. The second surprising thing, unless you're an armchair Unix archeologist, is that all but SIGFPE revert to SIG_DFL when they fire, like POSIX's SA_RESETHAND mode. I don't know if it also has SA_NODEFER behaviour (a combination of behaviours seen in some old Unixen of yestermillennium: your handler had to keep reinstalling itself, cf initdb.c:trapsig, but for a brief window the default process-terminating-core-dumping-nasal-daemon behaviour was installed and there was nothing you could do about that race; the BSD crew fixed that mistake a long time ago, everyone does it that way now, and POSIX sigaction() made those policies explicit and is the recommended replacement, but to this day the C standard has just signal() with undefined semantics and no requirement that any of it even work). *Even in the backend we don't catch Windows' native SIGFPE AFAICS, so I guess those must exit instead of being converted to an ERROR by FloatExceptionHandler. I wonder if there is a way to reach that condition from a SQL query.
-
Re: convert libpgport's pqsignal() to a void function
Nathan Bossart <nathandbossart@gmail.com> — 2025-01-15T23:47:51Z
On Thu, Jan 16, 2025 at 11:07:41AM +1300, Thomas Munro wrote: > +1 for your idea of not defining them at all outside the backend, it's > just confusing noise. I tried that, but these extra signals are needed even in the frontend for pgkill(), etc. My next thought was to simply ignore signal() errors for the extra signals, but I don't think that's very nice because it just masks broken code. Finally, I settled on modifying initdb's setup_signals() to use WIN32 checks instead of checking for the signals themselves. This is how it's done elsewhere, and this is apparently all that's needed to make cfbot's Windows run happy. I've also attached a 0002 that removes the redefinitions of SIG_ERR and friends. That looks good on cfbot, but we'll see what the buildfarm has to say... -- nathan
-
Re: convert libpgport's pqsignal() to a void function
Thomas Munro <thomas.munro@gmail.com> — 2025-01-16T01:18:44Z
On Thu, Jan 16, 2025 at 12:47 PM Nathan Bossart <nathandbossart@gmail.com> wrote: > On Thu, Jan 16, 2025 at 11:07:41AM +1300, Thomas Munro wrote: > > +1 for your idea of not defining them at all outside the backend, it's > > just confusing noise. > > I tried that, but these extra signals are needed even in the frontend for > pgkill(), etc. Right, of course. (In an unconf in Vancouver, a group of us were plotting that there should be a more explicit control socket to talk to the postmaster, on all OSes, to get current status, recovery progress, etc, and also support shutdown commands more explicitly. If you separately turn all the backend IPC signals into interrupts (CF 5118 and further work like that), and these cluster-level ones you just mentioned into commands in the hypothetical new cluster control protocol, then you don't need fake signals for Windows anymore, but apparently I got ahead of myself with that comment :-)) > My next thought was to simply ignore signal() errors for > the extra signals, but I don't think that's very nice because it just masks > broken code. Finally, I settled on modifying initdb's setup_signals() to > use WIN32 checks instead of checking for the signals themselves. This is > how it's done elsewhere, and this is apparently all that's needed to make > cfbot's Windows run happy. Cool. > I've also attached a 0002 that removes the redefinitions of SIG_ERR and > friends. That looks good on cfbot, but we'll see what the buildfarm has to > say... Ditto.
-
Re: convert libpgport's pqsignal() to a void function
Nathan Bossart <nathandbossart@gmail.com> — 2025-01-17T03:03:43Z
I've now committed all of this. I ended up finding a couple other frontend programs that called pqsignal() with an invalid signal number on Windows, so I fixed those as well. AFAICT the reason I didn't catch them in my earlier testing is because they aren't tested! I'll keep an eye on the buildfarm for any problems with the SIG_* redefinition removal, too. Thanks for reviewing and for sharing lots of context about this stuff. -- nathan