diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 0f0d4dd48dffc394b368e675c5ac33f4db31bb84..b06074982ca0070d9e3db8468b939f60c089bba4 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -139,6 +139,13 @@ CleanupProcSignalState(int status, Datum arg) slot = &ProcSignalSlots[pss_idx - 1]; Assert(slot == MyProcSignalSlot); + /* + * Clear MyProcSignalSlot, so that a SIGUSR1 received after this point + * won't try to access it after it's no longer ours (and perhaps even + * after we've unmapped the shared memory segment). + */ + MyProcSignalSlot = NULL; + /* sanity check */ if (slot->pss_pid != MyProcPid) { diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 3bfdd237a29a361bb7fca0bd56d7cbd273e0de69..c27c48fc91f2e04076ac461db8648fbc9d29e3bb 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -760,6 +760,7 @@ ProcKill(int code, Datum arg) { /* use volatile pointer to prevent code rearrangement */ volatile PROC_HDR *procglobal = ProcGlobal; + PGPROC *proc; Assert(MyProc != NULL); @@ -784,26 +785,29 @@ ProcKill(int code, Datum arg) */ LWLockReleaseAll(); - /* Release ownership of the process's latch, too */ - DisownLatch(&MyProc->procLatch); + /* + * Clear MyProc first; then disown the process latch. This is so that + * signal handlers won't try to clear the process latch after it's no + * longer ours. + */ + proc = MyProc; + MyProc = NULL; + DisownLatch(&proc->procLatch); SpinLockAcquire(ProcStructLock); /* Return PGPROC structure (and semaphore) to appropriate freelist */ if (IsAnyAutoVacuumProcess()) { - MyProc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs; - procglobal->autovacFreeProcs = MyProc; + proc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs; + procglobal->autovacFreeProcs = proc; } else { - MyProc->links.next = (SHM_QUEUE *) procglobal->freeProcs; - procglobal->freeProcs = MyProc; + proc->links.next = (SHM_QUEUE *) procglobal->freeProcs; + procglobal->freeProcs = proc; } - /* PGPROC struct isn't mine anymore */ - MyProc = NULL; - /* Update shared estimate of spins_per_delay */ procglobal->spins_per_delay = update_spins_per_delay(procglobal->spins_per_delay); @@ -832,6 +836,7 @@ AuxiliaryProcKill(int code, Datum arg) { int proctype = DatumGetInt32(arg); PGPROC *auxproc PG_USED_FOR_ASSERTS_ONLY; + PGPROC *proc; Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS); @@ -842,16 +847,19 @@ AuxiliaryProcKill(int code, Datum arg) /* Release any LW locks I am holding (see notes above) */ LWLockReleaseAll(); - /* Release ownership of the process's latch, too */ - DisownLatch(&MyProc->procLatch); + /* + * Clear MyProc first; then disown the process latch. This is so that + * signal handlers won't try to clear the process latch after it's no + * longer ours. + */ + proc = MyProc; + MyProc = NULL; + DisownLatch(&proc->procLatch); SpinLockAcquire(ProcStructLock); /* Mark auxiliary proc no longer in use */ - MyProc->pid = 0; - - /* PGPROC struct isn't mine anymore */ - MyProc = NULL; + proc->pid = 0; /* Update shared estimate of spins_per_delay */ ProcGlobal->spins_per_delay = update_spins_per_delay(ProcGlobal->spins_per_delay);