Skip to content

Commit 49c3000

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 29efe1b commit 49c3000

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
@@ -2106,6 +2106,7 @@ static int
21062106
pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
21072107
int argc, CONST84 char *argv[])
21082108
{
2109+
volatile MemoryContext plan_cxt = NULL;
21092110
int nargs;
21102111
CONST84 char **args;
21112112
pltcl_query_desc *qdesc;
@@ -2134,13 +2135,24 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
21342135

21352136
/************************************************************
21362137
* Allocate the new querydesc structure
2138+
*
2139+
* struct qdesc and subsidiary data all live in plan_cxt. Note that if the
2140+
* function is recompiled for whatever reason, permanent memory leaks
2141+
* occur. FIXME someday.
21372142
************************************************************/
2138-
qdesc = (pltcl_query_desc *) malloc(sizeof(pltcl_query_desc));
2143+
plan_cxt = AllocSetContextCreate(TopMemoryContext,
2144+
"PL/TCL spi_prepare query",
2145+
ALLOCSET_SMALL_MINSIZE,
2146+
ALLOCSET_SMALL_INITSIZE,
2147+
ALLOCSET_SMALL_MAXSIZE);
2148+
MemoryContextSwitchTo(plan_cxt);
2149+
qdesc = (pltcl_query_desc *) palloc0(sizeof(pltcl_query_desc));
21392150
snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc);
21402151
qdesc->nargs = nargs;
2141-
qdesc->argtypes = (Oid *) malloc(nargs * sizeof(Oid));
2142-
qdesc->arginfuncs = (FmgrInfo *) malloc(nargs * sizeof(FmgrInfo));
2143-
qdesc->argtypioparams = (Oid *) malloc(nargs * sizeof(Oid));
2152+
qdesc->argtypes = (Oid *) palloc(nargs * sizeof(Oid));
2153+
qdesc->arginfuncs = (FmgrInfo *) palloc(nargs * sizeof(FmgrInfo));
2154+
qdesc->argtypioparams = (Oid *) palloc(nargs * sizeof(Oid));
2155+
MemoryContextSwitchTo(oldcontext);
21442156

21452157
/************************************************************
21462158
* Execute the prepare inside a sub-transaction, so we can cope with
@@ -2168,7 +2180,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
21682180
getTypeInputInfo(typId, &typInput, &typIOParam);
21692181

21702182
qdesc->argtypes[i] = typId;
2171-
perm_fmgr_info(typInput, &(qdesc->arginfuncs[i]));
2183+
fmgr_info_cxt(typInput, &(qdesc->arginfuncs[i]), plan_cxt);
21722184
qdesc->argtypioparams[i] = typIOParam;
21732185
}
21742186

@@ -2195,10 +2207,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
21952207
{
21962208
pltcl_subtrans_abort(interp, oldcontext, oldowner);
21972209

2198-
free(qdesc->argtypes);
2199-
free(qdesc->arginfuncs);
2200-
free(qdesc->argtypioparams);
2201-
free(qdesc);
2210+
MemoryContextDelete(plan_cxt);
22022211
ckfree((char *) args);
22032212

22042213
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