Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 608cf2b

Browse filesBrowse files
committed
Fix ancient memory leak in contrib/auto_explain.
The ExecutorEnd hook is invoked in a context that could be quite long-lived, not the executor's own per-query context as I think we were sort of assuming. Thus, any cruft generated while producing the EXPLAIN output could accumulate over multiple queries. This can result in spectacular leakage if log_nested_statements is on, and even without that I'm surprised nobody complained before. To fix, just switch into the executor's context so that anything we allocate will be released when standard_ExecutorEnd frees the executor state. We might as well nuke the code's retail pfree of the explain output string, too; that's laughably inadequate to the need. Japin Li, per report from Jeff Janes. This bug is old, so back-patch to all supported branches. Discussion: https://postgr.es/m/CAMkU=1wCVtbeRn0s9gt12KwQ7PLXovbpM8eg25SYocKW3BT4hg@mail.gmail.com
1 parent d683d65 commit 608cf2b
Copy full SHA for 608cf2b

File tree

Expand file treeCollapse file tree

1 file changed

+9
-2
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

1 file changed

+9
-2
lines changed
Open diff view settings
Collapse file

‎contrib/auto_explain/auto_explain.c‎

Copy file name to clipboardExpand all lines: contrib/auto_explain/auto_explain.c
+9-2Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,15 @@ explain_ExecutorEnd(QueryDesc *queryDesc)
320320
{
321321
if (queryDesc->totaltime && auto_explain_enabled())
322322
{
323+
MemoryContext oldcxt;
323324
double msec;
324325

326+
/*
327+
* Make sure we operate in the per-query context, so any cruft will be
328+
* discarded later during ExecutorEnd.
329+
*/
330+
oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
331+
325332
/*
326333
* Make sure stats accumulation is done. (Note: it's okay if several
327334
* levels of hook all do this.)
@@ -369,9 +376,9 @@ explain_ExecutorEnd(QueryDesc *queryDesc)
369376
(errmsg("duration: %.3f ms plan:\n%s",
370377
msec, es->str->data),
371378
errhidestmt(true)));
372-
373-
pfree(es->str->data);
374379
}
380+
381+
MemoryContextSwitchTo(oldcxt);
375382
}
376383

377384
if (prev_ExecutorEnd)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.