Skip to content

Commit 3853f61

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 a527770 commit 3853f61

File tree

1 file changed

+40
-17
lines changed

1 file changed

+40
-17
lines changed

src/backend/utils/mmgr/mcxt.c

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ MemoryContext CurTransactionContext = NULL;
149149
/* This is a transient link to the active portal's memory context: */
150150
MemoryContext PortalContext = NULL;
151151

152+
/* Is memory context logging currently in progress? */
153+
static bool LogMemoryContextInProgress = false;
154+
152155
static void MemoryContextCallResetCallbacks(MemoryContext context);
153156
static void MemoryContextStatsInternal(MemoryContext context, int level,
154157
bool print, int max_children,
@@ -1201,25 +1204,45 @@ ProcessLogMemoryContextInterrupt(void)
12011204
LogMemoryContextPending = false;
12021205

12031206
/*
1204-
* Use LOG_SERVER_ONLY to prevent this message from being sent to the
1205-
* connected client.
1207+
* Exit immediately if memory context logging is already in progress. This
1208+
* prevents recursive calls, which could occur if logging is requested
1209+
* repeatedly and rapidly, potentially leading to infinite recursion and a
1210+
* crash.
12061211
*/
1207-
ereport(LOG_SERVER_ONLY,
1208-
(errhidestmt(true),
1209-
errhidecontext(true),
1210-
errmsg("logging memory contexts of PID %d", MyProcPid)));
1212+
if (LogMemoryContextInProgress)
1213+
return;
1214+
LogMemoryContextInProgress = true;
12111215

1212-
/*
1213-
* When a backend process is consuming huge memory, logging all its memory
1214-
* contexts might overrun available disk space. To prevent this, we limit
1215-
* the number of child contexts to log per parent to 100.
1216-
*
1217-
* As with MemoryContextStats(), we suppose that practical cases where the
1218-
* dump gets long will typically be huge numbers of siblings under the
1219-
* same parent context; while the additional debugging value from seeing
1220-
* details about individual siblings beyond 100 will not be large.
1221-
*/
1222-
MemoryContextStatsDetail(TopMemoryContext, 100, false);
1216+
PG_TRY();
1217+
{
1218+
/*
1219+
* Use LOG_SERVER_ONLY to prevent this message from being sent to the
1220+
* connected client.
1221+
*/
1222+
ereport(LOG_SERVER_ONLY,
1223+
(errhidestmt(true),
1224+
errhidecontext(true),
1225+
errmsg("logging memory contexts of PID %d", MyProcPid)));
1226+
1227+
/*
1228+
* When a backend process is consuming huge memory, logging all its
1229+
* memory contexts might overrun available disk space. To prevent
1230+
* this, we limit the number of child contexts to log per parent to
1231+
* 100.
1232+
*
1233+
* As with MemoryContextStats(), we suppose that practical cases where
1234+
* the dump gets long will typically be huge numbers of siblings under
1235+
* the same parent context; while the additional debugging value from
1236+
* seeing details about individual siblings beyond 100 will not be
1237+
* large.
1238+
*/
1239+
MemoryContextStatsDetail(TopMemoryContext, 100, false);
1240+
}
1241+
PG_FINALLY();
1242+
{
1243+
LogMemoryContextInProgress = false;
1244+
}
1245+
PG_END_TRY();
12231246
}
12241247

12251248
void *

0 commit comments

Comments
 (0)