Turn the crashes on Windows into WARNINGs

pull/2090/head
Brian Cloutier 2018-04-12 19:20:37 -07:00 committed by Brian Cloutier
parent 18cb93c107
commit c5f1235090
1 changed files with 47 additions and 1 deletions

View File

@ -63,6 +63,7 @@ static void CoordinatedSubTransactionCallback(SubXactEvent event, SubTransaction
static void AdjustMaxPreparedTransactions(void); static void AdjustMaxPreparedTransactions(void);
static void PushSubXact(SubTransactionId subId); static void PushSubXact(SubTransactionId subId);
static void PopSubXact(SubTransactionId subId); static void PopSubXact(SubTransactionId subId);
static void SwallowErrors(void (*func)());
/* /*
@ -194,7 +195,7 @@ CoordinatedTransactionCallback(XactEvent event, void *arg)
* transaction management. Do so before doing other work, so the * transaction management. Do so before doing other work, so the
* callbacks still can perform work if needed. * callbacks still can perform work if needed.
*/ */
RemoveIntermediateResultsDirectory(); SwallowErrors(RemoveIntermediateResultsDirectory);
ResetShardPlacementTransactionState(); ResetShardPlacementTransactionState();
/* handles both already prepared and open transactions */ /* handles both already prepared and open transactions */
@ -423,3 +424,48 @@ ActiveSubXacts(void)
return activeSubXactsReversed; return activeSubXactsReversed;
} }
/*
* If an ERROR is thrown while processing a transaction the ABORT handler is called.
* ERRORS thrown during ABORT are not treated any differently, the ABORT handler is also
* called during processing of those. If an ERROR was raised the first time through it's
* unlikely that the second try will succeed; more likely that an ERROR will be thrown
* again. This loop continues until Postgres notices and PANICs, complaining about a stack
* overflow.
*
* Instead of looping and crashing, SwallowErrors lets us attempt to continue running the
* ABORT logic. This wouldn't be safe in most other parts of the codebase, in
* approximately none of the places where we emit ERROR do we first clean up after
* ourselves! It's fine inside the ABORT handler though; Postgres is going to clean
* everything up before control passes back to us.
*/
static void
SwallowErrors(void (*func)())
{
MemoryContext savedContext = CurrentMemoryContext;
PG_TRY();
{
func();
}
PG_CATCH();
{
ErrorData *edata = CopyErrorData();
/* don't try to intercept PANIC or FATAL, let those breeze past us */
if (edata->elevel != ERROR)
{
PG_RE_THROW();
}
/* turn the ERROR into a WARNING and emit it */
edata->elevel = WARNING;
ThrowErrorData(edata);
/* leave the error handling system */
FlushErrorState();
MemoryContextSwitchTo(savedContext);
}
PG_END_TRY();
}