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
目录
相关文章
|
存储 XML NoSQL
提高代码质量,避免内存泄漏:深入探索Valgrind工具
提高代码质量,避免内存泄漏:深入探索Valgrind工具
|
6月前
|
IDE Linux 开发工具
内存泄漏检测工具Valgrind:C++代码问题检测的利器(一)
内存泄漏检测工具Valgrind:C++代码问题检测的利器
1519 0
|
6月前
|
缓存 Linux iOS开发
【C/C++ 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南
【C/C++ 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南
605 1
|
6月前
|
缓存 测试技术 开发工具
内存泄漏检测工具Valgrind:C++代码问题检测的利器(二)
内存泄漏检测工具Valgrind:C++代码问题检测的利器
178 0
|
6月前
|
XML NoSQL Linux
内存泄漏专题(3)内存泄漏调试神器valgrind
内存泄漏专题(3)内存泄漏调试神器valgrind
111 0
|
6月前
|
XML 存储 NoSQL
内存泄漏检测工具valgrind神器
内存泄漏检测工具valgrind神器
132 0
Linux系统调试篇——valgrind内存泄露检测
Linux系统调试篇——valgrind内存泄露检测
|
缓存 监控 Linux
嵌入式 linux 内存泄漏分析工具(1):valgrind
嵌入式 linux 内存泄漏分析工具(1):valgrind
1227 0
|
Ubuntu Linux 编译器
【Linux】内存检测工具Valgrind
【Linux】内存检测工具Valgrind
|
XML 存储 缓存
内存泄漏检测神器valgrind
Valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。
689 0