From 7bda2a03d0d05034c122df22d476d7bb5c6acb09 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Thu, 19 Mar 2020 18:54:08 -0700 Subject: [PATCH v2 2/3] WIP: reimplement elog() using ereport(). Author: Andres Freund Discussion: https://postgr.es/m/5995.1584660775@sss.pgh.pa.us --- src/include/utils/elog.h | 31 +--------- src/backend/utils/error/elog.c | 103 --------------------------------- 2 files changed, 1 insertion(+), 133 deletions(-) diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 241457f35bd..8404760ae39 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -215,37 +215,8 @@ extern int getinternalerrposition(void); * elog(ERROR, "portal \"%s\" not found", stmt->portalname); *---------- */ -/* - * Using variadic macros, we can give the compiler a hint about the - * call not returning when elevel >= ERROR. See comments for ereport(). - * Note that historically elog() has called elog_start (which saves errno) - * before evaluating "elevel", so we preserve that behavior here. - */ -#ifdef HAVE__BUILTIN_CONSTANT_P #define elog(elevel, ...) \ - do { \ - pg_prevent_errno_in_scope(); \ - elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \ - elog_finish(elevel, __VA_ARGS__); \ - if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ - pg_unreachable(); \ - } while(0) -#else /* !HAVE__BUILTIN_CONSTANT_P */ -#define elog(elevel, ...) \ - do { \ - pg_prevent_errno_in_scope(); \ - elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \ - { \ - const int elevel_ = (elevel); \ - elog_finish(elevel_, __VA_ARGS__); \ - if (elevel_ >= ERROR) \ - pg_unreachable(); \ - } \ - } while(0) -#endif /* HAVE__BUILTIN_CONSTANT_P */ - -extern void elog_start(const char *filename, int lineno, const char *funcname); -extern void elog_finish(int elevel, const char *fmt,...) pg_attribute_printf(2, 3); + ereport(elevel, errmsg(__VA_ARGS__)) /* Support for constructing error strings separately from ereport() calls */ diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index dc1fda03a8f..141eddeeeba 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -1330,109 +1330,6 @@ getinternalerrposition(void) return edata->internalpos; } - -/* - * elog_start --- startup for old-style API - * - * All that we do here is stash the hidden filename/lineno/funcname - * arguments into a stack entry, along with the current value of errno. - * - * We need this to be separate from elog_finish because there's no other - * C89-compliant way to deal with inserting extra arguments into the elog - * call. (When using C99's __VA_ARGS__, we could possibly merge this with - * elog_finish, but there doesn't seem to be a good way to save errno before - * evaluating the format arguments if we do that.) - */ -void -elog_start(const char *filename, int lineno, const char *funcname) -{ - ErrorData *edata; - - /* Make sure that memory context initialization has finished */ - if (ErrorContext == NULL) - { - /* Oops, hard crash time; very little we can do safely here */ - write_stderr("error occurred at %s:%d before error message processing is available\n", - filename ? filename : "(unknown file)", lineno); - exit(2); - } - - if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE) - { - /* - * Wups, stack not big enough. We treat this as a PANIC condition - * because it suggests an infinite loop of errors during error - * recovery. Note that the message is intentionally not localized, - * else failure to convert it to client encoding could cause further - * recursion. - */ - errordata_stack_depth = -1; /* make room on stack */ - ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded"))); - } - - edata = &errordata[errordata_stack_depth]; - if (filename) - { - const char *slash; - - /* keep only base name, useful especially for vpath builds */ - slash = strrchr(filename, '/'); - if (slash) - filename = slash + 1; - } - edata->filename = filename; - edata->lineno = lineno; - edata->funcname = funcname; - /* errno is saved now so that error parameter eval can't change it */ - edata->saved_errno = errno; - - /* Use ErrorContext for any allocations done at this level. */ - edata->assoc_context = ErrorContext; -} - -/* - * elog_finish --- finish up for old-style API - */ -void -elog_finish(int elevel, const char *fmt,...) -{ - ErrorData *edata = &errordata[errordata_stack_depth]; - MemoryContext oldcontext; - - CHECK_STACK_DEPTH(); - - /* - * Do errstart() to see if we actually want to report the message. - */ - errordata_stack_depth--; - errno = edata->saved_errno; - if (!errstart(elevel, edata->filename, edata->lineno, edata->funcname, NULL)) - return; /* nothing to do */ - - /* - * Format error message just like errmsg_internal(). - */ - recursion_depth++; - oldcontext = MemoryContextSwitchTo(edata->assoc_context); - - if (!edata->backtrace && - edata->funcname && - matches_backtrace_functions(edata->funcname)) - set_backtrace(edata, 2); - - edata->message_id = fmt; - EVALUATE_MESSAGE(edata->domain, message, false, false); - - MemoryContextSwitchTo(oldcontext); - recursion_depth--; - - /* - * And let errfinish() finish up. - */ - errfinish(); -} - - /* * Functions to allow construction of error message strings separately from * the ereport() call itself. -- 2.25.0.114.g5b0ca878e0