Skip to content

Commit f8d67ca

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 8d90736 commit f8d67ca

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
@@ -2104,6 +2104,7 @@ static int
21042104
pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
21052105
int argc, CONST84 char *argv[])
21062106
{
2107+
volatile MemoryContext plan_cxt = NULL;
21072108
int nargs;
21082109
CONST84 char **args;
21092110
pltcl_query_desc *qdesc;
@@ -2132,13 +2133,24 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
21322133

21332134
/************************************************************
21342135
* Allocate the new querydesc structure
2136+
*
2137+
* struct qdesc and subsidiary data all live in plan_cxt. Note that if the
2138+
* function is recompiled for whatever reason, permanent memory leaks
2139+
* occur. FIXME someday.
21352140
************************************************************/
2136-
qdesc = (pltcl_query_desc *) malloc(sizeof(pltcl_query_desc));
2141+
plan_cxt = AllocSetContextCreate(TopMemoryContext,
2142+
"PL/TCL spi_prepare query",
2143+
ALLOCSET_SMALL_MINSIZE,
2144+
ALLOCSET_SMALL_INITSIZE,
2145+
ALLOCSET_SMALL_MAXSIZE);
2146+
MemoryContextSwitchTo(plan_cxt);
2147+
qdesc = (pltcl_query_desc *) palloc0(sizeof(pltcl_query_desc));
21372148
snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc);
21382149
qdesc->nargs = nargs;
2139-
qdesc->argtypes = (Oid *) malloc(nargs * sizeof(Oid));
2140-
qdesc->arginfuncs = (FmgrInfo *) malloc(nargs * sizeof(FmgrInfo));
2141-
qdesc->argtypioparams = (Oid *) malloc(nargs * sizeof(Oid));
2150+
qdesc->argtypes = (Oid *) palloc(nargs * sizeof(Oid));
2151+
qdesc->arginfuncs = (FmgrInfo *) palloc(nargs * sizeof(FmgrInfo));
2152+
qdesc->argtypioparams = (Oid *) palloc(nargs * sizeof(Oid));
2153+
MemoryContextSwitchTo(oldcontext);
21422154

21432155
/************************************************************
21442156
* Execute the prepare inside a sub-transaction, so we can cope with
@@ -2166,7 +2178,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
21662178
getTypeInputInfo(typId, &typInput, &typIOParam);
21672179

21682180
qdesc->argtypes[i] = typId;
2169-
perm_fmgr_info(typInput, &(qdesc->arginfuncs[i]));
2181+
fmgr_info_cxt(typInput, &(qdesc->arginfuncs[i]), plan_cxt);
21702182
qdesc->argtypioparams[i] = typIOParam;
21712183
}
21722184

@@ -2193,10 +2205,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
21932205
{
21942206
pltcl_subtrans_abort(interp, oldcontext, oldowner);
21952207

2196-
free(qdesc->argtypes);
2197-
free(qdesc->arginfuncs);
2198-
free(qdesc->argtypioparams);
2199-
free(qdesc);
2208+
MemoryContextDelete(plan_cxt);
22002209
ckfree((char *) args);
22012210

22022211
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