valgrind 报告 ecpg内存泄露 (三)

简介:
valgrind为何 报 ecpg内存泄露错误?根据我的同事的研究成果:

究其原因,全局变量 sqlca 由malloc形成,但是释放时是隐含的:

ecpg_sqlca_key_destructor函数调用 free 进行释放。

复制代码
bool
ECPGconnect(int lineno, int c, const char *name, const char *user, const char *passwd, const char *connection_name, int autocommit){
struct sqlca_t *sqlca = ECPGget_sqlca();
        ......
struct sqlca_t *
ECPGget_sqlca(void)
{
#ifdef ENABLE_THREAD_SAFETY
        struct sqlca_t *sqlca;
        pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
        sqlca = pthread_getspecific(sqlca_key);
        if (sqlca == NULL){
                sqlca = malloc(sizeof(struct sqlca_t));
                ecpg_init_sqlca(sqlca);
                pthread_setspecific(sqlca_key, sqlca);
        }
        return (sqlca);
#else
        return (&sqlca);
#endif
static void
ecpg_sqlca_key_init(void){
        pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor);
}
 
static void
ecpg_sqlca_key_destructor(void *arg){
        free(arg);        /* sqlca structure allocated in ECPGget_sqlca */
}
复制代码
用GDB来调试,也可以验证这一点:

复制代码
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-50.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.

(gdb) file memoryleak
Reading symbols from /usr/local/pgsql/bin/memoryleak...done.
(gdb) break main
Breakpoint 1 at 0x804875e: file memoryleak.pgc, line 51.
(gdb) run
Starting program: /usr/local/pgsql/bin/memoryleak
[Thread debugging using libthread_db enabled]
 
Breakpoint 1, main (argc=1, argv=0xbffff6f4) at memoryleak.pgc:51
51        PerformTask( 25 );
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.el6.i686
(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) break ecpg_sqlca_key_destructor
Breakpoint 2 at 0x1af9b2: file misc.c, line 124.
(gdb) list misc.c:124
119
120     #ifdef ENABLE_THREAD_SAFETY
121     static void
122     ecpg_sqlca_key_destructor(void *arg)
123     {
124             free(arg);                                      /* sqlca structure allocated in ECPGget_sqlca */
125     }
126
127     static void
128     ecpg_sqlca_key_init(void)
(gdb) break misc.c:147
Breakpoint 3 at 0x1afa4e: file misc.c, line 147.
(gdb) list misc.c:134,misc.c:149
134     struct sqlca_t *
135     ECPGget_sqlca(void)
136     {
137     #ifdef ENABLE_THREAD_SAFETY
138             struct sqlca_t *sqlca;
139
140             pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
141
142             sqlca = pthread_getspecific(sqlca_key);
143             if (sqlca == NULL)
144             {
145                     sqlca = malloc(sizeof(struct sqlca_t));
146                     ecpg_init_sqlca(sqlca);
147                     pthread_setspecific(sqlca_key, sqlca);
148             }
149             return (sqlca);
(gdb) cont
Continuing.
[New Thread 0xb7ff0b70 (LWP 2936)]
[Switching to Thread 0xb7ff0b70 (LWP 2936)]
Breakpoint 3, ECPGget_sqlca () at misc.c:147
147                     pthread_setspecific(sqlca_key, sqlca);
(gdb) where
#0  ECPGget_sqlca () at misc.c:147
#1  0x001aed62 in ECPGconnect (lineno=29, c=0, name=0xb7400468 "postgres@192.168.66.123:5432", user=0x804884b "postgres", passwd=0x804884b "postgres",
    connection_name=0x8048844 "dbConn", autocommit=0) at connect.c:268
#2  0x080486bf in Work () at memoryleak.pgc:29
#3  0x00117a49 in start_thread () from /lib/libpthread.so.0
#4  0x00353e1e in clone () from /lib/libc.so.6
(gdb) print sqlca
$1 = (struct sqlca_t *) 0xb7400490
(gdb) cont
Continuing.
conncet ok
Breakpoint 2, ecpg_sqlca_key_destructor (arg=0xb7400490) at misc.c:124
124             free(arg);                                      /* sqlca structure allocated in ECPGget_sqlca */
Missing separate debuginfos, use: debuginfo-install libgcc-4.4.6-4.el6.i686
(gdb) print arg
$2 = (void *) 0xb7400490
(gdb) cont
Continuing.
[Thread 0xb7ff0b70 (LWP 2936) exited] 
Program exited normally.
(gdb)
复制代码
我的追记:后来经过确认,这还不是全部,GDB运行时加了开关才会如此。

需要加入 pthread_exit(NULL)线程终止退出函数,才会触发。目前,仍然被认为是有内存泄漏的。

下面会记录我用普通方法得到的结论。


本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2012/08/14/2637933.html,如需转载请自行联系原作者
相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
Java Maven
Maven常用镜像配置
Maven常用镜像配置
2275 0
|
9月前
|
人工智能 自然语言处理 知识图谱
实战指南:基于【两大核心+四轮驱动】理论,制定高效Geo优化策略
随着生成式AI重塑信息获取方式,传统SEO正升级为GEO(生成式引擎优化)。本文解读于磊老师首创的【两大核心+四轮驱动】GEO理论,融合E-E-A-T原则,提出以人性化内容与权威性建设为核心,通过结构化数据、多模态覆盖、意图优化与持续监测,构建AI时代高效获客的内容战略。
836 1
|
SQL Oracle 关系型数据库
案例分析:你造吗?有个ORA-60死锁的解决方案
这段时间应用一直被一个诡异的 ORA-00060 的错误所困扰,众所周知,造成 ORA-00060 的原因是由于应用逻辑,而非 Oracle 数据库自己,之所以说诡异(“诡异”可能不准确,只能说这种场景,以前碰见的少,并未刻意关注),是因为这次不是常见的,由于读取数据顺序有交叉,导致ORA-0006.
2993 0
|
10月前
|
前端开发 JavaScript BI
如何开发车辆管理系统中的车务管理板块(附架构图+流程图+代码参考)
本文介绍了中小企业如何通过车务管理模块提升车辆管理效率。许多企业在管理车辆时仍依赖人工流程,导致违章处理延误、年检过期、维修费用虚高等问题频发。将这些流程数字化,可显著降低合规风险、提升维修追溯性、优化调度与资产利用率。文章详细介绍了车务管理模块的功能清单、数据模型、系统架构、API与前端设计、开发技巧与落地建议,以及实现效果与验收标准。同时提供了数据库建表SQL、后端Node.js/TypeScript代码示例与前端React表单设计参考,帮助企业快速搭建并上线系统,实现合规与成本控制的双重优化。
|
8月前
|
人工智能 算法 机器人
深度解析:政务服务机器人技术演进与主流产品选型指南
“放管服”改革下,政务机器人正从迎宾工具迈向“数字公务员”。依托神经符号AI、时空知识图谱、端侧VLM与SLAM导航等核心技术,实现精准审批、动态政策响应与智能服务。猎户星空、科大讯飞、优必选等产品各具优势,推动政务服务向高效化、人性化、智能化转型。
569 2
|
8月前
|
数据库 索引
索引创建的原则
创建索引需遵循六大原则:针对数据量大、查询频繁的表;在常用作查询、排序、分组的字段上建索引;优先选择区分度高或唯一的字段;varchar字段建议使用前缀索引;尽量创建联合索引,高区分度字段前置;避免过多索引,以降低维护成本,提升查询效率。
|
机器学习/深度学习 人工智能 开发者
如何让AI从简单的记忆型模型进化为具备深度推理能力的‘学霸’?—— 解析提升AI推理能力的四大核心技术
本文由AI专家三桥君探讨AI推理能力的四大核心技术:推理时间扩展、纯强化学习、标注数据+强化学习、知识蒸馏。通过对比记忆型与推理型AI的差异,分析显式与隐式推理的特点,揭示AI从"记忆答案"到"深度思考"的进化路径。三桥君指出,这些技术使AI在数学证明、编程等复杂任务中表现显著提升,但也面临算力成本与输出速度的平衡挑战。三桥君认为AI推理能力的发展将为科研、教育等领域带来革新,推动AI成为人类的"思考伙伴"。
861 0
|
算法 Go
【LeetCode 热题100】55:跳跃游戏(详细解析)(Go语言版)
本篇解析详细讲解了 LeetCode 热题 55——跳跃游戏(Jump Game)。通过判断是否能从数组起点跳至终点,介绍了两种高效解法:贪心算法和反向思维。贪心法通过维护最远可达位置 `maxReach` 实现一次遍历,时间复杂度 O(n),空间复杂度 O(1);反向法则从终点回溯,判断是否可到达起点。两者均简洁高效,适合面试使用。延伸题目如 LeetCode 45 进一步提升挑战。
555 7
|
安全 Java API
Spring Boot 功能模块全解析:构建现代Java应用的技术图谱
Spring Boot不是一个单一的工具,而是一个由众多功能模块组成的生态系统。这些模块可以根据应用需求灵活组合,构建从简单的REST API到复杂的微服务系统,再到现代的AI驱动应用。
1750 8
|
Java 测试技术 Maven
成功解决:nested exception is java.lang.NoClassDefFoundError: org/springframework/aop/TargetSource
这篇文章介绍了解决Spring框架中出现的`java.lang.NoClassDefFoundError: org/springframework/aop/TargetSource`错误的步骤,指出错误原因是缺少`spring-aop`模块的jar包,并提供了通过Maven依赖或手动添加jar包到项目中的方法来解决这个问题。
成功解决:nested exception is java.lang.NoClassDefFoundError: org/springframework/aop/TargetSource