Skip to content

Commit 7b1f1e4

Browse files
MasaoFujiiCommitfest Bot
authored andcommitted
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 <[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
1 parent f727b63 commit 7b1f1e4

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
@@ -174,6 +174,9 @@ MemoryContext CurTransactionContext = NULL;
174174
/* This is a transient link to the active portal's memory context: */
175175
MemoryContext PortalContext = NULL;
176176

177+
/* Is memory context logging currently in progress? */
178+
static bool LogMemoryContextInProgress = false;
179+
177180
static void MemoryContextDeleteOnly(MemoryContext context);
178181
static void MemoryContextCallResetCallbacks(MemoryContext context);
179182
static void MemoryContextStatsInternal(MemoryContext context, int level,
@@ -1339,26 +1342,45 @@ ProcessLogMemoryContextInterrupt(void)
13391342
LogMemoryContextPending = false;
13401343

13411344
/*
1342-
* Use LOG_SERVER_ONLY to prevent this message from being sent to the
1343-
* connected client.
1345+
* Exit immediately if memory context logging is already in progress. This
1346+
* prevents recursive calls, which could occur if logging is requested
1347+
* repeatedly and rapidly, potentially leading to infinite recursion and a
1348+
* crash.
13441349
*/
1345-
ereport(LOG_SERVER_ONLY,
1346-
(errhidestmt(true),
1347-
errhidecontext(true),
1348-
errmsg("logging memory contexts of PID %d", MyProcPid)));
1350+
if (LogMemoryContextInProgress)
1351+
return;
1352+
LogMemoryContextInProgress = true;
13491353

1350-
/*
1351-
* When a backend process is consuming huge memory, logging all its memory
1352-
* contexts might overrun available disk space. To prevent this, we limit
1353-
* the depth of the hierarchy, as well as the number of child contexts to
1354-
* log per parent to 100.
1355-
*
1356-
* As with MemoryContextStats(), we suppose that practical cases where the
1357-
* dump gets long will typically be huge numbers of siblings under the
1358-
* same parent context; while the additional debugging value from seeing
1359-
* details about individual siblings beyond 100 will not be large.
1360-
*/
1361-
MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
1354+
PG_TRY();
1355+
{
1356+
/*
1357+
* Use LOG_SERVER_ONLY to prevent this message from being sent to the
1358+
* connected client.
1359+
*/
1360+
ereport(LOG_SERVER_ONLY,
1361+
(errhidestmt(true),
1362+
errhidecontext(true),
1363+
errmsg("logging memory contexts of PID %d", MyProcPid)));
1364+
1365+
/*
1366+
* When a backend process is consuming huge memory, logging all its
1367+
* memory contexts might overrun available disk space. To prevent
1368+
* this, we limit the depth of the hierarchy, as well as the number of
1369+
* child contexts to log per parent to 100.
1370+
*
1371+
* As with MemoryContextStats(), we suppose that practical cases where
1372+
* the dump gets long will typically be huge numbers of siblings under
1373+
* the same parent context; while the additional debugging value from
1374+
* seeing details about individual siblings beyond 100 will not be
1375+
* large.
1376+
*/
1377+
MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
1378+
}
1379+
PG_FINALLY();
1380+
{
1381+
LogMemoryContextInProgress = false;
1382+
}
1383+
PG_END_TRY();
13621384
}
13631385

13641386
void *

0 commit comments

Comments
 (0)