OSDN Git Service

Add textporter_exit_on_segv parameter.
authorFujii Masao <fujii@postgresql.org>
Wed, 14 Jul 2021 13:08:31 +0000 (22:08 +0900)
committerFujii Masao <fujii@postgresql.org>
Wed, 14 Jul 2021 13:31:10 +0000 (22:31 +0900)
If off, which is the default, segmentation fault caused by textporter
will lead to the server crash. If on, only the current session calling
pgs2textporter1 function and causing textpoter to throw
segmentation fault will be terminated.

input/textporter.source
ludia_funcs.c
output/textporter.source
output/textporter_1.source

index d3dc26e..e7ffc76 100644 (file)
@@ -6,6 +6,7 @@ CREATE EXTENSION ludia_funcs;
 -- DMC_GETTEXT_OPT_CRLF
 SET ludia_funcs.textporter_option = 8;
 SET ludia_funcs.textporter_error TO warning;
+SET ludia_funcs.textporter_exit_on_segv TO off;
 
 -- Test whether pgs2textporter1() can extract the contents from
 -- various types of input files.
@@ -47,6 +48,11 @@ SELECT pgs2textporter1('@abs_srcdir@/data/noexist');
 SET ludia_funcs.textporter_error TO error;
 SELECT pgs2textporter1('@abs_srcdir@/data/noexist');
 
+-- Test whether pgs2textporter1() can extract the contents
+-- even when textporter_exit_on_segv is enabled.
+SET ludia_funcs.textporter_exit_on_segv TO on;
+SELECT pgs2textporter1('@abs_srcdir@/data/test.docx');
+
 -- Clean up ludia_funcs module
 DROP EXTENSION ludia_funcs;
 
index c10d4e9..22fed40 100644 (file)
@@ -121,6 +121,7 @@ static bool                 EscapeSnippetKeyword(char **s, size_t *slen);
 /* GUC variables for pgs2textpoter1 */
 static int     textporter_error = ERROR;
 static unsigned int    textporter_option = TEXTPORTER_OPTION;
+static bool    textporter_exit_on_segv = false;
 
 /*
  * This variable is a dummy that doesn't do anything, except in some
@@ -143,6 +144,7 @@ static void CleanupTextPorterTmpFiles(void);
 
 static bool check_textporter_option(char **newval, void **extra, GucSource source);
 static void assign_textporter_option(const char *newval, void *extra);
+static void textporter_exit_on_segv_handler(SIGNAL_ARGS);
 #endif /* TEXTPORTER */
 
 void   _PG_init(void);
@@ -207,6 +209,17 @@ _PG_init(void)
                                                           assign_textporter_option,
                                                           NULL);
 
+       DefineCustomBoolVariable("ludia_funcs.textporter_exit_on_segv",
+                                                        "Terminate session when textporter causes segmentation fault.",
+                                                        NULL,
+                                                        &textporter_exit_on_segv,
+                                                        false,
+                                                        PGC_USERSET,
+                                                        0,
+                                                        NULL,
+                                                        NULL,
+                                                        NULL);
+
        /* Clean up remaining textporter temporary files */
        CleanupTextPorterTmpFiles();
 #endif /* TEXTPORTER */
@@ -301,6 +314,14 @@ pgs2textporter1(PG_FUNCTION_ARGS)
                                         errmsg("could not close temporary file \"%s\": %m", txtfile)));
 
                /*
+                * If textporter_exit_on_segv option is enabled, segmentation fault
+                * caused by textporter will terminate only this connection and
+                * not lead to the server crash.
+                */
+               if (textporter_exit_on_segv)
+                       pqsignal(SIGSEGV, textporter_exit_on_segv_handler);
+
+               /*
                 * Run TextPorter to read text data from application file (appfile)
                 * to temporary file (txtfile).
                 */
@@ -311,6 +332,10 @@ pgs2textporter1(PG_FUNCTION_ARGS)
                                                         TEXTPORTER_BBIGENDIAN, textporter_option,
                                                         TEXTPORTER_OPTION1, TEXTPORTER_SIZE,
                                                         TEXTPORTER_CSV_C);
+
+               if (textporter_exit_on_segv)
+                       pqsignal(SIGSEGV, SIG_DFL);
+
                if (ret != 0)
                {
                        ereport(textporter_error,
@@ -433,6 +458,15 @@ assign_textporter_option(const char *newval, void *extra)
        textporter_option = *((unsigned int *) extra);
 }
 
+static void
+textporter_exit_on_segv_handler(SIGNAL_ARGS)
+{
+       ereport(FATAL,
+                       (errcode(ERRCODE_INTERNAL_ERROR),
+                        errmsg("terminating PostgreSQL server process due to "
+                                       "segmentation fault by textporter")));
+}
+
 #else  /* TEXTPORTER */
 
 Datum
index bdae4f7..c1c74ce 100644 (file)
@@ -4,6 +4,7 @@ CREATE EXTENSION ludia_funcs;
 -- DMC_GETTEXT_OPT_CRLF
 SET ludia_funcs.textporter_option = 8;
 SET ludia_funcs.textporter_error TO warning;
+SET ludia_funcs.textporter_exit_on_segv TO off;
 -- Test whether pgs2textporter1() can extract the contents from
 -- various types of input files.
 SELECT pgs2snippet1(1,300,1,'∇','∇',0,'データベース',pgs2textporter1('@abs_srcdir@/data/test.txt'));
@@ -559,6 +560,15 @@ SET ludia_funcs.textporter_error TO error;
 SELECT pgs2textporter1('@abs_srcdir@/data/noexist');
 ERROR:  could not get text from application file "@abs_srcdir@/data/noexist"
 DETAIL:  DMC_GetText_V5() failed with errcode 2001
+-- Test whether pgs2textporter1() can extract the contents
+-- even when textporter_exit_on_segv is enabled.
+SET ludia_funcs.textporter_exit_on_segv TO on;
+SELECT pgs2textporter1('@abs_srcdir@/data/test.docx');
+           pgs2textporter1            
+--------------------------------------
+ PostgreSQLはオープンソースのDBMSです
+(1 row)
+
 -- Clean up ludia_funcs module
 DROP EXTENSION ludia_funcs;
 -- Test the case where database encoding is not UTF8
index 71bddd0..e5b87fd 100644 (file)
@@ -4,6 +4,7 @@ CREATE EXTENSION ludia_funcs;
 -- DMC_GETTEXT_OPT_CRLF
 SET ludia_funcs.textporter_option = 8;
 SET ludia_funcs.textporter_error TO warning;
+SET ludia_funcs.textporter_exit_on_segv TO off;
 -- Test whether pgs2textporter1() can extract the contents from
 -- various types of input files.
 SELECT pgs2snippet1(1,300,1,'∇','∇',0,'データベース',pgs2textporter1('@abs_srcdir@/data/test.txt'));
@@ -559,6 +560,15 @@ SET ludia_funcs.textporter_error TO error;
 SELECT pgs2textporter1('@abs_srcdir@/data/noexist');
 ERROR:  could not get text from application file "@abs_srcdir@/data/noexist"
 DETAIL:  DMC_GetText_V5() failed with errcode 2001
+-- Test whether pgs2textporter1() can extract the contents
+-- even when textporter_exit_on_segv is enabled.
+SET ludia_funcs.textporter_exit_on_segv TO on;
+SELECT pgs2textporter1('@abs_srcdir@/data/test.docx');
+            pgs2textporter1            
+---------------------------------------
+ PostgreSQLはオープンソースのDBMSです
+(1 row)
+
 -- Clean up ludia_funcs module
 DROP EXTENSION ludia_funcs;
 -- Test the case where database encoding is not UTF8