From 08ede423d1fefee039474303b31e3474c92eda9e Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 1 Dec 2000 19:52:04 +0000
Subject: [PATCH] Make elog() switch to ErrorContext while invoking libpq
 output routines, since those routines may do palloc's.  We want to be fairly
 sure we can send the error message to the client even under low-memory
 conditions. That's what we stashed away 8K in ErrorContext for, after all ...

---
 src/backend/utils/error/elog.c | 37 +++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index fcd8613a7dc..e6c19b246ef 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.69 2000/11/25 19:09:22 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.70 2000/12/01 19:52:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -30,12 +30,13 @@
 #include <syslog.h>
 #endif
 
+#include "commands/copy.h"
 #include "libpq/libpq.h"
 #include "libpq/pqformat.h"
 #include "miscadmin.h"
 #include "storage/proc.h"
 #include "tcop/tcopprot.h"
-#include "commands/copy.h"
+#include "utils/memutils.h"
 
 #ifdef MULTIBYTE
 #include "mb/pg_wchar.h"
@@ -374,8 +375,17 @@ elog(int lev, const char *fmt, ...)
 	if (lev > DEBUG && whereToSendOutput == Remote)
 	{
 		/* Send IPC message to the front-end program */
+		MemoryContext oldcxt;
 		char		msgtype;
 
+		/*
+		 * Since backend libpq may call palloc(), switch to a context where
+		 * there's fairly likely to be some free space.  After all the
+		 * pushups above, we don't want to drop the ball by running out of
+		 * space now...
+		 */
+		oldcxt = MemoryContextSwitchTo(ErrorContext);
+
 		if (lev == NOTICE)
 			msgtype = 'N';
 		else
@@ -402,6 +412,8 @@ elog(int lev, const char *fmt, ...)
 		 * much ...
 		 */
 		pq_flush();
+
+		MemoryContextSwitchTo(oldcxt);
 	}
 
 	if (lev > DEBUG && whereToSendOutput != Remote)
@@ -612,6 +624,7 @@ write_syslog(int level, const char *line)
 	static bool	openlog_done = false;
 	static unsigned long seq = 0;
 	static int	syslog_fac = LOG_LOCAL0;
+
 	int len = strlen(line);
 
 	if (Use_syslog == 0)
@@ -649,19 +662,21 @@ write_syslog(int level, const char *line)
 	/* or if the message contains embedded NewLine(s) '\n' */
 	if (len > PG_SYSLOG_LIMIT || strchr(line,'\n') != NULL )
 	{
-		static char	buf[PG_SYSLOG_LIMIT+1];
-		int chunk_nr = 0;
-		int buflen;
+		int		chunk_nr = 0;
 
 		while (len > 0)
 		{
-			int l;
-			int i;
+			char	buf[PG_SYSLOG_LIMIT+1];
+			int		buflen;
+			int		l;
+			int		i;
+
 			/* if we start at a newline, move ahead one char */
 			if (line[0] == '\n')
 			{
 				line++;
 				len--;
+				continue;
 			}
 
 			strncpy(buf, line, PG_SYSLOG_LIMIT);
@@ -681,9 +696,9 @@ write_syslog(int level, const char *line)
 				buflen = l;
 			else
 			{
-				/* try to divide in word boundary */
+				/* try to divide at word boundary */
 				i = l - 1;
-				while(i > 0 && !isspace(buf[i]))
+				while (i > 0 && !isspace(buf[i]))
 					i--;
 
 				if (i <= 0)	/* couldn't divide word boundary */
@@ -702,9 +717,11 @@ write_syslog(int level, const char *line)
 			len -= buflen;
 		}
 	}
-	/* message short enough */
 	else
+	{
+		/* message short enough */
 		syslog(level, "[%lu] %s", seq, line);
+	}
 }
 
 #endif /* ENABLE_SYSLOG */
-- 
GitLab