(Re-sending just the fourth of four patches: c++exception)

These patches are based on CVS head in which the latest commit was
 user:        petere
 date:        Thu Dec 04 17:51:28 2008 +0000
 summary:     Default values for function arguments

4. c++exception

    When C code calls C++ code, all C++ exceptions need to be caught
    and fully contained within the C++ code.  Exceptions should never
    be thrown outward across the C/C++ frontier.

    If an exception is not caught within C++ code, and the search for
    a matching 'catch' bumps into a C stack frame, the result may be
    platform dependent.  On my platform (Linux/GCC), if this happens
    in the postgres backend, the process terminates silently as if
    abort() had been called.

    With this patch, if --enable-cplusplus is configured,
    PostgresMain defines a handler to intercept any uncaught C++
    exception and convert it to a conventional PostgreSQL error of
    FATAL severity.  This allows the backend to clean up and report
    the error before terminating.

diff -r 9b2c774a6b05 src/backend/tcop/Makefile
--- a/src/backend/tcop/Makefile
+++ b/src/backend/tcop/Makefile
@@ -14,6 +14,11 @@

 OBJS= dest.o fastpath.o postgres.o pquery.o utility.o

+# Designate modules to be compiled as C++ when 'configure --enable-cplusplus'
+ifeq ($(enable_cplusplus),yes)
+CXXOBJS = postgres.o
+endif
+
 ifneq (,$(filter $(PORTNAME),cygwin win32))
 override CPPFLAGS += -DWIN32_STACK_RLIMIT=$(WIN32_STACK_RLIMIT)
 endif
diff -r 9b2c774a6b05 src/backend/tcop/postgres.c
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -33,6 +33,17 @@
 #endif
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
+#endif
+
+#ifdef ENABLE_CPLUSPLUS
+#ifndef __cplusplus
+#error --enable-cplusplus configure option specified; this file should be 
compiled as C++
+#endif
+#include <exception>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
 #endif

 #ifndef HAVE_GETRUSAGE
@@ -163,6 +174,11 @@
 #endif   /* TCOP_DONTUSENEWLINE */


+#ifdef __cplusplus
+}                               /* extern "C" */
+#endif
+
+
 /* ----------------------------------------------------------------
  *             decls for routines only used in this file
  * ----------------------------------------------------------------
@@ -1212,7 +1228,7 @@
                if (log_parser_stats)
                        ResetUsage();

-               query = parse_analyze_varparams(copyObject(raw_parse_tree),
+               query = parse_analyze_varparams((Node 
*)copyObject(raw_parse_tree),
                                                                                
query_string,
                                                                                
&paramTypes,
                                                                                
&numParams);
@@ -1679,7 +1695,7 @@
                 * we have to make a copy of the parse trees.  FIXME someday.
                 */
                oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
-               query_list = copyObject(cplan->stmt_list);
+               query_list = (List *)copyObject(cplan->stmt_list);
                plan_list = pg_plan_queries(query_list, 0, params, true);
                MemoryContextSwitchTo(oldContext);

@@ -2791,6 +2807,29 @@

        return NULL;
 }
+
+
+#ifdef ENABLE_CPLUSPLUS
+/*
+ * PostgresMainUncaught
+ *      Called when C++ code throws an exception which is not caught.
+ *
+ * NB: On some platforms when C++ code calls C code, and the C code calls
+ * a deeper layer of C++ code, the outer C++ code can't catch exceptions
+ * thrown by the inner C++ code.  The search for a matching 'catch' is
+ * abandoned upon encountering an intervening C stack frame, and the
+ * exception is considered uncaught.
+ */
+static void
+PostgresMainUncaught()
+{
+    /* Context callbacks might not work right if call stack has been unwound */
+    error_context_stack = NULL;
+
+    elog(FATAL, "Unexpected internal error: Unhandled C++ exception");
+    abort();                                /* not reached */
+}
+#endif  /* ENABLE_CPLUSPLUS */


 /* ----------------------------------------------------------------
@@ -2850,6 +2889,11 @@
        /* Set up reference point for stack depth checking */
        stack_base_ptr = &stack_base;

+#ifdef ENABLE_CPLUSPLUS
+    /* Any unhandled C++ exception is to be treated as a FATAL error. */
+    std::set_terminate(PostgresMainUncaught);
+#endif
+
        /* Compute paths, if we didn't inherit them from postmaster */
        if (my_exec_path[0] == '\0')
        {
@@ -3108,10 +3152,10 @@
                        char       *name;
                        char       *value;

-                       name = lfirst(gucopts);
+                       name = (char *)lfirst(gucopts);
                        gucopts = lnext(gucopts);

-                       value = lfirst(gucopts);
+                       value = (char *)lfirst(gucopts);
                        gucopts = lnext(gucopts);

                        if (IsSuperuserConfigOption(name))
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to