Commit 1a86e6ea authored by Tom Lane's avatar Tom Lane

On further consideration, there's another problem here: the existing

elog() emulation code always calls errstart with ERROR error level.
This means that a recursive error call triggered by elog would do
MemoryContextReset(ErrorContext), whether or not this was actually
appropriate.  I'm surprised we haven't seen this in the field...
parent cefb4b14
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.149 2004/09/05 02:01:41 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.150 2004/09/05 03:42:11 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -862,10 +862,42 @@ getinternalerrposition(void) ...@@ -862,10 +862,42 @@ getinternalerrposition(void)
/* /*
* elog_finish --- finish up for old-style API * elog_start --- startup for old-style API
*
* All that we do here is stash the hidden filename/lineno/funcname
* arguments into a stack entry.
* *
* The elog() macro already called errstart, but with ERROR rather than * We need this to be separate from elog_finish because there's no other
* the true elevel. * portable way to deal with inserting extra arguments into the elog call.
* (If macros with variable numbers of arguments were portable, it'd be
* easy, but they aren't.)
*/
void
elog_start(const char *filename, int lineno, const char *funcname)
{
ErrorData *edata;
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.
*/
errordata_stack_depth = -1; /* make room on stack */
ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
}
edata = &errordata[errordata_stack_depth];
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;
}
/*
* elog_finish --- finish up for old-style API
*/ */
void void
elog_finish(int elevel, const char *fmt,...) elog_finish(int elevel, const char *fmt,...)
...@@ -876,8 +908,7 @@ elog_finish(int elevel, const char *fmt,...) ...@@ -876,8 +908,7 @@ elog_finish(int elevel, const char *fmt,...)
CHECK_STACK_DEPTH(); CHECK_STACK_DEPTH();
/* /*
* We need to redo errstart() because the elog macro had to call it * Do errstart() to see if we actually want to report the message.
* with bogus elevel.
*/ */
errordata_stack_depth--; errordata_stack_depth--;
errno = edata->saved_errno; errno = edata->saved_errno;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.75 2004/08/29 05:06:58 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.76 2004/09/05 03:42:13 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -153,8 +153,9 @@ extern int getinternalerrposition(void); ...@@ -153,8 +153,9 @@ extern int getinternalerrposition(void);
* elog(ERROR, "portal \"%s\" not found", stmt->portalname); * elog(ERROR, "portal \"%s\" not found", stmt->portalname);
*---------- *----------
*/ */
#define elog errstart(ERROR, __FILE__, __LINE__, PG_FUNCNAME_MACRO), elog_finish #define elog elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), elog_finish
extern void elog_start(const char *filename, int lineno, const char *funcname);
extern void extern void
elog_finish(int elevel, const char *fmt,...) elog_finish(int elevel, const char *fmt,...)
/* This extension allows gcc to check the format string for consistency with /* This extension allows gcc to check the format string for consistency with
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment