pgpool2.git / summary / log / commit / refs
commit 47564e79f7440a034e2ca83fc04cfb59219ca051
Author: Muhammad Usama <m.usama@gmail.com>
Date: Thu May 28 12:17:35 2015 +0000
Fixing a problem in elog.c when forwarding a message to frontend clients.
Error while forwarding the message to the frontend client can potentially cause
the infinite recursion and terminate the child with ERRORDATA_STACK_SIZE exceeded error.
Fix is to check the recursion depth of send_message_to_frontend() function
and pulling the plug if it is more than two levels deep.
src/utils/error/elog.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/utils/error/elog.c b/src/utils/error/elog.c
index 879863d5d..d9fc252a3 100644
--- a/src/utils/error/elog.c
+++ b/src/utils/error/elog.c
@@ -162,6 +162,8 @@ static int errordata_stack_depth = -1; /* index of topmost active frame */
static int recursion_depth = 0; /* to detect actual recursion */
+static int frontend_error_recursion_depth = 0; /* to detect recursion in delivering error to frontend clients */
+
/* Macro for checking errordata_stack_depth is reasonable */
#define CHECK_STACK_DEPTH() \
@@ -302,6 +304,7 @@ errstart(int elevel, const char *filename, int lineno,
if (in_error_recursion_trouble())
{
error_context_stack = NULL;
+ output_to_client = false;
}
}
if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE)
@@ -1225,6 +1228,7 @@ FlushErrorState(void)
*/
errordata_stack_depth = -1;
recursion_depth = 0;
+ frontend_error_recursion_depth = 0;
/* Delete all data in ErrorContext */
MemoryContextResetAndDeleteChildren(ErrorContext);
}
@@ -1730,6 +1734,11 @@ send_message_to_frontend(ErrorData *edata)
if (pool_frontend_exists() < 0 )
return;
+ /*
+ * Leave if we are failing on sending the message to frontend.
+ */
+ if (++frontend_error_recursion_depth > 2)
+ return;
if(processType == PT_CHILD)
{
@@ -1737,7 +1746,10 @@ send_message_to_frontend(ErrorData *edata)
* Do not forward the debug messages to client before session is initialized
*/
if (edata->elevel < ERROR && pool_get_session_context(true) == NULL)
+ {
+ frontend_error_recursion_depth--;
return;
+ }
protoVersion = get_frontend_protocol_version();
set_pg_frontend_blocking(false);
}
@@ -1835,6 +1847,8 @@ send_message_to_frontend(ErrorData *edata)
if (processType == PT_CHILD)
set_pg_frontend_blocking(true);
+
+ frontend_error_recursion_depth--;
}
/*
[parent: 23236af1976c]