]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Restore SIGFPE handler after initializing PL/Perl.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 5 Sep 2012 20:43:55 +0000 (16:43 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 5 Sep 2012 20:43:55 +0000 (16:43 -0400)
Perl, for some unaccountable reason, believes it's a good idea to reset
SIGFPE handling to SIG_IGN.  Which wouldn't be a good idea even if it
worked; but on some platforms (Linux at least) it doesn't work at all,
instead resulting in forced process termination if the signal occurs.
Given the lack of other complaints, it seems safe to assume that Perl
never actually provokes SIGFPE and so there is no value in the setting
anyway.  Hence, reset it to our normal handler after initializing Perl.

Report, analysis and patch by Andres Freund.

src/pl/plperl/plperl.c

index 7206e2e2da74c8a537a82a727d8891e49269f5c2..0d7e3b94e7fe5ac8018e74e5d9b0c2f5d3d5ab21 100644 (file)
 #include "commands/trigger.h"
 #include "executor/spi.h"
 #include "funcapi.h"
+#include "libpq/pqsignal.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "parser/parse_type.h"
+#include "tcop/tcopprot.h"
 #include "utils/fmgroids.h"
 #include "utils/guc.h"
 #include "utils/lsyscache.h"
@@ -552,6 +554,18 @@ plperl_init_interp(void)
        if (!perl_sys_init_done)
        {
                PERL_SYS_INIT3(&nargs, (char ***) &embedding, (char ***) &dummy_perl_env);
+
+               /*
+                * For unclear reasons, PERL_SYS_INIT3 sets the SIGFPE handler to
+                * SIG_IGN.  Aside from being extremely unfriendly behavior for a
+                * library, this is dumb on the grounds that the results of a
+                * SIGFPE in this state are undefined according to POSIX, and in
+                * fact you get a forced process kill at least on Linux.  Hence,
+                * restore the SIGFPE handler to the backend's standard setting.
+                * (See Perl bug 114574 for more information.)
+                */
+               pqsignal(SIGFPE, FloatExceptionHandler);
+
                perl_sys_init_done = 1;
        }
 #endif