From 5d7c52ffa6d5bce4d8dcca05d9918e46cafead6e Mon Sep 17 00:00:00 2001 From: Hadi Moshayedi Date: Wed, 3 Jan 2018 09:54:03 -0500 Subject: [PATCH] Don't return in PG_TRY() block when cancellations happen in WaitForConnections(). (#1923) We shouldn't return in middle of a PG_TRY() block because if we do, we won't reset PG_exception_stack, and later when a re-throw tries to jump to the jump-point which was active in this PG_TRY() block, it seg-faults. We used to return in middle of PG_TRY() block in WaitForConnections() where we checked for cancellations. Whenever cancellations were caught here, Citus crashed. And example was reported by @onderkalaci at #1903. --- .../distributed/connection/remote_commands.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/backend/distributed/connection/remote_commands.c b/src/backend/distributed/connection/remote_commands.c index a09aa877c..00bd0de81 100644 --- a/src/backend/distributed/connection/remote_commands.c +++ b/src/backend/distributed/connection/remote_commands.c @@ -781,6 +781,7 @@ WaitForAllConnections(List *connectionList, bool raiseInterrupts) while (pendingConnectionsStartIndex < totalConnectionCount) { + bool cancellationReceived = false; int eventIndex = 0; int eventCount = 0; long timeout = -1; @@ -837,9 +838,13 @@ WaitForAllConnections(List *connectionList, bool raiseInterrupts) if (InterruptHoldoffCount > 0 && (QueryCancelPending || ProcDiePending)) { - /* return immediately in case of cancellation */ - FreeWaitEventSet(waitEventSet); - return; + /* + * Break out of event loop immediately in case of cancellation. + * We cannot use "return" here inside a PG_TRY() block since + * then the exception stack won't be reset. + */ + cancellationReceived = true; + break; } continue; @@ -905,6 +910,11 @@ WaitForAllConnections(List *connectionList, bool raiseInterrupts) } } + if (cancellationReceived) + { + break; + } + /* move non-ready connections to the back of the array */ for (connectionIndex = pendingConnectionsStartIndex; connectionIndex < totalConnectionCount; connectionIndex++)