summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2009-05-15 15:56:39 +0000
committerTom Lane2009-05-15 15:56:39 +0000
commit1f4cebe8eaae7f1992870842b1a9892e56856746 (patch)
tree800a6a05d8b9ce3a4579566c5f2f038400f7c94d
parentfdfb258cba5dc7dbc1b81fc6e100bd435d4c8f42 (diff)
Fix all the server-side SIGQUIT handlers (grumble ... why so many identical
copies?) to ensure they really don't run proc_exit/shmem_exit callbacks, as was intended. I broke this behavior recently by installing atexit callbacks without thinking about the one case where we truly don't want to run those callback functions. Noted in an example from Dave Page.
-rw-r--r--src/backend/access/transam/xlog.c18
-rw-r--r--src/backend/postmaster/autovacuum.c18
-rw-r--r--src/backend/postmaster/bgwriter.c18
-rw-r--r--src/backend/postmaster/walwriter.c18
-rw-r--r--src/backend/storage/ipc/ipc.c6
-rw-r--r--src/backend/tcop/postgres.c20
6 files changed, 70 insertions, 28 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 58b647af52..1b575e242a 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7790,14 +7790,22 @@ startupproc_quickdie(SIGNAL_ARGS)
PG_SETMASK(&BlockSig);
/*
- * DO NOT proc_exit() -- we're here because shared memory may be
- * corrupted, so we don't want to try to clean up our transaction. Just
- * nail the windows shut and get out of town.
- *
+ * We DO NOT want to run proc_exit() callbacks -- we're here because
+ * shared memory may be corrupted, so we don't want to try to clean up our
+ * transaction. Just nail the windows shut and get out of town. Now that
+ * there's an atexit callback to prevent third-party code from breaking
+ * things by calling exit() directly, we have to reset the callbacks
+ * explicitly to make this work as intended.
+ */
+ on_exit_reset();
+
+ /*
* Note we do exit(2) not exit(0). This is to force the postmaster into a
* system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
* backend. This is necessary precisely because we don't clean up our
- * shared memory state.
+ * shared memory state. (The "dead man switch" mechanism in pmsignal.c
+ * should ensure the postmaster sees this as a crash, too, but no harm
+ * in being doubly sure.)
*/
exit(2);
}
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 20a5d70748..ad7228144f 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -1337,14 +1337,22 @@ avl_quickdie(SIGNAL_ARGS)
PG_SETMASK(&BlockSig);
/*
- * DO NOT proc_exit() -- we're here because shared memory may be
- * corrupted, so we don't want to try to clean up our transaction. Just
- * nail the windows shut and get out of town.
- *
+ * We DO NOT want to run proc_exit() callbacks -- we're here because
+ * shared memory may be corrupted, so we don't want to try to clean up our
+ * transaction. Just nail the windows shut and get out of town. Now that
+ * there's an atexit callback to prevent third-party code from breaking
+ * things by calling exit() directly, we have to reset the callbacks
+ * explicitly to make this work as intended.
+ */
+ on_exit_reset();
+
+ /*
* Note we do exit(2) not exit(0). This is to force the postmaster into a
* system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
* backend. This is necessary precisely because we don't clean up our
- * shared memory state.
+ * shared memory state. (The "dead man switch" mechanism in pmsignal.c
+ * should ensure the postmaster sees this as a crash, too, but no harm
+ * in being doubly sure.)
*/
exit(2);
}
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 9d5dd8aa99..1189177800 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -798,14 +798,22 @@ bg_quickdie(SIGNAL_ARGS)
PG_SETMASK(&BlockSig);
/*
- * DO NOT proc_exit() -- we're here because shared memory may be
- * corrupted, so we don't want to try to clean up our transaction. Just
- * nail the windows shut and get out of town.
- *
+ * We DO NOT want to run proc_exit() callbacks -- we're here because
+ * shared memory may be corrupted, so we don't want to try to clean up our
+ * transaction. Just nail the windows shut and get out of town. Now that
+ * there's an atexit callback to prevent third-party code from breaking
+ * things by calling exit() directly, we have to reset the callbacks
+ * explicitly to make this work as intended.
+ */
+ on_exit_reset();
+
+ /*
* Note we do exit(2) not exit(0). This is to force the postmaster into a
* system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
* backend. This is necessary precisely because we don't clean up our
- * shared memory state.
+ * shared memory state. (The "dead man switch" mechanism in pmsignal.c
+ * should ensure the postmaster sees this as a crash, too, but no harm
+ * in being doubly sure.)
*/
exit(2);
}
diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
index 1760f49bc4..8d78e6dcd8 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -288,14 +288,22 @@ wal_quickdie(SIGNAL_ARGS)
PG_SETMASK(&BlockSig);
/*
- * DO NOT proc_exit() -- we're here because shared memory may be
- * corrupted, so we don't want to try to clean up our transaction. Just
- * nail the windows shut and get out of town.
- *
+ * We DO NOT want to run proc_exit() callbacks -- we're here because
+ * shared memory may be corrupted, so we don't want to try to clean up our
+ * transaction. Just nail the windows shut and get out of town. Now that
+ * there's an atexit callback to prevent third-party code from breaking
+ * things by calling exit() directly, we have to reset the callbacks
+ * explicitly to make this work as intended.
+ */
+ on_exit_reset();
+
+ /*
* Note we do exit(2) not exit(0). This is to force the postmaster into a
* system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
* backend. This is necessary precisely because we don't clean up our
- * shared memory state.
+ * shared memory state. (The "dead man switch" mechanism in pmsignal.c
+ * should ensure the postmaster sees this as a crash, too, but no harm
+ * in being doubly sure.)
*/
exit(2);
}
diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c
index 0242f4f916..459b4c686d 100644
--- a/src/backend/storage/ipc/ipc.c
+++ b/src/backend/storage/ipc/ipc.c
@@ -166,7 +166,8 @@ proc_exit_prepare(int code)
/* do our shared memory exits first */
shmem_exit(code);
- elog(DEBUG3, "proc_exit(%d)", code);
+ elog(DEBUG3, "proc_exit(%d): %d callbacks to make",
+ code, on_proc_exit_index);
/*
* call all the registered callbacks.
@@ -193,7 +194,8 @@ proc_exit_prepare(int code)
void
shmem_exit(int code)
{
- elog(DEBUG3, "shmem_exit(%d)", code);
+ elog(DEBUG3, "shmem_exit(%d): %d callbacks to make",
+ code, on_shmem_exit_index);
/*
* call all the registered callbacks.
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 3781b55be8..c880502f07 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -2495,14 +2495,22 @@ quickdie(SIGNAL_ARGS)
" database and repeat your command.")));
/*
- * DO NOT proc_exit() -- we're here because shared memory may be
- * corrupted, so we don't want to try to clean up our transaction. Just
- * nail the windows shut and get out of town.
- *
+ * We DO NOT want to run proc_exit() callbacks -- we're here because
+ * shared memory may be corrupted, so we don't want to try to clean up our
+ * transaction. Just nail the windows shut and get out of town. Now that
+ * there's an atexit callback to prevent third-party code from breaking
+ * things by calling exit() directly, we have to reset the callbacks
+ * explicitly to make this work as intended.
+ */
+ on_exit_reset();
+
+ /*
* Note we do exit(2) not exit(0). This is to force the postmaster into a
* system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
* backend. This is necessary precisely because we don't clean up our
- * shared memory state.
+ * shared memory state. (The "dead man switch" mechanism in pmsignal.c
+ * should ensure the postmaster sees this as a crash, too, but no harm
+ * in being doubly sure.)
*/
exit(2);
}
@@ -2554,7 +2562,7 @@ die(SIGNAL_ARGS)
void
authdie(SIGNAL_ARGS)
{
- exit(1);
+ proc_exit(1);
}
/*