You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 05:25:02