日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pgpool-II3.1 的内存泄漏(四)

發布時間:2024/6/14 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pgpool-II3.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索引頁
磨礪技術珠磯,踐行數據之道,追求卓越價值

轉載于:https://www.cnblogs.com/gaojian/archive/2012/08/21/2649037.html

總結

以上是生活随笔為你收集整理的pgpool-II3.1 的内存泄漏(四)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。