Skip to content

Commit 699293d

Browse files
committed
Add guard to prevent recursive memory context logging.
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 <robertmhaas@gmail.com> Author: Fujii Masao <masao.fujii@gmail.com> Reviewed-by: Atsushi Torikoshi <torikoshia@oss.nttdata.com> Reviewed-by: Robert Haas <robertmhaas@gmail.com> Reviewed-by: Artem Gavrilov <artem.gavrilov@percona.com> Discussion: https://postgr.es/m/CA+TgmoZMrv32tbNRrFTvF9iWLnTGqbhYSLVcrHGuwZvCtph0NA@mail.gmail.com Backpatch-through: 14
1 parent 1cdc07a commit 699293d

File tree

1 file changed

+40
-18
lines changed

1 file changed

+40
-18
lines changed

src/backend/utils/mmgr/mcxt.c

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ MemoryContext CurTransactionContext = NULL;
157157
/* This is a transient link to the active portal's memory context: */
158158
MemoryContext PortalContext = NULL;
159159

160+
/* Is memory context logging currently in progress? */
161+
static bool LogMemoryContextInProgress = false;
162+
160163
static void MemoryContextDeleteOnly(MemoryContext context);
161164
static void MemoryContextCallResetCallbacks(MemoryContext context);
162165
static void MemoryContextStatsInternal(MemoryContext context, int level,
@@ -1290,26 +1293,45 @@ ProcessLogMemoryContextInterrupt(void)
12901293
LogMemoryContextPending = false;
12911294

12921295
/*
1293-
* Use LOG_SERVER_ONLY to prevent this message from being sent to the
1294-
* connected client.
1296+
* Exit immediately if memory context logging is already in progress. This
1297+
* prevents recursive calls, which could occur if logging is requested
1298+
* repeatedly and rapidly, potentially leading to infinite recursion and a
1299+
* crash.
12951300
*/
1296-
ereport(LOG_SERVER_ONLY,
1297-
(errhidestmt(true),
1298-
errhidecontext(true),
1299-
errmsg("logging memory contexts of PID %d", MyProcPid)));
1301+
if (LogMemoryContextInProgress)
1302+
return;
1303+
LogMemoryContextInProgress = true;
13001304

1301-
/*
1302-
* When a backend process is consuming huge memory, logging all its memory
1303-
* contexts might overrun available disk space. To prevent this, we limit
1304-
* the depth of the hierarchy, as well as the number of child contexts to
1305-
* log per parent to 100.
1306-
*
1307-
* As with MemoryContextStats(), we suppose that practical cases where the
1308-
* dump gets long will typically be huge numbers of siblings under the
1309-
* same parent context; while the additional debugging value from seeing
1310-
* details about individual siblings beyond 100 will not be large.
1311-
*/
1312-
MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
1305+
PG_TRY();
1306+
{
1307+
/*
1308+
* Use LOG_SERVER_ONLY to prevent this message from being sent to the
1309+
* connected client.
1310+
*/
1311+
ereport(LOG_SERVER_ONLY,
1312+
(errhidestmt(true),
1313+
errhidecontext(true),
1314+
errmsg("logging memory contexts of PID %d", MyProcPid)));
1315+
1316+
/*
1317+
* When a backend process is consuming huge memory, logging all its
1318+
* memory contexts might overrun available disk space. To prevent
1319+
* this, we limit the depth of the hierarchy, as well as the number of
1320+
* child contexts to log per parent to 100.
1321+
*
1322+
* As with MemoryContextStats(), we suppose that practical cases where
1323+
* the dump gets long will typically be huge numbers of siblings under
1324+
* the same parent context; while the additional debugging value from
1325+
* seeing details about individual siblings beyond 100 will not be
1326+
* large.
1327+
*/
1328+
MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
1329+
}
1330+
PG_FINALLY();
1331+
{
1332+
LogMemoryContextInProgress = false;
1333+
}
1334+
PG_END_TRY();
13131335
}
13141336

13151337
void *

0 commit comments

Comments
 (0)