From 51a0382e8d8793b5cc89b69285e5ecdffe03c2bf Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 28 Mar 2025 20:19:17 +0200 Subject: [PATCH] Fix crash if LockErrorCleanup() is called twice The refactoring in commit 3c0fd64fec removed the clearing of awaitedLock from LockErrorCleanup(). It's still needed, otherwise LockErrorCleanup() during abort processing will try to update the LOCALLOCK struct even after the lock has already been released. Put it back. Reported-by: Richard Guo Reported-by: Robins Tharakan Reported-by: Alexander Lakhin Discussion: https://www.postgresql.org/message-id/flat/CAMbWs4_dNX1SzBmvFdoY-LxJh_4W_BjtVd5i008ihfU-wFF=eg@mail.gmail.com Discussion: https://www.postgresql.org/message-id/18832-38e5575b1bbd7277@postgresql.org Discussion: https://www.postgresql.org/message-id/e11a30e5-c0d8-491d-8546-3a1b50c10ad4@gmail.com --- src/backend/storage/lmgr/lock.c | 9 +++++++++ src/backend/storage/lmgr/proc.c | 2 ++ src/include/storage/lock.h | 1 + 3 files changed, 12 insertions(+) diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 38a5d75bbe1..002303664aa 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -1896,6 +1896,15 @@ GetAwaitedLock(void) return awaitedLock; } +/* + * ResetAwaitedLock -- Forget that we are waiting on a lock. + */ +void +ResetAwaitedLock(void) +{ + awaitedLock = NULL; +} + /* * MarkLockClear -- mark an acquired lock as "clear" * diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index e4ca861a8e6..066319afe2b 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -814,6 +814,8 @@ LockErrorCleanup(void) GrantAwaitedLock(); } + ResetAwaitedLock(); + LWLockRelease(partitionLock); RESUME_INTERRUPTS(); diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index ad4e40badbe..6f2108a44e8 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -588,6 +588,7 @@ extern bool LockCheckConflicts(LockMethod lockMethodTable, extern void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode); extern void GrantAwaitedLock(void); extern LOCALLOCK *GetAwaitedLock(void); +extern void ResetAwaitedLock(void); extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode); extern LockData *GetLockStatusData(void);