PostgreSQL ECPG及16版本:PREPARE错误查询致内存非法释放崩溃问题
ECPG手动释放主机变量后,错误PREPARE触发重复free崩溃的问题
问题现象
PostgreSQL 6版本的ECPG存在崩溃问题,且该问题在PostgreSQL 16等后续版本中仍未修复。Valgrind捕获的崩溃日志如下:
==31300== Invalid free() / delete / delete[] / realloc() ==31300== at 0x4C3210C: free (vg_replace_malloc.c:538) ==31300== by 0x5071C13: ECPGfree_auto_mem (in /bdd/usr/pgsql/lib/libecpg.so.6.6) ==31300== by 0x5070CF5: ??? (in /bdd/usr/pgsql/lib/libecpg.so.6.6) ==31300== by 0x507124B: ??? (in /bdd/usr/pgsql/lib/libecpg.so.6.6) ==31300== by 0x50716D4: ECPGprepare (in /bdd/usr/pgsql/lib/libecpg.so.6.6)
该崩溃会100%复现在以下场景:
- 先执行一条成功的
SELECT column into :hostVariable from ...查询,其中hostVariable为char*类型 - 手动调用
free(hostVariable)释放该变量 - 执行一条存在语法错误的
PREPARE语句(例如截断的查询语句"order by bigint")
复现代码
EXEC SQL BEGIN DECLARE SECTION; char * hostVariable = NULL; EXEC SQL END DECLARE SECTION; EXEC SQL SELECT my_column INTO :hostVariable FROM my_table LIMIT 1; free(hostVariable); EXEC SQL BEGIN DECLARE SECTION; const char * cRequest = "order by bigint"; EXEC SQL END DECLARE SECTION; // 崩溃发生在此处 EXEC SQL PREPARE prepare_crash FROM :cRequest ;
临时解决方案及疑问
将手动free(hostVariable)替换为调用ECPGfree_auto_mem()后,当前示例中的崩溃和内存泄漏问题均得到解决。推测原因是ECPG通过该内部函数统一管理主机变量内存,避免了后续错误PREPARE操作时的重复释放。
但ECPGfree_auto_mem()并未在官方ECPG文档中提及,因此存在以下疑问:
- 是否存在更复杂的场景(如多线程环境、嵌套查询、多主机变量混合使用等)会导致该方法失效?
- 使用
ECPGfree_auto_mem()是否会引发性能相关问题?
内容的提问来源于stack exchange,提问作者moonychan
相关产品推荐
相关产品推荐

