Commit 4616d57d authored by Tom Lane's avatar Tom Lane

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.
parent abc92451
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.339 2009/05/14 21:28:35 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.340 2009/05/15 15:56:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -7790,14 +7790,22 @@ startupproc_quickdie(SIGNAL_ARGS) ...@@ -7790,14 +7790,22 @@ startupproc_quickdie(SIGNAL_ARGS)
PG_SETMASK(&BlockSig); PG_SETMASK(&BlockSig);
/* /*
* DO NOT proc_exit() -- we're here because shared memory may be * We DO NOT want to run proc_exit() callbacks -- we're here because
* corrupted, so we don't want to try to clean up our transaction. Just * shared memory may be corrupted, so we don't want to try to clean up our
* nail the windows shut and get out of town. * 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 * 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 * 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 * 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); exit(2);
} }
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.94 2009/03/31 22:12:48 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/autovacuum.c,v 1.95 2009/05/15 15:56:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1337,14 +1337,22 @@ avl_quickdie(SIGNAL_ARGS) ...@@ -1337,14 +1337,22 @@ avl_quickdie(SIGNAL_ARGS)
PG_SETMASK(&BlockSig); PG_SETMASK(&BlockSig);
/* /*
* DO NOT proc_exit() -- we're here because shared memory may be * We DO NOT want to run proc_exit() callbacks -- we're here because
* corrupted, so we don't want to try to clean up our transaction. Just * shared memory may be corrupted, so we don't want to try to clean up our
* nail the windows shut and get out of town. * 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 * 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 * 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 * 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); exit(2);
} }
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.57 2009/03/26 22:26:06 petere Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.58 2009/05/15 15:56:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -798,14 +798,22 @@ bg_quickdie(SIGNAL_ARGS) ...@@ -798,14 +798,22 @@ bg_quickdie(SIGNAL_ARGS)
PG_SETMASK(&BlockSig); PG_SETMASK(&BlockSig);
/* /*
* DO NOT proc_exit() -- we're here because shared memory may be * We DO NOT want to run proc_exit() callbacks -- we're here because
* corrupted, so we don't want to try to clean up our transaction. Just * shared memory may be corrupted, so we don't want to try to clean up our
* nail the windows shut and get out of town. * 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 * 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 * 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 * 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); exit(2);
} }
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/walwriter.c,v 1.5 2009/01/01 17:23:46 momjian Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/walwriter.c,v 1.6 2009/05/15 15:56:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -288,14 +288,22 @@ wal_quickdie(SIGNAL_ARGS) ...@@ -288,14 +288,22 @@ wal_quickdie(SIGNAL_ARGS)
PG_SETMASK(&BlockSig); PG_SETMASK(&BlockSig);
/* /*
* DO NOT proc_exit() -- we're here because shared memory may be * We DO NOT want to run proc_exit() callbacks -- we're here because
* corrupted, so we don't want to try to clean up our transaction. Just * shared memory may be corrupted, so we don't want to try to clean up our
* nail the windows shut and get out of town. * 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 * 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 * 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 * 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); exit(2);
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipc.c,v 1.103 2009/05/05 20:06:07 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/ipc/ipc.c,v 1.104 2009/05/15 15:56:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -166,7 +166,8 @@ proc_exit_prepare(int code) ...@@ -166,7 +166,8 @@ proc_exit_prepare(int code)
/* do our shared memory exits first */ /* do our shared memory exits first */
shmem_exit(code); 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. * call all the registered callbacks.
...@@ -193,7 +194,8 @@ proc_exit_prepare(int code) ...@@ -193,7 +194,8 @@ proc_exit_prepare(int code)
void void
shmem_exit(int code) 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. * call all the registered callbacks.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.565 2009/01/07 19:35:43 momjian Exp $ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.566 2009/05/15 15:56:39 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -2495,14 +2495,22 @@ quickdie(SIGNAL_ARGS) ...@@ -2495,14 +2495,22 @@ quickdie(SIGNAL_ARGS)
" database and repeat your command."))); " database and repeat your command.")));
/* /*
* DO NOT proc_exit() -- we're here because shared memory may be * We DO NOT want to run proc_exit() callbacks -- we're here because
* corrupted, so we don't want to try to clean up our transaction. Just * shared memory may be corrupted, so we don't want to try to clean up our
* nail the windows shut and get out of town. * 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 * 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 * 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 * 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); exit(2);
} }
...@@ -2554,7 +2562,7 @@ die(SIGNAL_ARGS) ...@@ -2554,7 +2562,7 @@ die(SIGNAL_ARGS)
void void
authdie(SIGNAL_ARGS) authdie(SIGNAL_ARGS)
{ {
exit(1); proc_exit(1);
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment