(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,
¶mTypes,
&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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers