public inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH v2 1/1] Simplify COPY FROM parsing by forcing lookahead.
12+ messages / 7 participants
[nested] [flat]

* [PATCH v2 1/1] Simplify COPY FROM parsing by forcing lookahead.
@ 2021-03-04 09:10  Heikki Linnakangas <[email protected]>
  0 siblings, 0 replies; 12+ messages in thread

From: Heikki Linnakangas @ 2021-03-04 09:10 UTC (permalink / raw)

Now that we don't support the old-style COPY protocol anymore, we can
force four bytes of lookahead like was suggested in an existing comment,
and simplify the loop in CopyReadLineText().

Discussion: https://www.postgresql.org/message-id/9ec25819-0a8a-d51a-17dc-4150bb3cca3b%40iki.fi
---
 src/backend/commands/copyfromparse.c     | 119 ++++++++---------------
 src/include/commands/copyfrom_internal.h |   3 +-
 2 files changed, 40 insertions(+), 82 deletions(-)

diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c
index ce24a1528bd..c2efe7e0782 100644
--- a/src/backend/commands/copyfromparse.c
+++ b/src/backend/commands/copyfromparse.c
@@ -46,21 +46,6 @@
  * empty statements.  See http://www.cit.gu.edu.au/~anthony/info/C/C.macros.
  */
 
-/*
- * This keeps the character read at the top of the loop in the buffer
- * even if there is more than one read-ahead.
- */
-#define IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(extralen) \
-if (1) \
-{ \
-	if (raw_buf_ptr + (extralen) >= copy_buf_len && !hit_eof) \
-	{ \
-		raw_buf_ptr = prev_raw_ptr; /* undo fetch */ \
-		need_data = true; \
-		continue; \
-	} \
-} else ((void) 0)
-
 /* This consumes the remainder of the buffer and breaks */
 #define IF_NEED_REFILL_AND_EOF_BREAK(extralen) \
 if (1) \
@@ -118,7 +103,7 @@ static int	CopyGetData(CopyFromState cstate, void *databuf,
 						int minread, int maxread);
 static inline bool CopyGetInt32(CopyFromState cstate, int32 *val);
 static inline bool CopyGetInt16(CopyFromState cstate, int16 *val);
-static bool CopyLoadRawBuf(CopyFromState cstate);
+static bool CopyLoadRawBuf(CopyFromState cstate, int minread);
 static int	CopyReadBinaryData(CopyFromState cstate, char *dest, int nbytes);
 
 void
@@ -209,7 +194,7 @@ CopyGetData(CopyFromState cstate, void *databuf, int minread, int maxread)
 				ereport(ERROR,
 						(errcode_for_file_access(),
 						 errmsg("could not read from COPY file: %m")));
-			if (bytesread == 0)
+			if (bytesread < maxread)
 				cstate->reached_eof = true;
 			break;
 		case COPY_FRONTEND:
@@ -278,6 +263,8 @@ CopyGetData(CopyFromState cstate, void *databuf, int minread, int maxread)
 			break;
 		case COPY_CALLBACK:
 			bytesread = cstate->data_source_cb(databuf, minread, maxread);
+			if (bytesread < minread)
+				cstate->reached_eof = true;
 			break;
 	}
 
@@ -329,14 +316,13 @@ CopyGetInt16(CopyFromState cstate, int16 *val)
 /*
  * CopyLoadRawBuf loads some more data into raw_buf
  *
- * Returns true if able to obtain at least one more byte, else false.
+ * Returns true if able to obtain at least 'minread' bytes, else false.
  *
  * If RAW_BUF_BYTES(cstate) > 0, the unprocessed bytes are moved to the start
- * of the buffer and then we load more data after that.  This case occurs only
- * when a multibyte character crosses a bufferload boundary.
+ * of the buffer and then we load more data after that.
  */
 static bool
-CopyLoadRawBuf(CopyFromState cstate)
+CopyLoadRawBuf(CopyFromState cstate, int minread)
 {
 	int			nbytes = RAW_BUF_BYTES(cstate);
 	int			inbytes;
@@ -347,14 +333,15 @@ CopyLoadRawBuf(CopyFromState cstate)
 				nbytes);
 
 	inbytes = CopyGetData(cstate, cstate->raw_buf + nbytes,
-						  1, RAW_BUF_SIZE - nbytes);
+						  minread, RAW_BUF_SIZE - nbytes);
 	nbytes += inbytes;
 	cstate->raw_buf[nbytes] = '\0';
 	cstate->raw_buf_index = 0;
 	cstate->raw_buf_len = nbytes;
 	cstate->bytes_processed += inbytes;
 	pgstat_progress_update_param(PROGRESS_COPY_BYTES_PROCESSED, cstate->bytes_processed);
-	return (inbytes > 0);
+
+	return (inbytes >= minread);
 }
 
 /*
@@ -389,7 +376,7 @@ CopyReadBinaryData(CopyFromState cstate, char *dest, int nbytes)
 			/* Load more data if buffer is empty. */
 			if (RAW_BUF_BYTES(cstate) == 0)
 			{
-				if (!CopyLoadRawBuf(cstate))
+				if (!CopyLoadRawBuf(cstate, 1))
 					break;		/* EOF */
 			}
 
@@ -678,7 +665,7 @@ CopyReadLine(CopyFromState cstate)
 			do
 			{
 				cstate->raw_buf_index = cstate->raw_buf_len;
-			} while (CopyLoadRawBuf(cstate));
+			} while (CopyLoadRawBuf(cstate, 1));
 		}
 	}
 	else
@@ -747,7 +734,6 @@ CopyReadLineText(CopyFromState cstate)
 	char	   *copy_raw_buf;
 	int			raw_buf_ptr;
 	int			copy_buf_len;
-	bool		need_data = false;
 	bool		hit_eof = false;
 	bool		result = false;
 	char		mblen_str[2];
@@ -794,6 +780,7 @@ CopyReadLineText(CopyFromState cstate)
 	copy_raw_buf = cstate->raw_buf;
 	raw_buf_ptr = cstate->raw_buf_index;
 	copy_buf_len = cstate->raw_buf_len;
+	hit_eof = cstate->reached_eof;
 
 	for (;;)
 	{
@@ -801,38 +788,40 @@ CopyReadLineText(CopyFromState cstate)
 		char		c;
 
 		/*
-		 * Load more data if needed.  Ideally we would just force four bytes
-		 * of read-ahead and avoid the many calls to
-		 * IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(), but the COPY_OLD_FE protocol
-		 * does not allow us to read too far ahead or we might read into the
-		 * next data, so we read-ahead only as far we know we can.  One
-		 * optimization would be to read-ahead four byte here if
-		 * cstate->copy_src != COPY_OLD_FE, but it hardly seems worth it,
-		 * considering the size of the buffer.
+		 * Load more data if needed.
+		 *
+		 * We need to look ahead max three bytes in one iteration of the loop
+		 * (for the sequence \.<CR><NL>), so make sure we have at least four
+		 * bytes in the buffer.  Note that we always guarantee that there is
+		 * one \0 in the buffer, after last valid byte; the lookaheads below
+		 * rely on that.
 		 */
-		if (raw_buf_ptr >= copy_buf_len || need_data)
+#define COPY_READ_LINE_LOOKAHEAD	4
+		if (raw_buf_ptr + COPY_READ_LINE_LOOKAHEAD >= copy_buf_len)
 		{
-			REFILL_LINEBUF;
+			if (!hit_eof)
+			{
+				REFILL_LINEBUF;
 
-			/*
-			 * Try to read some more data.  This will certainly reset
-			 * raw_buf_index to zero, and raw_buf_ptr must go with it.
-			 */
-			if (!CopyLoadRawBuf(cstate))
-				hit_eof = true;
-			raw_buf_ptr = 0;
-			copy_buf_len = cstate->raw_buf_len;
+				/*
+				 * Try to read some more data.  This will certainly reset
+				 * raw_buf_index to zero, and raw_buf_ptr must go with it.
+				 */
+				if (!CopyLoadRawBuf(cstate, COPY_READ_LINE_LOOKAHEAD))
+					hit_eof = true;
+				raw_buf_ptr = 0;
+				copy_buf_len = cstate->raw_buf_len;
+			}
 
 			/*
 			 * If we are completely out of data, break out of the loop,
 			 * reporting EOF.
 			 */
-			if (copy_buf_len <= 0)
+			if (copy_buf_len - raw_buf_ptr <= 0)
 			{
 				result = true;
 				break;
 			}
-			need_data = false;
 		}
 
 		/* OK to fetch a character */
@@ -841,20 +830,6 @@ CopyReadLineText(CopyFromState cstate)
 
 		if (cstate->opts.csv_mode)
 		{
-			/*
-			 * If character is '\\' or '\r', we may need to look ahead below.
-			 * Force fetch of the next character if we don't already have it.
-			 * We need to do this before changing CSV state, in case one of
-			 * these characters is also the quote or escape character.
-			 *
-			 * Note: old-protocol does not like forced prefetch, but it's OK
-			 * here since we cannot validly be at EOF.
-			 */
-			if (c == '\\' || c == '\r')
-			{
-				IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
-			}
-
 			/*
 			 * Dealing with quotes and escapes here is mildly tricky. If the
 			 * quote char is also the escape char, there's no problem - we
@@ -888,14 +863,9 @@ CopyReadLineText(CopyFromState cstate)
 				cstate->eol_type == EOL_CRNL)
 			{
 				/*
-				 * If need more data, go back to loop top to load it.
-				 *
-				 * Note that if we are at EOF, c will wind up as '\0' because
-				 * of the guaranteed pad of raw_buf.
+				 * Look at the next character.  If we're at EOF, c2 will wind
+				 * up as '\0' because of the guaranteed pad of raw_buf.
 				 */
-				IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
-
-				/* get next char */
 				c = copy_raw_buf[raw_buf_ptr];
 
 				if (c == '\n')
@@ -961,7 +931,6 @@ CopyReadLineText(CopyFromState cstate)
 		{
 			char		c2;
 
-			IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
 			IF_NEED_REFILL_AND_EOF_BREAK(0);
 
 			/* -----
@@ -976,16 +945,9 @@ CopyReadLineText(CopyFromState cstate)
 			{
 				raw_buf_ptr++;	/* consume the '.' */
 
-				/*
-				 * Note: if we loop back for more data here, it does not
-				 * matter that the CSV state change checks are re-executed; we
-				 * will come back here with no important state changed.
-				 */
 				if (cstate->eol_type == EOL_CRNL)
 				{
-					/* Get the next character */
-					IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
-					/* if hit_eof, c2 will become '\0' */
+					/* Get next character.  If hit_eof, c2 will become '\0' */
 					c2 = copy_raw_buf[raw_buf_ptr++];
 
 					if (c2 == '\n')
@@ -1008,9 +970,7 @@ CopyReadLineText(CopyFromState cstate)
 					}
 				}
 
-				/* Get the next character */
-				IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
-				/* if hit_eof, c2 will become '\0' */
+				/* Get next character.  If hit_eof, c2 will become '\0' */
 				c2 = copy_raw_buf[raw_buf_ptr++];
 
 				if (c2 != '\r' && c2 != '\n')
@@ -1095,7 +1055,6 @@ not_end_of_copy:
 			mblen_str[0] = c;
 			mblen = pg_encoding_mblen(cstate->file_encoding, mblen_str);
 
-			IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(mblen - 1);
 			IF_NEED_REFILL_AND_EOF_BREAK(mblen - 1);
 			raw_buf_ptr += mblen - 1;
 		}
diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h
index 705f5b615be..c088c4facdb 100644
--- a/src/include/commands/copyfrom_internal.h
+++ b/src/include/commands/copyfrom_internal.h
@@ -70,8 +70,7 @@ typedef struct CopyFromStateData
 	CopySource	copy_src;		/* type of copy source */
 	FILE	   *copy_file;		/* used if copy_src == COPY_FILE */
 	StringInfo	fe_msgbuf;		/* used if copy_src == COPY_NEW_FE */
-	bool		reached_eof;	/* true if we read to end of copy data (not
-								 * all copy_src types maintain this) */
+	bool		reached_eof;	/* true if we read to end of copy data */
 
 	EolType		eol_type;		/* EOL type of input */
 	int			file_encoding;	/* file or remote side's character encoding */
-- 
2.30.1


--------------5F54C02640018A10FACC0C96--





^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* pgsql: Add function to log the memory contexts of specified backend pro
@ 2021-04-06 04:45  Fujii Masao <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Fujii Masao @ 2021-04-06 04:45 UTC (permalink / raw)
  To: [email protected]

Add function to log the memory contexts of specified backend process.

Commit 3e98c0bafb added pg_backend_memory_contexts view to display
the memory contexts of the backend process. However its target process
is limited to the backend that is accessing to the view. So this is
not so convenient when investigating the local memory bloat of other
backend process. To improve this situation, this commit adds
pg_log_backend_memory_contexts() function that requests to log
the memory contexts of the specified backend process.

This information can be also collected by calling
MemoryContextStats(TopMemoryContext) via a debugger. But
this technique cannot be used in some environments because no debugger
is available there. So, pg_log_backend_memory_contexts() allows us to
see the memory contexts of specified backend more easily.

Only superusers are allowed to request to log the memory contexts
because allowing any users to issue this request at an unbounded rate
would cause lots of log messages and which can lead to denial of service.

On receipt of the request, at the next CHECK_FOR_INTERRUPTS(),
the target backend logs its memory contexts at LOG_SERVER_ONLY level,
so that these memory contexts will appear in the server log but not
be sent to the client. It logs one message per memory context.
Because if it buffers all memory contexts into StringInfo to log them
as one message, which may require the buffer to be enlarged very much
and lead to OOM error since there can be a large number of memory
contexts in a backend.

When a backend process is consuming huge memory, logging all its
memory contexts might overrun available disk space. To prevent this,
now this patch limits the number of child contexts to log per parent
to 100. As with MemoryContextStats(), it supposes that practical cases
where the log gets long will typically be huge numbers of siblings
under the same parent context; while the additional debugging value
from seeing details about individual siblings beyond 100 will not be large.

There was another proposed patch to add the function to return
the memory contexts of specified backend as the result sets,
instead of logging them, in the discussion. However that patch is
not included in this commit because it had several issues to address.

Thanks to Tatsuhito Kasahara, Andres Freund, Tom Lane, Tomas Vondra,
Michael Paquier, Kyotaro Horiguchi and Zhihong Yu for the discussion.

Bump catalog version.

Author: Atsushi Torikoshi
Reviewed-by: Kyotaro Horiguchi, Zhihong Yu, Fujii Masao
Discussion: https://postgr.es/m/[email protected]

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/43620e328617c1f41a2a54c8cee01723064e3ffa

Modified Files
--------------
doc/src/sgml/func.sgml                       |  52 ++++++++
src/backend/storage/ipc/procsignal.c         |   4 +
src/backend/tcop/postgres.c                  |   3 +
src/backend/utils/adt/mcxtfuncs.c            |  60 ++++++++-
src/backend/utils/init/globals.c             |   1 +
src/backend/utils/mmgr/aset.c                |   8 +-
src/backend/utils/mmgr/generation.c          |   8 +-
src/backend/utils/mmgr/mcxt.c                | 180 ++++++++++++++++++++++-----
src/backend/utils/mmgr/slab.c                |   9 +-
src/include/catalog/catversion.h             |   2 +-
src/include/catalog/pg_proc.dat              |   6 +
src/include/miscadmin.h                      |   1 +
src/include/nodes/memnodes.h                 |   6 +-
src/include/storage/procsignal.h             |   1 +
src/include/utils/memutils.h                 |   5 +-
src/test/regress/expected/misc_functions.out |  13 ++
src/test/regress/sql/misc_functions.sql      |   9 ++
17 files changed, 320 insertions(+), 48 deletions(-)



^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: pgsql: Add function to log the memory contexts of specified backend pro
@ 2025-05-01 07:53  Fujii Masao <[email protected]>
  parent: Fujii Masao <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Fujii Masao @ 2025-05-01 07:53 UTC (permalink / raw)
  To: Robert Haas <[email protected]>; Fujii Masao <[email protected]>; +Cc: PostgreSQL Hackers <[email protected]>



On 2025/05/01 2:15, Robert Haas wrote:
> On Tue, Apr 6, 2021 at 12:45 AM Fujii Masao <[email protected]> wrote:
>> Add function to log the memory contexts of specified backend process.
> 
> Hi,
> 
> I think this might need a recursion guard. I tried this:
> 
> diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
> index dc4c600922d..b219a934034 100644
> --- a/src/backend/tcop/postgres.c
> +++ b/src/backend/tcop/postgres.c
> @@ -3532,7 +3532,7 @@ ProcessInterrupts(void)
>       if (ParallelMessagePending)
>           ProcessParallelMessages();
> 
> -    if (LogMemoryContextPending)
> +    if (true)
>           ProcessLogMemoryContextInterrupt();
> 
>       if (PublishMemoryContextPending)
> diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
> index 72f5655fb34..867fd7b0ad5 100644
> --- a/src/include/miscadmin.h
> +++ b/src/include/miscadmin.h
> @@ -112,7 +112,7 @@ extern void ProcessInterrupts(void);
>   /* Test whether an interrupt is pending */
>   #ifndef WIN32
>   #define INTERRUPTS_PENDING_CONDITION() \
> -    (unlikely(InterruptPending))
> +    (unlikely(InterruptPending) || true)
>   #else
>   #define INTERRUPTS_PENDING_CONDITION() \
>       (unlikely(UNBLOCKED_SIGNAL_QUEUE()) ?
> pgwin32_dispatch_queued_signals() : 0, \
> 
> That immediately caused infinite recursion, ending in a core dump:
> 
>      frame #13: 0x0000000104607b00
> postgres`errfinish(filename=<unavailable>, lineno=<unavailable>,
> funcname=<unavailable>) at elog.c:543:2 [opt]
>      frame #14: 0x0000000104637078
> postgres`ProcessLogMemoryContextInterrupt at mcxt.c:1392:2 [opt]
>      frame #15: 0x00000001044a901c postgres`ProcessInterrupts at
> postgres.c:3536:3 [opt]
>      frame #16: 0x0000000104607b54
> postgres`errfinish(filename=<unavailable>, lineno=<unavailable>,
> funcname=<unavailable>) at elog.c:608:2 [opt] [artificial]
>      frame #17: 0x0000000104637078
> postgres`ProcessLogMemoryContextInterrupt at mcxt.c:1392:2 [opt]
>      frame #18: 0x00000001044a901c postgres`ProcessInterrupts at
> postgres.c:3536:3 [opt]
> <repeat until we have 174241 frames on the stack, then dump core>
> 
> It might be unlikely that a process can be signalled fast enough to
> actually fail in this way, but I'm not sure it's impossible, and I
> think we should be defending against it. The most trivial recursion
> guard would be HOLD_INTERRUPTS()/RESUME_INTERRUPTS() around
> ProcessLogMemoryContextInterrupt(), but I think that's probably not
> quite good enough because it would make the backend impervious to
> pg_terminate_backend() while it's dumping memory contexts, and that
> could be a long time if the write blocks.

Just idea, what do you think about adding a flag to indicate whether
ProcessLogMemoryContextInterrupt() is currently running? Then,
when a backend receives a signal and ProcessLogMemoryContextInterrupt()
is invoked, it can simply return immediately if the flag is already set
like this:

------------------------------
@ -1383,8 +1383,14 @@ HandleGetMemoryContextInterrupt(void)
  void
  ProcessLogMemoryContextInterrupt(void)
  {
+       static bool     loggingMemoryContext = false;
+
         LogMemoryContextPending = false;
  
+       if (loggingMemoryContext)
+               return;
+       loggingMemoryContext = true;
+
         /*
          * Use LOG_SERVER_ONLY to prevent this message from being sent to the
          * connected client.
@@ -1406,6 +1412,8 @@ ProcessLogMemoryContextInterrupt(void)
          * details about individual siblings beyond 100 will not be large.
          */
         MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+
+       loggingMemoryContext = false;
  }
------------------------------

This way, we can safely ignore overlapping
pg_log_backend_memory_contexts() requests while the function
is already running. Thoughts?

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION






^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: pgsql: Add function to log the memory contexts of specified backend pro
@ 2025-05-02 00:02  Fujii Masao <[email protected]>
  parent: Fujii Masao <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Fujii Masao @ 2025-05-02 00:02 UTC (permalink / raw)
  To: Robert Haas <[email protected]>; +Cc: PostgreSQL Hackers <[email protected]>



On 2025/05/02 2:27, Fujii Masao wrote:
> 
> 
> On 2025/05/01 21:42, Robert Haas wrote:
>> On Thu, May 1, 2025 at 3:53 AM Fujii Masao <[email protected]> wrote:
>>> Just idea, what do you think about adding a flag to indicate whether
>>> ProcessLogMemoryContextInterrupt() is currently running? Then,
>>> when a backend receives a signal and ProcessLogMemoryContextInterrupt()
>>> is invoked, it can simply return immediately if the flag is already set
>>> like this:
>>
>> I think that something like this could work, but you would need more
>> than this. Otherwise, if the function errors out, the flag would
>> remain permanently set.
> 
> Yes, we need to either use PG_TRY()/PG_FINALLY() or handle the flag as
> a global variable and reset it in the error handling path. I think using
> PG_TRY()/PG_FINALLY() is the simpler option.

I've implemented the patch in that way. Patch attached.

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION

From 5a65280d10fec6e4c5577e26eeddeb10c9ddb13f Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Fri, 2 May 2025 00:35:48 +0900
Subject: [PATCH v1] Add guard to prevent recursive memory contexts logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory contexts logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory contexts logging was introduced.
---
 src/backend/utils/mmgr/mcxt.c | 61 +++++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 20 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 7d28ca706eb..907c7f7affe 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -1383,29 +1383,50 @@ HandleGetMemoryContextInterrupt(void)
 void
 ProcessLogMemoryContextInterrupt(void)
 {
+	static bool in_progress = false;
+
 	LogMemoryContextPending = false;
 
-	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
-	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	PG_TRY();
+	{
+		/*
+		 * Exit immediately if memory contexts logging is already in progress.
+		 * This prevents recursive calls, which could occur if logging is
+		 * requested  repeatedly and rapidly, potentially leading to infinite
+		 * recursion and a crash.
+		 */
+		if (in_progress)
+			return;
+		in_progress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the depth of the hierarchy, as well as the number of child contexts to
-	 * log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the depth of the hierarchy, as well as the number of
+		 * child contexts to log per parent to 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	}
+	PG_FINALLY();
+	{
+		in_progress = false;
+	}
+	PG_END_TRY();
 }
 
 /*
-- 
2.49.0



Attachments:

  [text/plain] v1-0001-Add-guard-to-prevent-recursive-memory-contexts-lo.patch (3.6K, ../../[email protected]/2-v1-0001-Add-guard-to-prevent-recursive-memory-contexts-lo.patch)
  download | inline diff:
From 5a65280d10fec6e4c5577e26eeddeb10c9ddb13f Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Fri, 2 May 2025 00:35:48 +0900
Subject: [PATCH v1] Add guard to prevent recursive memory contexts logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory contexts logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory contexts logging was introduced.
---
 src/backend/utils/mmgr/mcxt.c | 61 +++++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 20 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 7d28ca706eb..907c7f7affe 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -1383,29 +1383,50 @@ HandleGetMemoryContextInterrupt(void)
 void
 ProcessLogMemoryContextInterrupt(void)
 {
+	static bool in_progress = false;
+
 	LogMemoryContextPending = false;
 
-	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
-	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	PG_TRY();
+	{
+		/*
+		 * Exit immediately if memory contexts logging is already in progress.
+		 * This prevents recursive calls, which could occur if logging is
+		 * requested  repeatedly and rapidly, potentially leading to infinite
+		 * recursion and a crash.
+		 */
+		if (in_progress)
+			return;
+		in_progress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the depth of the hierarchy, as well as the number of child contexts to
-	 * log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the depth of the hierarchy, as well as the number of
+		 * child contexts to log per parent to 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	}
+	PG_FINALLY();
+	{
+		in_progress = false;
+	}
+	PG_END_TRY();
 }
 
 /*
-- 
2.49.0



^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: pgsql: Add function to log the memory contexts of specified backend pro
@ 2025-05-02 05:58  torikoshia <[email protected]>
  parent: Fujii Masao <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: torikoshia @ 2025-05-02 05:58 UTC (permalink / raw)
  To: Fujii Masao <[email protected]>; +Cc: Robert Haas <[email protected]>; PostgreSQL Hackers <[email protected]>

On 2025-05-02 09:02, Fujii Masao wrote:
> On 2025/05/02 2:27, Fujii Masao wrote:
>> 
>> 
>> On 2025/05/01 21:42, Robert Haas wrote:
>>> On Thu, May 1, 2025 at 3:53 AM Fujii Masao 
>>> <[email protected]> wrote:
>>>> Just idea, what do you think about adding a flag to indicate whether
>>>> ProcessLogMemoryContextInterrupt() is currently running? Then,
>>>> when a backend receives a signal and 
>>>> ProcessLogMemoryContextInterrupt()
>>>> is invoked, it can simply return immediately if the flag is already 
>>>> set
>>>> like this:
>>> 
>>> I think that something like this could work, but you would need more
>>> than this. Otherwise, if the function errors out, the flag would
>>> remain permanently set.
>> 
>> Yes, we need to either use PG_TRY()/PG_FINALLY() or handle the flag as
>> a global variable and reset it in the error handling path. I think 
>> using
>> PG_TRY()/PG_FINALLY() is the simpler option.
> 
> I've implemented the patch in that way. Patch attached.

Thank you for the patch!

I confirmed that with this patch applied, the process no longer crashes 
even after applying the change Robert used to trigger the crash.

a small nitpick:

+                * requested  repeatedly and rapidly, potentially 
leading to infinite

It looks like there are two spaces between "requested" and "repeatedly".


-- 
Regards,

--
Atsushi Torikoshi
Seconded from NTT DATA GROUP CORPORATION to SRA OSS K.K.





^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: pgsql: Add function to log the memory contexts of specified backend pro
@ 2025-05-03 01:53  Fujii Masao <[email protected]>
  parent: torikoshia <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Fujii Masao @ 2025-05-03 01:53 UTC (permalink / raw)
  To: torikoshia <[email protected]>; +Cc: Robert Haas <[email protected]>; PostgreSQL Hackers <[email protected]>



On 2025/05/02 14:58, torikoshia wrote:
> I confirmed that with this patch applied, the process no longer crashes even after applying the change Robert used to trigger the crash.
> 
> a small nitpick:
> 
> +                * requested  repeatedly and rapidly, potentially leading to infinite
> 
> It looks like there are two spaces between "requested" and "repeatedly".

Thanks for the review and testing! I've fixed the issue you pointed out.
Updated patch attached.

Since git cherry-pick didn't work cleanly for v16 and earlier,
I've also prepared a separate patch for those versions.

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION

From c39b3b83f8a04e781812bd3b83acb235babe3116 Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Sat, 3 May 2025 10:21:01 +0900
Subject: [PATCH v2] Add guard to prevent recursive memory contexts logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory contexts logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory contexts logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 60 ++++++++++++++++++++++++-----------
 1 file changed, 41 insertions(+), 19 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 9fc83f11f6f..73dcd64c351 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -1198,28 +1198,50 @@ HandleLogMemoryContextInterrupt(void)
 void
 ProcessLogMemoryContextInterrupt(void)
 {
+	static bool in_progress = false;
+
 	LogMemoryContextPending = false;
 
-	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
-	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	PG_TRY();
+	{
+		/*
+		 * Exit immediately if memory contexts logging is already in progress.
+		 * This prevents recursive calls, which could occur if logging is
+		 * requested repeatedly and rapidly, potentially leading to infinite
+		 * recursion and a crash.
+		 */
+		if (in_progress)
+			return;
+		in_progress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the number of child contexts to log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, false);
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the number of child contexts to log per parent to
+		 * 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, false);
+	}
+	PG_FINALLY();
+	{
+		in_progress = false;
+	}
+	PG_END_TRY();
 }
 
 void *
-- 
2.49.0


From 35bb669bcf1be12d7517b3cc993bcf519c0db361 Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Sat, 3 May 2025 10:21:01 +0900
Subject: [PATCH v2] Add guard to prevent recursive memory contexts logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory contexts logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory contexts logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 61 +++++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 20 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 7d28ca706eb..f0a8ccdfe12 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -1383,29 +1383,50 @@ HandleGetMemoryContextInterrupt(void)
 void
 ProcessLogMemoryContextInterrupt(void)
 {
+	static bool in_progress = false;
+
 	LogMemoryContextPending = false;
 
-	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
-	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	PG_TRY();
+	{
+		/*
+		 * Exit immediately if memory contexts logging is already in progress.
+		 * This prevents recursive calls, which could occur if logging is
+		 * requested repeatedly and rapidly, potentially leading to infinite
+		 * recursion and a crash.
+		 */
+		if (in_progress)
+			return;
+		in_progress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the depth of the hierarchy, as well as the number of child contexts to
-	 * log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the depth of the hierarchy, as well as the number of
+		 * child contexts to log per parent to 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	}
+	PG_FINALLY();
+	{
+		in_progress = false;
+	}
+	PG_END_TRY();
 }
 
 /*
-- 
2.49.0



Attachments:

  [text/plain] v2-0001-PG14-PG16-Add-guard-to-prevent-recursive-memory-contexts-lo.patch (3.8K, ../../[email protected]/2-v2-0001-PG14-PG16-Add-guard-to-prevent-recursive-memory-contexts-lo.patch)
  download | inline diff:
From c39b3b83f8a04e781812bd3b83acb235babe3116 Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Sat, 3 May 2025 10:21:01 +0900
Subject: [PATCH v2] Add guard to prevent recursive memory contexts logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory contexts logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory contexts logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 60 ++++++++++++++++++++++++-----------
 1 file changed, 41 insertions(+), 19 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 9fc83f11f6f..73dcd64c351 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -1198,28 +1198,50 @@ HandleLogMemoryContextInterrupt(void)
 void
 ProcessLogMemoryContextInterrupt(void)
 {
+	static bool in_progress = false;
+
 	LogMemoryContextPending = false;
 
-	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
-	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	PG_TRY();
+	{
+		/*
+		 * Exit immediately if memory contexts logging is already in progress.
+		 * This prevents recursive calls, which could occur if logging is
+		 * requested repeatedly and rapidly, potentially leading to infinite
+		 * recursion and a crash.
+		 */
+		if (in_progress)
+			return;
+		in_progress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the number of child contexts to log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, false);
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the number of child contexts to log per parent to
+		 * 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, false);
+	}
+	PG_FINALLY();
+	{
+		in_progress = false;
+	}
+	PG_END_TRY();
 }
 
 void *
-- 
2.49.0



  [text/plain] v2-0001-PG17-master-Add-guard-to-prevent-recursive-memory-contexts-lo.patch (3.9K, ../../[email protected]/3-v2-0001-PG17-master-Add-guard-to-prevent-recursive-memory-contexts-lo.patch)
  download | inline diff:
From 35bb669bcf1be12d7517b3cc993bcf519c0db361 Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Sat, 3 May 2025 10:21:01 +0900
Subject: [PATCH v2] Add guard to prevent recursive memory contexts logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory contexts logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory contexts logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 61 +++++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 20 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 7d28ca706eb..f0a8ccdfe12 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -1383,29 +1383,50 @@ HandleGetMemoryContextInterrupt(void)
 void
 ProcessLogMemoryContextInterrupt(void)
 {
+	static bool in_progress = false;
+
 	LogMemoryContextPending = false;
 
-	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
-	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	PG_TRY();
+	{
+		/*
+		 * Exit immediately if memory contexts logging is already in progress.
+		 * This prevents recursive calls, which could occur if logging is
+		 * requested repeatedly and rapidly, potentially leading to infinite
+		 * recursion and a crash.
+		 */
+		if (in_progress)
+			return;
+		in_progress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the depth of the hierarchy, as well as the number of child contexts to
-	 * log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the depth of the hierarchy, as well as the number of
+		 * child contexts to log per parent to 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	}
+	PG_FINALLY();
+	{
+		in_progress = false;
+	}
+	PG_END_TRY();
 }
 
 /*
-- 
2.49.0



^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: pgsql: Add function to log the memory contexts of specified backend pro
@ 2025-05-05 14:57  Robert Haas <[email protected]>
  parent: Fujii Masao <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Robert Haas @ 2025-05-05 14:57 UTC (permalink / raw)
  To: Fujii Masao <[email protected]>; +Cc: torikoshia <[email protected]>; PostgreSQL Hackers <[email protected]>

On Fri, May 2, 2025 at 9:54 PM Fujii Masao <[email protected]> wrote:
> Thanks for the review and testing! I've fixed the issue you pointed out.
> Updated patch attached.

Thanks for addressing this. However, I believe this commit may need to
take note of the following comment from elog.h:

 * Note: if a local variable of the function containing PG_TRY is modified
 * in the PG_TRY section and used in the PG_CATCH section, that variable
 * must be declared "volatile" for POSIX compliance.  This is not mere
 * pedantry; we have seen bugs from compilers improperly optimizing code
 * away when such a variable was not marked.  Beware that gcc's -Wclobbered
 * warnings are just about entirely useless for catching such oversights.

Based on this comment, I believe in_progress must be declared volatile.

As a stylistic comment, I think I would prefer making in_progress a
file-level global and giving it a less generic name (e.g.
LogMemoryContextInProgress). However, perhaps others will disagree.

-- 
Robert Haas
EDB: http://www.enterprisedb.com





^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: pgsql: Add function to log the memory contexts of specified backend pro
@ 2025-05-07 09:06  Fujii Masao <[email protected]>
  parent: Robert Haas <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Fujii Masao @ 2025-05-07 09:06 UTC (permalink / raw)
  To: Robert Haas <[email protected]>; +Cc: torikoshia <[email protected]>; PostgreSQL Hackers <[email protected]>



On 2025/05/05 23:57, Robert Haas wrote:
> On Fri, May 2, 2025 at 9:54 PM Fujii Masao <[email protected]> wrote:
>> Thanks for the review and testing! I've fixed the issue you pointed out.
>> Updated patch attached.
> 
> Thanks for addressing this. However, I believe this commit may need to
> take note of the following comment from elog.h:

Thanks for the review!


>   * Note: if a local variable of the function containing PG_TRY is modified
>   * in the PG_TRY section and used in the PG_CATCH section, that variable
>   * must be declared "volatile" for POSIX compliance.  This is not mere
>   * pedantry; we have seen bugs from compilers improperly optimizing code
>   * away when such a variable was not marked.  Beware that gcc's -Wclobbered
>   * warnings are just about entirely useless for catching such oversights.
> 
> Based on this comment, I believe in_progress must be declared volatile.

You're right. OTOH, setting the flag inside the PG_TRY() block isn't necessary,
so I've moved it outside instead of leaving it inside and marking the flag volatile.


> As a stylistic comment, I think I would prefer making in_progress a
> file-level global and giving it a less generic name (e.g.
> LogMemoryContextInProgress). However, perhaps others will disagree.

I'm fine with this. I've renamed the flag and made it a file-level global
variable as suggested. Updated patch is attached.

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION

From c5870f8b41118d1208d111101b9a360f1abc7e53 Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Wed, 7 May 2025 17:45:02 +0900
Subject: [PATCH v3] Add guard to prevent recursive memory context logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory context logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory context logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Reviewed-by: Robert Haas <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 57 ++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 9fc83f11f6f..30286a3ff33 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -149,6 +149,9 @@ MemoryContext CurTransactionContext = NULL;
 /* This is a transient link to the active portal's memory context: */
 MemoryContext PortalContext = NULL;
 
+/* Is memory context logging currently in progress? */
+static bool LogMemoryContextInProgress = false;
+
 static void MemoryContextCallResetCallbacks(MemoryContext context);
 static void MemoryContextStatsInternal(MemoryContext context, int level,
 									   bool print, int max_children,
@@ -1201,25 +1204,45 @@ ProcessLogMemoryContextInterrupt(void)
 	LogMemoryContextPending = false;
 
 	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
+	 * Exit immediately if memory context logging is already in progress. This
+	 * prevents recursive calls, which could occur if logging is requested
+	 * repeatedly and rapidly, potentially leading to infinite recursion and a
+	 * crash.
 	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	if (LogMemoryContextInProgress)
+		return;
+	LogMemoryContextInProgress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the number of child contexts to log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, false);
+	PG_TRY();
+	{
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the number of child contexts to log per parent to
+		 * 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, false);
+	}
+	PG_FINALLY();
+	{
+		LogMemoryContextInProgress = false;
+	}
+	PG_END_TRY();
 }
 
 void *
-- 
2.49.0


From 92a0fc0397831849f6e1443b010733a69e1d4b1d Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Wed, 7 May 2025 16:49:31 +0900
Subject: [PATCH v3] Add guard to prevent recursive memory context logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory context logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory context logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Reviewed-by: Robert Haas <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 58 ++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 7d28ca706eb..4690d039011 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -174,6 +174,9 @@ MemoryContext CurTransactionContext = NULL;
 MemoryContext PortalContext = NULL;
 dsa_area   *MemoryStatsDsaArea = NULL;
 
+/* Is memory context logging currently in progress? */
+static bool LogMemoryContextInProgress = false;
+
 static void MemoryContextDeleteOnly(MemoryContext context);
 static void MemoryContextCallResetCallbacks(MemoryContext context);
 static void MemoryContextStatsInternal(MemoryContext context, int level,
@@ -1386,26 +1389,45 @@ ProcessLogMemoryContextInterrupt(void)
 	LogMemoryContextPending = false;
 
 	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
+	 * Exit immediately if memory context logging is already in progress. This
+	 * prevents recursive calls, which could occur if logging is requested
+	 * repeatedly and rapidly, potentially leading to infinite recursion and a
+	 * crash.
 	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	if (LogMemoryContextInProgress)
+		return;
+	LogMemoryContextInProgress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the depth of the hierarchy, as well as the number of child contexts to
-	 * log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	PG_TRY();
+	{
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the depth of the hierarchy, as well as the number of
+		 * child contexts to log per parent to 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	}
+	PG_FINALLY();
+	{
+		LogMemoryContextInProgress = false;
+	}
+	PG_END_TRY();
 }
 
 /*
-- 
2.49.0



Attachments:

  [text/plain] v3-0001-PG14-PG16-Add-guard-to-prevent-recursive-memory-context-log.patch (4.2K, ../../[email protected]/2-v3-0001-PG14-PG16-Add-guard-to-prevent-recursive-memory-context-log.patch)
  download | inline diff:
From c5870f8b41118d1208d111101b9a360f1abc7e53 Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Wed, 7 May 2025 17:45:02 +0900
Subject: [PATCH v3] Add guard to prevent recursive memory context logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory context logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory context logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Reviewed-by: Robert Haas <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 57 ++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 9fc83f11f6f..30286a3ff33 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -149,6 +149,9 @@ MemoryContext CurTransactionContext = NULL;
 /* This is a transient link to the active portal's memory context: */
 MemoryContext PortalContext = NULL;
 
+/* Is memory context logging currently in progress? */
+static bool LogMemoryContextInProgress = false;
+
 static void MemoryContextCallResetCallbacks(MemoryContext context);
 static void MemoryContextStatsInternal(MemoryContext context, int level,
 									   bool print, int max_children,
@@ -1201,25 +1204,45 @@ ProcessLogMemoryContextInterrupt(void)
 	LogMemoryContextPending = false;
 
 	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
+	 * Exit immediately if memory context logging is already in progress. This
+	 * prevents recursive calls, which could occur if logging is requested
+	 * repeatedly and rapidly, potentially leading to infinite recursion and a
+	 * crash.
 	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	if (LogMemoryContextInProgress)
+		return;
+	LogMemoryContextInProgress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the number of child contexts to log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, false);
+	PG_TRY();
+	{
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the number of child contexts to log per parent to
+		 * 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, false);
+	}
+	PG_FINALLY();
+	{
+		LogMemoryContextInProgress = false;
+	}
+	PG_END_TRY();
 }
 
 void *
-- 
2.49.0



  [text/plain] v3-0001-PG17-master-Add-guard-to-prevent-recursive-memory-context-log.patch (4.3K, ../../[email protected]/3-v3-0001-PG17-master-Add-guard-to-prevent-recursive-memory-context-log.patch)
  download | inline diff:
From 92a0fc0397831849f6e1443b010733a69e1d4b1d Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Wed, 7 May 2025 16:49:31 +0900
Subject: [PATCH v3] Add guard to prevent recursive memory context logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory context logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory context logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Reviewed-by: Robert Haas <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 58 ++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 7d28ca706eb..4690d039011 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -174,6 +174,9 @@ MemoryContext CurTransactionContext = NULL;
 MemoryContext PortalContext = NULL;
 dsa_area   *MemoryStatsDsaArea = NULL;
 
+/* Is memory context logging currently in progress? */
+static bool LogMemoryContextInProgress = false;
+
 static void MemoryContextDeleteOnly(MemoryContext context);
 static void MemoryContextCallResetCallbacks(MemoryContext context);
 static void MemoryContextStatsInternal(MemoryContext context, int level,
@@ -1386,26 +1389,45 @@ ProcessLogMemoryContextInterrupt(void)
 	LogMemoryContextPending = false;
 
 	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
+	 * Exit immediately if memory context logging is already in progress. This
+	 * prevents recursive calls, which could occur if logging is requested
+	 * repeatedly and rapidly, potentially leading to infinite recursion and a
+	 * crash.
 	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	if (LogMemoryContextInProgress)
+		return;
+	LogMemoryContextInProgress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the depth of the hierarchy, as well as the number of child contexts to
-	 * log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	PG_TRY();
+	{
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the depth of the hierarchy, as well as the number of
+		 * child contexts to log per parent to 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	}
+	PG_FINALLY();
+	{
+		LogMemoryContextInProgress = false;
+	}
+	PG_END_TRY();
 }
 
 /*
-- 
2.49.0



^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: pgsql: Add function to log the memory contexts of specified backend pro
@ 2025-07-14 13:53  Fujii Masao <[email protected]>
  parent: Fujii Masao <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Fujii Masao @ 2025-07-14 13:53 UTC (permalink / raw)
  To: Robert Haas <[email protected]>; +Cc: torikoshia <[email protected]>; PostgreSQL Hackers <[email protected]>



On 2025/05/07 18:06, Fujii Masao wrote:
> 
> 
> On 2025/05/05 23:57, Robert Haas wrote:
>> On Fri, May 2, 2025 at 9:54 PM Fujii Masao <[email protected]> wrote:
>>> Thanks for the review and testing! I've fixed the issue you pointed out.
>>> Updated patch attached.
>>
>> Thanks for addressing this. However, I believe this commit may need to
>> take note of the following comment from elog.h:
> 
> Thanks for the review!
> 
> 
>>   * Note: if a local variable of the function containing PG_TRY is modified
>>   * in the PG_TRY section and used in the PG_CATCH section, that variable
>>   * must be declared "volatile" for POSIX compliance.  This is not mere
>>   * pedantry; we have seen bugs from compilers improperly optimizing code
>>   * away when such a variable was not marked.  Beware that gcc's -Wclobbered
>>   * warnings are just about entirely useless for catching such oversights.
>>
>> Based on this comment, I believe in_progress must be declared volatile.
> 
> You're right. OTOH, setting the flag inside the PG_TRY() block isn't necessary,
> so I've moved it outside instead of leaving it inside and marking the flag volatile.
> 
> 
>> As a stylistic comment, I think I would prefer making in_progress a
>> file-level global and giving it a less generic name (e.g.
>> LogMemoryContextInProgress). However, perhaps others will disagree.
> 
> I'm fine with this. I've renamed the flag and made it a file-level global
> variable as suggested. Updated patch is attached.

I've attached the rebased versions of the patches.

The patch for v14–v16 is labeled with a .txt extension to prevent cfbot
from treating it as a patch for master, which would cause it to fail
when applying.

Regards,

-- 
Fujii Masao
NTT DATA Japan Corporation

From 3c6e6d0bab29147fb1dc469161b619b977cf5fc8 Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Mon, 14 Jul 2025 22:42:44 +0900
Subject: [PATCH v4] Add guard to prevent recursive memory context logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory context logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory context logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Reviewed-by: Robert Haas <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 57 ++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index a5f31e23a02..ffdab7b087d 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -56,6 +56,9 @@ MemoryContext CurTransactionContext = NULL;
 /* This is a transient link to the active portal's memory context: */
 MemoryContext PortalContext = NULL;
 
+/* Is memory context logging currently in progress? */
+static bool LogMemoryContextInProgress = false;
+
 static void MemoryContextCallResetCallbacks(MemoryContext context);
 static void MemoryContextStatsInternal(MemoryContext context, int level,
 									   bool print, int max_children,
@@ -1043,25 +1046,45 @@ ProcessLogMemoryContextInterrupt(void)
 	LogMemoryContextPending = false;
 
 	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
+	 * Exit immediately if memory context logging is already in progress. This
+	 * prevents recursive calls, which could occur if logging is requested
+	 * repeatedly and rapidly, potentially leading to infinite recursion and a
+	 * crash.
 	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	if (LogMemoryContextInProgress)
+		return;
+	LogMemoryContextInProgress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the number of child contexts to log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, false);
+	PG_TRY();
+	{
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the number of child contexts to log per parent to
+		 * 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, false);
+	}
+	PG_FINALLY();
+	{
+		LogMemoryContextInProgress = false;
+	}
+	PG_END_TRY();
 }
 
 void *
-- 
2.49.0


From 2b9e286c5d98bf24a3efc06aeb7645990c2ea7c0 Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Mon, 14 Jul 2025 22:38:45 +0900
Subject: [PATCH v4] Add guard to prevent recursive memory context logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory context logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory context logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Reviewed-by: Robert Haas <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 58 ++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 15fa4d0a55e..f7689ea6de8 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -157,6 +157,9 @@ MemoryContext CurTransactionContext = NULL;
 /* This is a transient link to the active portal's memory context: */
 MemoryContext PortalContext = NULL;
 
+/* Is memory context logging currently in progress? */
+static bool LogMemoryContextInProgress = false;
+
 static void MemoryContextDeleteOnly(MemoryContext context);
 static void MemoryContextCallResetCallbacks(MemoryContext context);
 static void MemoryContextStatsInternal(MemoryContext context, int level,
@@ -1295,26 +1298,45 @@ ProcessLogMemoryContextInterrupt(void)
 	LogMemoryContextPending = false;
 
 	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
+	 * Exit immediately if memory context logging is already in progress. This
+	 * prevents recursive calls, which could occur if logging is requested
+	 * repeatedly and rapidly, potentially leading to infinite recursion and a
+	 * crash.
 	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	if (LogMemoryContextInProgress)
+		return;
+	LogMemoryContextInProgress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the depth of the hierarchy, as well as the number of child contexts to
-	 * log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	PG_TRY();
+	{
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the depth of the hierarchy, as well as the number of
+		 * child contexts to log per parent to 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	}
+	PG_FINALLY();
+	{
+		LogMemoryContextInProgress = false;
+	}
+	PG_END_TRY();
 }
 
 void *
-- 
2.49.0



Attachments:

  [text/plain] v4-0001-PG14-PG16-Add-guard-to-prevent-recursive-memory-context-log.txt (4.2K, ../../[email protected]/2-v4-0001-PG14-PG16-Add-guard-to-prevent-recursive-memory-context-log.txt)
  download | inline diff:
From 3c6e6d0bab29147fb1dc469161b619b977cf5fc8 Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Mon, 14 Jul 2025 22:42:44 +0900
Subject: [PATCH v4] Add guard to prevent recursive memory context logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory context logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory context logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Reviewed-by: Robert Haas <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 57 ++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index a5f31e23a02..ffdab7b087d 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -56,6 +56,9 @@ MemoryContext CurTransactionContext = NULL;
 /* This is a transient link to the active portal's memory context: */
 MemoryContext PortalContext = NULL;
 
+/* Is memory context logging currently in progress? */
+static bool LogMemoryContextInProgress = false;
+
 static void MemoryContextCallResetCallbacks(MemoryContext context);
 static void MemoryContextStatsInternal(MemoryContext context, int level,
 									   bool print, int max_children,
@@ -1043,25 +1046,45 @@ ProcessLogMemoryContextInterrupt(void)
 	LogMemoryContextPending = false;
 
 	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
+	 * Exit immediately if memory context logging is already in progress. This
+	 * prevents recursive calls, which could occur if logging is requested
+	 * repeatedly and rapidly, potentially leading to infinite recursion and a
+	 * crash.
 	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	if (LogMemoryContextInProgress)
+		return;
+	LogMemoryContextInProgress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the number of child contexts to log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, false);
+	PG_TRY();
+	{
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the number of child contexts to log per parent to
+		 * 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, false);
+	}
+	PG_FINALLY();
+	{
+		LogMemoryContextInProgress = false;
+	}
+	PG_END_TRY();
 }
 
 void *
-- 
2.49.0



  [text/plain] v4-0001-PG17-master-Add-guard-to-prevent-recursive-memory-context-log.patch (4.3K, ../../[email protected]/3-v4-0001-PG17-master-Add-guard-to-prevent-recursive-memory-context-log.patch)
  download | inline diff:
From 2b9e286c5d98bf24a3efc06aeb7645990c2ea7c0 Mon Sep 17 00:00:00 2001
From: Fujii Masao <[email protected]>
Date: Mon, 14 Jul 2025 22:38:45 +0900
Subject: [PATCH v4] Add guard to prevent recursive memory context logging.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, if memory context logging was triggered repeatedly and
rapidly while a previous request was still being processed, it could
result in recursive calls to ProcessLogMemoryContextInterrupt().
This could lead to infinite recursion and potentially crash the process.

This commit adds a guard to prevent such recursion.
If ProcessLogMemoryContextInterrupt() is already in progress and
logging memory contexts, subsequent calls will exit immediately,
avoiding unintended recursive calls.

While this scenario is unlikely in practice, it’s not impossible.
This change adds a safety check to prevent such failures.

Back-patch to v14, where memory context logging was introduced.

Reported-by: Robert Haas <[email protected]>
Author: Fujii Masao <[email protected]>
Reviewed-by: Atsushi Torikoshi <[email protected]>
Reviewed-by: Robert Haas <[email protected]>
Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com
Backpatch-through: 14
---
 src/backend/utils/mmgr/mcxt.c | 58 ++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 15fa4d0a55e..f7689ea6de8 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -157,6 +157,9 @@ MemoryContext CurTransactionContext = NULL;
 /* This is a transient link to the active portal's memory context: */
 MemoryContext PortalContext = NULL;
 
+/* Is memory context logging currently in progress? */
+static bool LogMemoryContextInProgress = false;
+
 static void MemoryContextDeleteOnly(MemoryContext context);
 static void MemoryContextCallResetCallbacks(MemoryContext context);
 static void MemoryContextStatsInternal(MemoryContext context, int level,
@@ -1295,26 +1298,45 @@ ProcessLogMemoryContextInterrupt(void)
 	LogMemoryContextPending = false;
 
 	/*
-	 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
-	 * connected client.
+	 * Exit immediately if memory context logging is already in progress. This
+	 * prevents recursive calls, which could occur if logging is requested
+	 * repeatedly and rapidly, potentially leading to infinite recursion and a
+	 * crash.
 	 */
-	ereport(LOG_SERVER_ONLY,
-			(errhidestmt(true),
-			 errhidecontext(true),
-			 errmsg("logging memory contexts of PID %d", MyProcPid)));
+	if (LogMemoryContextInProgress)
+		return;
+	LogMemoryContextInProgress = true;
 
-	/*
-	 * When a backend process is consuming huge memory, logging all its memory
-	 * contexts might overrun available disk space. To prevent this, we limit
-	 * the depth of the hierarchy, as well as the number of child contexts to
-	 * log per parent to 100.
-	 *
-	 * As with MemoryContextStats(), we suppose that practical cases where the
-	 * dump gets long will typically be huge numbers of siblings under the
-	 * same parent context; while the additional debugging value from seeing
-	 * details about individual siblings beyond 100 will not be large.
-	 */
-	MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	PG_TRY();
+	{
+		/*
+		 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
+		 * connected client.
+		 */
+		ereport(LOG_SERVER_ONLY,
+				(errhidestmt(true),
+				 errhidecontext(true),
+				 errmsg("logging memory contexts of PID %d", MyProcPid)));
+
+		/*
+		 * When a backend process is consuming huge memory, logging all its
+		 * memory contexts might overrun available disk space. To prevent
+		 * this, we limit the depth of the hierarchy, as well as the number of
+		 * child contexts to log per parent to 100.
+		 *
+		 * As with MemoryContextStats(), we suppose that practical cases where
+		 * the dump gets long will typically be huge numbers of siblings under
+		 * the same parent context; while the additional debugging value from
+		 * seeing details about individual siblings beyond 100 will not be
+		 * large.
+		 */
+		MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
+	}
+	PG_FINALLY();
+	{
+		LogMemoryContextInProgress = false;
+	}
+	PG_END_TRY();
 }
 
 void *
-- 
2.49.0



^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: pgsql: Add function to log the memory contexts of specified backend pro
@ 2025-12-08 19:32  Artem Gavrilov <[email protected]>
  parent: Fujii Masao <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Artem Gavrilov @ 2025-12-08 19:32 UTC (permalink / raw)
  To: Fujii Masao <[email protected]>; +Cc: Robert Haas <[email protected]>; torikoshia <[email protected]>; PostgreSQL Hackers <[email protected]>

Hi Fujii,

I did your patch review. It successfully applies to all targeted branches:
REL_14_STABLE (48969555447), REL_15_STABLE (b9a02b9780b), REL_16_STABLE
(4d689a17693), REL_17_STABLE (cad40cec24f), REL_18_STABLE (5278222853c) and
master (d0d0ba6cf66). All tests successfully pass on MacOS 15.7 for every
revision. Everything seems fine with the patch, I think it's ready for
committer.

-- 

Artem Gavrilov

Senior Software Engineer, Percona

[email protected]
percona.com <http://www.percona.com;


^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: pgsql: Add function to log the memory contexts of specified backend pro
@ 2025-12-15 15:07  Robert Haas <[email protected]>
  parent: Artem Gavrilov <[email protected]>
  0 siblings, 1 reply; 12+ messages in thread

From: Robert Haas @ 2025-12-15 15:07 UTC (permalink / raw)
  To: Artem Gavrilov <[email protected]>; +Cc: Fujii Masao <[email protected]>; torikoshia <[email protected]>; PostgreSQL Hackers <[email protected]>

On Mon, Dec 8, 2025 at 2:32 PM Artem Gavrilov
<[email protected]> wrote:
> I did your patch review. It successfully applies to all targeted branches: REL_14_STABLE (48969555447), REL_15_STABLE (b9a02b9780b), REL_16_STABLE (4d689a17693), REL_17_STABLE (cad40cec24f), REL_18_STABLE (5278222853c) and master (d0d0ba6cf66). All tests successfully pass on MacOS 15.7 for every revision. Everything seems fine with the patch, I think it's ready for committer.

LGTM, too.

-- 
Robert Haas
EDB: http://www.enterprisedb.com





^ permalink  raw  reply  [nested|flat] 12+ messages in thread

* Re: pgsql: Add function to log the memory contexts of specified backend pro
@ 2025-12-19 03:17  Fujii Masao <[email protected]>
  parent: Robert Haas <[email protected]>
  0 siblings, 0 replies; 12+ messages in thread

From: Fujii Masao @ 2025-12-19 03:17 UTC (permalink / raw)
  To: Robert Haas <[email protected]>; +Cc: Artem Gavrilov <[email protected]>; Fujii Masao <[email protected]>; torikoshia <[email protected]>; PostgreSQL Hackers <[email protected]>

On Tue, Dec 16, 2025 at 12:07 AM Robert Haas <[email protected]> wrote:
>
> On Mon, Dec 8, 2025 at 2:32 PM Artem Gavrilov
> <[email protected]> wrote:
> > I did your patch review. It successfully applies to all targeted branches: REL_14_STABLE (48969555447), REL_15_STABLE (b9a02b9780b), REL_16_STABLE (4d689a17693), REL_17_STABLE (cad40cec24f), REL_18_STABLE (5278222853c) and master (d0d0ba6cf66). All tests successfully pass on MacOS 15.7 for every revision. Everything seems fine with the patch, I think it's ready for committer.
>
> LGTM, too.

Thanks to both of you for the review! I've pushed the patch.

Regards,

-- 
Fujii Masao





^ permalink  raw  reply  [nested|flat] 12+ messages in thread


end of thread, other threads:[~2025-12-19 03:17 UTC | newest]

Thread overview: 12+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2021-03-04 09:10 [PATCH v2 1/1] Simplify COPY FROM parsing by forcing lookahead. Heikki Linnakangas <[email protected]>
2021-04-06 04:45 pgsql: Add function to log the memory contexts of specified backend pro Fujii Masao <[email protected]>
2025-05-01 07:53 ` Re: pgsql: Add function to log the memory contexts of specified backend pro Fujii Masao <[email protected]>
2025-05-02 00:02   ` Re: pgsql: Add function to log the memory contexts of specified backend pro Fujii Masao <[email protected]>
2025-05-02 05:58     ` Re: pgsql: Add function to log the memory contexts of specified backend pro torikoshia <[email protected]>
2025-05-03 01:53       ` Re: pgsql: Add function to log the memory contexts of specified backend pro Fujii Masao <[email protected]>
2025-05-05 14:57         ` Re: pgsql: Add function to log the memory contexts of specified backend pro Robert Haas <[email protected]>
2025-05-07 09:06           ` Re: pgsql: Add function to log the memory contexts of specified backend pro Fujii Masao <[email protected]>
2025-07-14 13:53             ` Re: pgsql: Add function to log the memory contexts of specified backend pro Fujii Masao <[email protected]>
2025-12-08 19:32               ` Re: pgsql: Add function to log the memory contexts of specified backend pro Artem Gavrilov <[email protected]>
2025-12-15 15:07                 ` Re: pgsql: Add function to log the memory contexts of specified backend pro Robert Haas <[email protected]>
2025-12-19 03:17                   ` Re: pgsql: Add function to log the memory contexts of specified backend pro Fujii Masao <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox