zoukankan      html  css  js  c++  java
  • pgpoolII3.1 的内存泄漏(四)

    磨砺技术珠矶,践行数据之道,追求卓越价值
    回到上一级页面: PostgreSQL集群方案相关索引页     回到顶级页面:PostgreSQL索引页
    [作者 高健@博客园  luckyjackgao@gmail.com]

    接上文,继续对pgpool-II3.1的内存泄漏进行分析。

    情形A extract_string 调用 strdup

    ==27927== 3 bytes in 1 blocks are possibly lost in loss record 3 of 100
    ==27927== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
    ==27927== by 0x3C51E798C1: strdup (in /lib64/libc-2.5.so)
    ==27927== by 0x40C9C4: extract_string (pool_config.l:2065)
    ==27927== by 0x410D52: pool_get_config (pool_config.l:1756)
    ==27927== by 0x4066B5: main (main.c:320)
    ==27927==

    从上述log可知, 调用关系如下:
    main->pool_get_config -> extract_string -> strdup->malloc

    以下是各个函数的主要相关逻辑:
    pool_get_config函数(中间省略了很多):

    int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context){  
    ...... #define PARSE_ERROR()

    pool_error("pool_config: parse error at line %d '%s'", Lineno, yytext) /* open config file */ fd = fopen(confpath, "r"); if (!fd){ fprintf(stderr, "pool_config: could not open configuration file (%s)\n", POOL_CONF_FILE_NAME); fprintf(stderr, "pool_config: using default values...\n"); return 0; } yyin = fd; Lineno = 1; for(;;) { token = yylex(); if (token == 0){ break; } if (token == POOL_PARSE_ERROR){ PARSE_ERROR(); fclose(fd); return(-1); } if (token == POOL_EOL) continue; if (token != POOL_KEY){ PARSE_ERROR(); fclose(fd); return(-1); } …… if (!strcmp(key, "allow_inet_domain_socket") &&
    CHECK_CONTEXT(INIT_CONFIG, context)){ …… }
    else if (!strcmp(key, "listen_addresses") &&
    CHECK_CONTEXT(INIT_CONFIG, context)){
    char *str; if (token != POOL_STRING && token != POOL_UNQUOTED_STRING &&

    token != POOL_KEY){ PARSE_ERROR(); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL){ fclose(fd); return(-1); } pool_config->listen_addresses = str; } …… else if (!strncmp(key, "backend_hostname", 16) && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) && mypid == getpid())
    /* this parameter must be modified by parent pid */ { int slot; char *str; slot = atoi(key + 16); if (slot < 0 || slot >= MAX_CONNECTION_SLOTS) { pool_error("pool_config:
    backend number %s for backend_hostname out of range
    ", key); fclose(fd); return(-1); } str = extract_string(yytext, token); if (str == NULL){ fclose(fd); return(-1); } if (context == INIT_CONFIG || (context == RELOAD_CONFIG &&

    BACKEND_INFO(slot).backend_status == CON_UNUSED)) strncpy(BACKEND_INFO(slot).backend_hostname, str,
    MAX_DB_HOST_NAMELEN); } ……
    else if (!strcmp(key, "relcache_expire") &&

    CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context)){ int v = atoi(yytext); if (token != POOL_INTEGER || v < 0){ pool_error("pool_config: %s
    must be equal or higher than 0 numeric value
    ", key); fclose(fd); return(-1); } pool_config->relcache_expire = v; } } fclose(fd); …… return 0; }

     extract_string 函数:

    static char *extract_string(char *value, POOL_TOKEN token){                        
        char *ret;          
        ret = strdup(value);                    
        if (!ret){                    
            pool_error("extract_string: out of memory");                
            return NULL;                
        }                    
                            
        if (token == POOL_STRING){                    
            ret[strlen(ret)-1] = '\0';                
            return (ret+1);                
        }                    
        return ret;                    
    }

    strdup 是C 语言的标准函数, 是字符串复制。
    其内部调用了 malloc ,在运行结束的时候,应当释放。

    但是!  
    由于其 是在 pool_config.c 的 pool_get_config 中被调用,
    这个函数 是要实现 把配置文件中的各项内容读取出来。
    配置文件项内容的地址,就存储在 strdup 返回的 指针里面。

    在pgpool 运行结束以前, 都是需要能随时访问 配置文件向内容的。
    所以,在pgpool运行结束以前,都是不能随意 释放 strdup返回 值的。

    至于运行结束的那一刻 是否 有代码专门来释放了,前面我们的分析已经说过,不在我们的讨论范围内。

    [作者 高健@博客园  luckyjackgao@gmail.com]
    回到上一级页面: PostgreSQL集群方案相关索引页     回到顶级页面:PostgreSQL索引页
    磨砺技术珠矶,践行数据之道,追求卓越价值

  • 相关阅读:
    JSONObject登录接口
    HttpClient跨域请求post
    线段树个人理解及模板
    Python基本语法(一)
    Boyer-Moore算法
    Sunday算法浅谈
    Kmp算法浅谈
    bm坏字符 , Horspool算法 以及Sunday算法的不同
    字典树的建立和基本查找
    CF Round551 Div2 题解
  • 原文地址:https://www.cnblogs.com/gaojian/p/2649037.html
Copyright © 2011-2022 走看看