Skip to content
Snippets Groups Projects
Commit 1a86e6ea authored by Tom Lane's avatar Tom Lane
Browse files

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
Branches
Tags
No related merge requests found
...@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment