Skip to content

Commit af1e9a9

Browse files
committed
Protect referenced PLpgSQL_function structure until fextra is used
1 parent 76f4cfd commit af1e9a9

4 files changed

Lines changed: 35 additions & 84 deletions

File tree

src/cursors_leaks.c

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ int plpgsql_check_cursors_leaks_level = WARNING;
3333
typedef struct CursorTrace
3434
{
3535
int stmtid;
36-
int rec_level;
36+
PLpgSQL_execstate *estate;
3737
char *curname;
3838
} CursorTrace;
3939

@@ -195,16 +195,7 @@ func_end(PLpgSQL_execstate *estate,
195195
* Iterate over traced cursors. Remove slots for tracing immediately,
196196
* when traced cursor is closed already.
197197
*/
198-
#if PG_VERSION_NUM >= 180000
199-
200-
if (ct->curname && ct->rec_level == func->cfunc.use_count)
201-
202-
#else
203-
204-
if (ct->curname && ct->rec_level == func->use_count)
205-
206-
#endif
207-
198+
if (ct->curname && ct->estate == estate)
208199
{
209200
if (SPI_cursor_find(ct->curname))
210201
{
@@ -286,16 +277,7 @@ stmt_end(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt, plch_fextra *fextra)
286277

287278
if (SPI_cursor_find(ct->curname))
288279
{
289-
#if PG_VERSION_NUM >= 180000
290-
291-
if (estate->func->cfunc.use_count == 1 && !plpgsql_check_cursors_leaks_strict)
292-
293-
#else
294-
295-
if (estate->func->use_count == 1 && !plpgsql_check_cursors_leaks_strict)
296-
297-
#endif
298-
280+
if (!plpgsql_check_cursors_leaks_strict)
299281
{
300282
char *context;
301283

@@ -362,16 +344,7 @@ stmt_end(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt, plch_fextra *fextra)
362344

363345
ct->stmtid = stmt->stmtid;
364346

365-
#if PG_VERSION_NUM >= 180000
366-
367-
ct->rec_level = estate->func->cfunc.use_count;
368-
369-
#else
370-
371-
ct->rec_level = estate->func->use_count;
372-
373-
#endif
374-
347+
ct->estate = estate;
375348
ct->curname = pstrdup(curname);
376349

377350
MemoryContextSwitchTo(oldcxt);

src/fextra_cache.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,17 @@ plch_get_fextra(PLpgSQL_function *func)
321321
}
322322

323323
fextra->use_count++;
324+
fextra->func = func;
325+
326+
#if PG_VERSION_NUM >= 180000
327+
328+
func->cfunc.use_count++;
329+
330+
#else
331+
332+
func->use_count++;
333+
334+
#endif
324335

325336
return fextra;
326337
}
@@ -330,7 +341,21 @@ plch_release_fextra(plch_fextra *fextra)
330341
{
331342
Assert(fextra->use_count > 0);
332343

344+
/* until now, referenced PLpgSQL_function should be still valid */
345+
Assert(fextra->hk.fn_oid == fextra->func->fn_oid);
346+
333347
fextra->use_count--;
348+
349+
#if PG_VERSION_NUM >= 180000
350+
351+
fextra->func->cfunc.use_count--;
352+
353+
#else
354+
355+
fextra->func->use_count--;
356+
357+
#endif
358+
334359
}
335360

336361

src/pldbgapi3.c

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ typedef struct plpgsql_plugin_info
4444
/* for assertations */
4545
Oid fn_oid;
4646
PLpgSQL_execstate *estate;
47-
int use_count;
4847

4948
plch_fextra *fextra;
5049

@@ -160,9 +159,12 @@ plugin_info_reset(void *arg)
160159
{
161160
plpgsql_plugin_info *plugin_info = (plpgsql_plugin_info*) arg;
162161
MemoryContext exec_mcxt = CurrentMemoryContext;
163-
int stmts_stack_size = plugin_info->stmts_stack_size;
162+
int stmts_stack_size;
164163
int i;
165164

165+
/* The memory should not be corrupted! */
166+
Assert(plugin_info->magic == PLUGIN_INFO_MAGIC);
167+
166168
/*
167169
* PostgreSQL 19 can remove this callback. But we need to support
168170
* previous releases, so when fextra is already released, then
@@ -171,6 +173,7 @@ plugin_info_reset(void *arg)
171173
if (!plugin_info->fextra)
172174
return;
173175

176+
stmts_stack_size = plugin_info->stmts_stack_size;
174177
plugin_info->stmts_stack_size = 0;
175178

176179
PG_TRY();
@@ -221,17 +224,6 @@ func_setup(PLpgSQL_execstate *estate, PLpgSQL_function *func)
221224
plugin_info->fn_oid = func->fn_oid;
222225
plugin_info->estate = estate;
223226

224-
225-
#if PG_VERSION_NUM >= 180000
226-
227-
plugin_info->use_count = func->cfunc.use_count;
228-
229-
#else
230-
231-
plugin_info->use_count = func->use_count;
232-
233-
#endif
234-
235227
for (i = 0; i < nplugins; i++)
236228
{
237229
if (plugins[i]->is_active(estate, func))
@@ -333,16 +325,6 @@ func_beg(PLpgSQL_execstate *estate, PLpgSQL_function *func)
333325
Assert(plugin_info->estate == estate);
334326
Assert(plugin_info->fn_oid == func->fn_oid);
335327

336-
#if PG_VERSION_NUM >= 180000
337-
338-
Assert(plugin_info->use_count == func->cfunc.use_count);
339-
340-
#else
341-
342-
Assert(plugin_info->use_count == func->use_count);
343-
344-
#endif
345-
346328
PG_TRY();
347329
{
348330
if (plugin_info->fextra)
@@ -397,16 +379,6 @@ func_end(PLpgSQL_execstate *estate, PLpgSQL_function *func)
397379
Assert(plugin_info->estate == estate);
398380
Assert(plugin_info->fn_oid == func->fn_oid);
399381

400-
#if PG_VERSION_NUM >= 180000
401-
402-
Assert(plugin_info->use_count == func->cfunc.use_count);
403-
404-
#else
405-
406-
Assert(plugin_info->use_count == func->use_count);
407-
408-
#endif
409-
410382
PG_TRY();
411383
{
412384
if (plugin_info->fextra)
@@ -481,16 +453,6 @@ stmt_beg(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt)
481453
Assert(plugin_info->estate == estate);
482454
Assert(plugin_info->fn_oid == estate->func->fn_oid);
483455

484-
#if PG_VERSION_NUM >= 180000
485-
486-
Assert(plugin_info->use_count == estate->func->cfunc.use_count);
487-
488-
#else
489-
490-
Assert(plugin_info->use_count == estate->func->use_count);
491-
492-
#endif
493-
494456
if (plugin_info->fextra)
495457
{
496458
if (estate->cur_error)
@@ -572,16 +534,6 @@ stmt_end(PLpgSQL_execstate *estate, PLpgSQL_stmt *stmt)
572534
Assert(plugin_info->estate == estate);
573535
Assert(plugin_info->fn_oid == estate->func->fn_oid);
574536

575-
#if PG_VERSION_NUM >= 180000
576-
577-
Assert(plugin_info->use_count == estate->func->cfunc.use_count);
578-
579-
#else
580-
581-
Assert(plugin_info->use_count == estate->func->use_count);
582-
583-
#endif
584-
585537
if (plugin_info->fextra)
586538
{
587539
Assert(plugin_info->stmts_stack_size > 0);

src/plpgsql_check.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ typedef struct
437437
{
438438
plch_fextra_hk hk;
439439
uint32 hashValue;
440+
PLpgSQL_function *func;
440441

441442
Oid fn_oid;
442443
char *fn_signature;

0 commit comments

Comments
 (0)