Skip to content

Commit b2efbb7

Browse files
committed
Fix (some of) pltcl memory usage
As reported by Bill Parker, PL/Tcl did not validate some malloc() calls against NULL return. Fix by using palloc() in a new long-lived memory context instead. This allows us to simplify error handling too, by simply deleting the memory context instead of doing retail frees. There's still a lot that could be done to improve PL/Tcl's memory handling ... This is pretty ancient, so backpatch all the way back. Author: Michael Paquier and Álvaro Herrera Discussion: https://www.postgresql.org/message-id/CAFrbyQwyLDYXfBOhPfoBGqnvuZO_Y90YgqFM11T2jvnxjLFmqw@mail.gmail.com
1 parent 498a29d commit b2efbb7

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

src/pl/tcl/pltcl.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,6 +2039,7 @@ static int
20392039
pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
20402040
int argc, CONST84 char *argv[])
20412041
{
2042+
volatile MemoryContext plan_cxt = NULL;
20422043
int nargs;
20432044
CONST84 char **args;
20442045
pltcl_query_desc *qdesc;
@@ -2067,13 +2068,24 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
20672068

20682069
/************************************************************
20692070
* Allocate the new querydesc structure
2071+
*
2072+
* struct qdesc and subsidiary data all live in plan_cxt. Note that if the
2073+
* function is recompiled for whatever reason, permanent memory leaks
2074+
* occur. FIXME someday.
20702075
************************************************************/
2071-
qdesc = (pltcl_query_desc *) malloc(sizeof(pltcl_query_desc));
2076+
plan_cxt = AllocSetContextCreate(TopMemoryContext,
2077+
"PL/TCL spi_prepare query",
2078+
ALLOCSET_SMALL_MINSIZE,
2079+
ALLOCSET_SMALL_INITSIZE,
2080+
ALLOCSET_SMALL_MAXSIZE);
2081+
MemoryContextSwitchTo(plan_cxt);
2082+
qdesc = (pltcl_query_desc *) palloc0(sizeof(pltcl_query_desc));
20722083
snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc);
20732084
qdesc->nargs = nargs;
2074-
qdesc->argtypes = (Oid *) malloc(nargs * sizeof(Oid));
2075-
qdesc->arginfuncs = (FmgrInfo *) malloc(nargs * sizeof(FmgrInfo));
2076-
qdesc->argtypioparams = (Oid *) malloc(nargs * sizeof(Oid));
2085+
qdesc->argtypes = (Oid *) palloc(nargs * sizeof(Oid));
2086+
qdesc->arginfuncs = (FmgrInfo *) palloc(nargs * sizeof(FmgrInfo));
2087+
qdesc->argtypioparams = (Oid *) palloc(nargs * sizeof(Oid));
2088+
MemoryContextSwitchTo(oldcontext);
20772089

20782090
/************************************************************
20792091
* Execute the prepare inside a sub-transaction, so we can cope with
@@ -2101,7 +2113,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
21012113
getTypeInputInfo(typId, &typInput, &typIOParam);
21022114

21032115
qdesc->argtypes[i] = typId;
2104-
perm_fmgr_info(typInput, &(qdesc->arginfuncs[i]));
2116+
fmgr_info_cxt(typInput, &(qdesc->arginfuncs[i]), plan_cxt);
21052117
qdesc->argtypioparams[i] = typIOParam;
21062118
}
21072119

@@ -2128,10 +2140,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
21282140
{
21292141
pltcl_subtrans_abort(interp, oldcontext, oldowner);
21302142

2131-
free(qdesc->argtypes);
2132-
free(qdesc->arginfuncs);
2133-
free(qdesc->argtypioparams);
2134-
free(qdesc);
2143+
MemoryContextDelete(plan_cxt);
21352144
ckfree((char *) args);
21362145

21372146
return TCL_ERROR;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy