Skip to content

Commit 458b20f

Browse files
committed
Clear MyProc and MyProcSignalState before they become invalid.
Evidence from buildfarm member crake suggests that the new test_shm_mq module is routinely crashing the server due to the arrival of a SIGUSR1 after the shared memory segment has been unmapped. Although processes using the new dynamic background worker facilities are more likely to receive a SIGUSR1 around this time, the problem is also possible on older branches, so I'm back-patching the parts of this change that apply to older branches as far as they apply. It's already generally the case that code checks whether these pointers are NULL before deferencing them, so the important thing is mostly to make sure that they do get set to NULL before they become invalid. But in master, there's one case in procsignal_sigusr1_handler that lacks a NULL guard, so add that. Patch by me; review by Tom Lane.
1 parent 01b882f commit 458b20f

File tree

1 file changed

+23
-11
lines changed
  • src/backend/storage/lmgr

1 file changed

+23
-11
lines changed

src/backend/storage/lmgr/proc.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ ProcKill(int code, Datum arg)
591591
{
592592
/* use volatile pointer to prevent code rearrangement */
593593
volatile PROC_HDR *procglobal = ProcGlobal;
594+
PGPROC *proc;
594595

595596
Assert(MyProc != NULL);
596597

@@ -601,23 +602,28 @@ ProcKill(int code, Datum arg)
601602
*/
602603
LWLockReleaseAll();
603604

605+
/*
606+
* Clear MyProc first before after putting it back on the global list,
607+
* so that signal handlers won't try to access it after it's no longer
608+
* ours.
609+
*/
610+
proc = MyProc;
611+
MyProc = NULL;
612+
604613
SpinLockAcquire(ProcStructLock);
605614

606615
/* Return PGPROC structure (and semaphore) to freelist */
607616
if (IsAutoVacuumWorkerProcess())
608617
{
609-
MyProc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs;
610-
procglobal->autovacFreeProcs = MyProc;
618+
proc->links.next = (SHM_QUEUE *) procglobal->autovacFreeProcs;
619+
procglobal->autovacFreeProcs = proc;
611620
}
612621
else
613622
{
614-
MyProc->links.next = (SHM_QUEUE *) procglobal->freeProcs;
615-
procglobal->freeProcs = MyProc;
623+
proc->links.next = (SHM_QUEUE *) procglobal->freeProcs;
624+
procglobal->freeProcs = proc;
616625
}
617626

618-
/* PGPROC struct isn't mine anymore */
619-
MyProc = NULL;
620-
621627
/* Update shared estimate of spins_per_delay */
622628
procglobal->spins_per_delay = update_spins_per_delay(procglobal->spins_per_delay);
623629

@@ -645,6 +651,7 @@ AuxiliaryProcKill(int code, Datum arg)
645651
{
646652
int proctype = DatumGetInt32(arg);
647653
PGPROC *auxproc;
654+
PGPROC *proc;
648655

649656
Assert(proctype >= 0 && proctype < NUM_AUXILIARY_PROCS);
650657

@@ -655,13 +662,18 @@ AuxiliaryProcKill(int code, Datum arg)
655662
/* Release any LW locks I am holding (see notes above) */
656663
LWLockReleaseAll();
657664

665+
/*
666+
* Clear MyProc first before after putting it back on the global list,
667+
* so that signal handlers won't try to access it after it's no longer
668+
* ours.
669+
*/
670+
proc = MyProc;
671+
MyProc = NULL;
672+
658673
SpinLockAcquire(ProcStructLock);
659674

660675
/* Mark auxiliary proc no longer in use */
661-
MyProc->pid = 0;
662-
663-
/* PGPROC struct isn't mine anymore */
664-
MyProc = NULL;
676+
proc->pid = 0;
665677

666678
/* Update shared estimate of spins_per_delay */
667679
ProcGlobal->spins_per_delay = update_spins_per_delay(ProcGlobal->spins_per_delay);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy