A race condition can make us try to dereference a NULL pointer to the
PGPROC struct of a process that's already finished. That results in
crashes during REINDEX CONCURRENTLY and CREATE INDEX CONCURRENTLY.
This was introduced in
ab0dfc961b6a, so backpatch to pg12.
Reported by: Justin Pryzby
Reviewed-by: Michaƫl Paquier
Discussion: https://postgr.es/m/
20191012004446.GT10470@telsasoft.com
if (VirtualTransactionIdIsValid(old_snapshots[i]))
{
+ /* If requested, publish who we're going to wait for. */
if (progress)
{
PGPROC *holder = BackendIdGetProc(old_snapshots[i].backendId);
- pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
- holder->pid);
+ if (holder)
+ pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
+ holder->pid);
}
VirtualXactLock(old_snapshots[i], true);
}
while (VirtualTransactionIdIsValid(*lockholders))
{
- /*
- * If requested, publish who we're going to wait for. This is not
- * 100% accurate if they're already gone, but we don't care.
- */
+ /* If requested, publish who we're going to wait for. */
if (progress)
{
PGPROC *holder = BackendIdGetProc(lockholders->backendId);
- pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
- holder->pid);
+ if (holder)
+ pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
+ holder->pid);
}
VirtualXactLock(*lockholders, true);
lockholders++;