diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 2476bc40acb..02bad79a343 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -142,6 +142,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 00e27556a39..bdbb9990086 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -661,6 +661,7 @@ ProcKill(int code, Datum arg) { /* use volatile pointer to prevent code rearrangement */ volatile PROC_HDR *procglobal = ProcGlobal; + PGPROC *proc; Assert(MyProc != NULL); @@ -671,23 +672,28 @@ ProcKill(int code, Datum arg) */ LWLockReleaseAll(); + /* + * Clear MyProc first before after putting it back on the global list, + * so that signal handlers won't try to access it after it's no longer + * ours. + */ + proc = MyProc; + MyProc = NULL; + 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); @@ -716,6 +722,7 @@ AuxiliaryProcKill(int code, Datum arg) { int proctype = DatumGetInt32(arg); PGPROC *auxproc; + PGPROC *proc; Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS); @@ -726,13 +733,18 @@ AuxiliaryProcKill(int code, Datum arg) /* Release any LW locks I am holding (see notes above) */ LWLockReleaseAll(); + /* + * Clear MyProc first before after putting it back on the global list, + * so that signal handlers won't try to access it after it's no longer + * ours. + */ + proc = MyProc; + MyProc = NULL; + 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);