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
目录
相关文章
|
11月前
|
Java 开发者 Spring
精通SpringBoot:16个扩展接口精讲
【10月更文挑战第16天】 SpringBoot以其简化的配置和强大的扩展性,成为了Java开发者的首选框架之一。SpringBoot提供了一系列的扩展接口,使得开发者能够灵活地定制和扩展应用的行为。掌握这些扩展接口,能够帮助我们写出更加优雅和高效的代码。本文将详细介绍16个SpringBoot的扩展接口,并探讨它们在实际开发中的应用。
316 1
|
Dart 开发工具 Android开发
在 Android 系统上搭建 Flutter 环境的具体步骤是什么?
在 Android 系统上搭建 Flutter 环境的具体步骤是什么?
|
JavaScript API
【Vue3的组合式API】超详细教程,含computed、watch、组件通信、模版引用......
【Vue3的组合式API】超详细教程,含computed、watch、组件通信、模版引用......
|
SQL 前端开发 Java
迄今为止最好用的Flink SQL教程:Flink SQL Cookbook on Zeppelin
无需写任何代码,只要照着这篇文章轻松几步就能跑各种类型的 Flink SQL 语句。
迄今为止最好用的Flink SQL教程:Flink SQL Cookbook on Zeppelin
|
数据采集 前端开发 Python
【项目】全国疫情实时追踪——python爬虫+flask+echarts实现(超详细)(一)
【项目】全国疫情实时追踪——python爬虫+flask+echarts实现(超详细)(一)
811 0
【项目】全国疫情实时追踪——python爬虫+flask+echarts实现(超详细)(一)
|
Cloud Native 安全 中间件
阿里云:龙蜥操作系统开源一年后总装机量破 130 万
5 月 24 日,龙蜥社区宣布,自发布首个开源版本一年来,龙蜥操作系统整体装机量已达 130 多万,生态伙伴超过 200 家,有效应对了 CentOS 8 停服以来的替代需求。
274 0
|
弹性计算 人工智能