Index: src/backend/utils/error/elog.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/error/elog.c,v retrieving revision 1.208 diff -c -r1.208 elog.c *** src/backend/utils/error/elog.c 17 Oct 2008 22:56:16 -0000 1.208 --- src/backend/utils/error/elog.c 27 Oct 2008 16:16:28 -0000 *************** *** 149,154 **** --- 149,169 ---- static void setup_formatted_log_time(void); static void setup_formatted_start_time(void); + + /* + * in_error_recursion_trouble --- are we at risk of infinite error recursion? + * + * This function exists to provide common control of various fallback steps + * that we take if we think we are facing infinite error recursion. See the + * callers for details. + */ + bool + in_error_recursion_trouble(void) + { + /* Pull the plug if recurse more than once */ + return (recursion_depth > 2); + } + /* * errstart --- begin an error-reporting cycle * *************** *** 261,272 **** MemoryContextReset(ErrorContext); /* ! * If we recurse more than once, the problem might be something broken * in a context traceback routine. Abandon them too. We also abandon * attempting to print the error statement (which, if long, could * itself be the source of the recursive failure). */ ! if (recursion_depth > 2) { error_context_stack = NULL; debug_query_string = NULL; --- 276,287 ---- MemoryContextReset(ErrorContext); /* ! * Infinite error recursion might be due to something broken * in a context traceback routine. Abandon them too. We also abandon * attempting to print the error statement (which, if long, could * itself be the source of the recursive failure). */ ! if (in_error_recursion_trouble()) { error_context_stack = NULL; debug_query_string = NULL; *************** *** 2408,2413 **** --- 2423,2432 ---- /* * error_severity --- get localized string representing elevel + * + * Note: in an error recursion situation, we stop localizing the tags + * for ERROR and above. This is necessary because the problem might be + * failure to convert one of these strings to the client encoding. */ static const char * error_severity(int elevel) *************** *** 2437,2449 **** prefix = _("WARNING"); break; case ERROR: ! prefix = _("ERROR"); break; case FATAL: ! prefix = _("FATAL"); break; case PANIC: ! prefix = _("PANIC"); break; default: prefix = "???"; --- 2456,2477 ---- prefix = _("WARNING"); break; case ERROR: ! if (in_error_recursion_trouble()) ! prefix = "ERROR"; ! else ! prefix = _("ERROR"); break; case FATAL: ! if (in_error_recursion_trouble()) ! prefix = "FATAL"; ! else ! prefix = _("FATAL"); break; case PANIC: ! if (in_error_recursion_trouble()) ! prefix = "PANIC"; ! else ! prefix = _("PANIC"); break; default: prefix = "???"; Index: src/backend/utils/mb/wchar.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/mb/wchar.c,v retrieving revision 1.66 diff -c -r1.66 wchar.c *** src/backend/utils/mb/wchar.c 15 Nov 2007 21:14:40 -0000 1.66 --- src/backend/utils/mb/wchar.c 27 Oct 2008 16:16:28 -0000 *************** *** 1567,1578 **** for (j = 0; j < jlimit; j++) p += sprintf(p, "%02x", (unsigned char) mbstr[j]); ! ereport(ERROR, ! (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER), ! errmsg("character 0x%s of encoding \"%s\" has no equivalent in \"%s\"", ! buf, ! pg_enc2name_tbl[src_encoding].name, ! pg_enc2name_tbl[dest_encoding].name))); } #endif --- 1567,1595 ---- for (j = 0; j < jlimit; j++) p += sprintf(p, "%02x", (unsigned char) mbstr[j]); ! /* ! * In an error recursion situation, don't try to translate the message. ! * This gets us out of trouble if the problem is failure to convert ! * the translated message to the client encoding. Note that we have to ! * spell the message slightly differently, which we do by sticking a ! * space on the end --- using errmsg_internal() doesn't actually keep ! * elog.c from calling gettext, it only prevents the string from being ! * entered into the translation lists. ! */ ! if (in_error_recursion_trouble()) ! ereport(ERROR, ! (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER), ! errmsg_internal("character 0x%s of encoding \"%s\" has no equivalent in \"%s\" ", ! buf, ! pg_enc2name_tbl[src_encoding].name, ! pg_enc2name_tbl[dest_encoding].name))); ! else ! ereport(ERROR, ! (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER), ! errmsg("character 0x%s of encoding \"%s\" has no equivalent in \"%s\"", ! buf, ! pg_enc2name_tbl[src_encoding].name, ! pg_enc2name_tbl[dest_encoding].name))); } #endif Index: src/include/utils/elog.h =================================================================== RCS file: /cvsroot/pgsql/src/include/utils/elog.h,v retrieving revision 1.96 diff -c -r1.96 elog.h *** src/include/utils/elog.h 9 Oct 2008 22:22:31 -0000 1.96 --- src/include/utils/elog.h 27 Oct 2008 16:16:28 -0000 *************** *** 324,329 **** --- 324,330 ---- /* Other exported functions */ extern void DebugFileOpen(void); extern char *unpack_sql_state(int sql_state); + extern bool in_error_recursion_trouble(void); #ifdef HAVE_SYSLOG extern void set_syslog_parameters(const char *ident, int facility);