From c1ed64757d039f318a38d44d20086792ff1cfdf0 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Mon, 29 Jun 2026 23:22:16 +1200 Subject: [PATCH v2] ecpg: Fix auto_mem cleanup on thread exit. The pthread key destructor registered to free memory allocated with ecpg_auto_alloc() on thread exit had two problems: 1. It didn't do anything, because the OS clears the thread-specific slot (ie the value that get_auto_allocs() will return) before calling the destructor. We need to use the value that is passed to the destructor as an argument. 2. It was using ECPGfree_auto_mem(), but that would free the actual allocated values, and not just the list structure. The values are supposed to be freed by user code (for example the free(r) call in src/interfaces/ecpg/test/thread/alloc.pgc). We need to use ecpg_clear_auto_mem() instead, or valid .pgc code will double-free the most recently auto-allocated objects on thread exit. The destructor still doesn't run at all on Windows, but a proposed patch will address that problem. Discussion: Reviewed-by: --- src/interfaces/ecpg/ecpglib/memory.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/interfaces/ecpg/ecpglib/memory.c b/src/interfaces/ecpg/ecpglib/memory.c index 2112e55b6e4..b510b45b28c 100644 --- a/src/interfaces/ecpg/ecpglib/memory.c +++ b/src/interfaces/ecpg/ecpglib/memory.c @@ -80,11 +80,13 @@ struct auto_mem static pthread_key_t auto_mem_key; static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT; +static void ecpg_clear_auto_mem_list(struct auto_mem *am); + static void auto_mem_destructor(void *arg) { - (void) arg; /* keep the compiler quiet */ - ECPGfree_auto_mem(); + if (arg) + ecpg_clear_auto_mem_list((struct auto_mem *) arg); } static void @@ -161,16 +163,22 @@ ecpg_clear_auto_mem(void) { struct auto_mem *am = get_auto_allocs(); - /* only free our own structure */ if (am) { - do - { - struct auto_mem *act = am; - - am = am->next; - ecpg_free(act); - } while (am); + ecpg_clear_auto_mem_list(am); set_auto_allocs(NULL); } } + +static void +ecpg_clear_auto_mem_list(struct auto_mem *am) +{ + /* only free our own structure */ + do + { + struct auto_mem *act = am; + + am = am->next; + ecpg_free(act); + } while (am); +} -- 2.47.3