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]