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
目录
相关文章
|
5月前
|
人工智能 监控 机器人
【Valgrind】如何使用Valgrind监控内存
【Valgrind】如何使用Valgrind监控内存
|
5月前
|
监控 NoSQL Linux
深入Linux内存泄漏排查:Valgrind与系统工具的联合应用
深入Linux内存泄漏排查:Valgrind与系统工具的联合应用
744 0
|
5月前
|
IDE Linux 开发工具
内存泄漏检测工具Valgrind:C++代码问题检测的利器(一)
内存泄漏检测工具Valgrind:C++代码问题检测的利器
1228 0
|
5月前
|
缓存 测试技术 开发工具
内存泄漏检测工具Valgrind:C++代码问题检测的利器(二)
内存泄漏检测工具Valgrind:C++代码问题检测的利器
144 0
|
5月前
|
XML NoSQL Linux
内存泄漏专题(3)内存泄漏调试神器valgrind
内存泄漏专题(3)内存泄漏调试神器valgrind
68 0
|
5月前
|
XML 存储 NoSQL
内存泄漏检测工具valgrind神器
内存泄漏检测工具valgrind神器
122 0
|
XML 存储 缓存
内存泄漏检测神器valgrind
Valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。
677 0
|
分布式计算 Hadoop Linux
C/C++的内存泄漏检测工具Valgrind memcheck的使用经历
Linux下的Valgrind真是利器啊(不知道Valgrind的请自觉查看参考文献(1)(2)),帮我找出了不少C++中的内存管理错误,前一阵子还在纠结为什么VS 2013下运行良好的程序到了Linux下用g++编译运行却崩溃了,给出一堆汇编代码也看不懂。
1477 0
基于WinDbg的内存泄漏分析
在前面C++中基于Crt的内存泄漏检测一文中提到的方法已经可以解决我们的大部分内存泄露问题了,但是该方法是有前提的,那就是一定要有源代码,而且还只能是Debug版本调试模式下。实际上很多时候我们的程序会用到第三方没有源代码的模块,有些情况下我们甚至怀疑系统模块有内存泄露,但是有没有证据,我们该怎么办? 这时我们就要依靠无所不能的WinDbg了。
1146 0
使用valgrind检查内存问题
作者:gfree.wind@gmail.com 博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net    本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。
985 0