zoukankan      html  css  js  c++  java
  • 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)线程终止退出函数,才会触发。目前,仍然被认为是有内存泄漏的。

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

  • 相关阅读:
    如何查看python的当前版本号
    Android数据库程序开发必备工具SqliteDev 狼人:
    Android四种Activity的加载模式 狼人:
    20+ 个很棒的 jQuery 文件上传插件或教程(此文值得“推荐”和“收藏”) 狼人:
    艾伟:10分钟去除天天团购系统版权 狼人:
    WIN7,server2008 IIS 伪静态 不能显示特殊图片 加号 减号 “+”,""号的图片需要转义才可以显示 狼人:
    近百余款最新HTML5应用案例给大伙儿共享了 狼人:
    shopex李钟伟:独立电子商务发展与网络购物 狼人:
    《天将客户关系管理系统》 狼人:
    Shopex V4.8.4 V4.8.5 后台拿Shell 0Days 狼人:
  • 原文地址:https://www.cnblogs.com/gaojian/p/2637933.html
Copyright © 2011-2022 走看看