[pgpool-general-jp: 81] Re: pgpoolのprepared_listについて

Yoshiyuki Asaba y-asaba @ sraoss.co.jp
2007年 1月 22日 (月) 20:35:05 JST


浅羽です。

From: Kenichi Sawada <k @ sawada.cc>
Subject: [pgpool-general-jp: 79] Re: pgpoolのprepared_listについて
Date: Mon, 22 Jan 2007 19:54:32 +0900 (JST)

> 浅羽さん、パッチありがとうございます。御返信遅くなり申し訳ありません。
> パッチの中で気になった点がありまして、
省略
> この部分がちょっと良く判らなかったのですが、strdupの対象は
> stmt->portal_nameの方がよいのでしょうか?

すみません、その通りです。


> また、頂いたパッチで前回お送りしたPerlスクリプトを実行すると
> *** glibc detected *** double free or corruption (faststop): 0xxxxxxxxx ***
> というエラーが出てしまうようです。
> これは恐らく2726行目あたりの
> if (stmt == NULL)
> 	 free(name);
> else if (*portal_name == '\0')
> のfreeでエラーが発生しているものと思われますが、
> (微妙によくわかっていないのですが
> 2727行目のfree(name)はどういう場合に必要になるのでしょうか。。?)
> 遡ると2720〜2721行目のsprintfとlookup_prepared_statement_by_statementが
> 悪さをしているようです。

はい、2重解放していました…。


> 可能であれば、正規化はprepared_listに登録/削除する直前、並びにlookupする直前
> に行うのがよいかと思いますが、いかがでしょうか?
> 御検討頂ければと存じます。どうぞ宜しくお願い致します。

Parse と Bind メッセージの場合は大文字と小文字を区別しないといけないた
め "" で囲んでいましたが、必要無くなったので strdup() するように修正し
ました。

澤田さんの再現スクリプトでも正しく動くパッチを添付します。
--
Yoshiyuki Asaba
y-asaba @ sraoss.co.jp
-------------- next part --------------
Index: pool_process_query.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool/pool_process_query.c,v
retrieving revision 1.36
diff -c -r1.36 pool_process_query.c
*** pool_process_query.c	13 Jan 2007 11:13:38 -0000	1.36
--- pool_process_query.c	22 Jan 2007 11:31:34 -0000
***************
*** 2620,2626 ****
  	int len;
  	int sendlen;
  	char *p;
- 	int name_len;
  	char *name = NULL;
  
  	if (pool_write(MASTER(backend), &kind, 1))
--- 2620,2625 ----
***************
*** 2710,2749 ****
  			stmt = unnamed_statement;
  		else
  		{
! 			name = malloc(strlen(stmt_name) + 3);
  			if (name == NULL)
  			{
! 				pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
  				return POOL_END;
  			}
  
- 			sprintf(name, "\"%s\"", stmt_name);
  			stmt = lookup_prepared_statement_by_statement(&prepared_list, name);
  			free(name);
  		}
  
! 		if (stmt == NULL)
! 			free(name);
! 		else if (*portal_name == '\0')
  			unnamed_portal = stmt;
  		else
  		{
  			if (stmt->portal_name)
  				free(stmt->portal_name);
! 			stmt->portal_name = strdup(stmt->portal_name);
  		}
  
  	}
  	else if (kind == 'C' && *p == 'S' && *(p + 1))
  	{
! 		name_len = strlen(p + 1) + 3;
! 		name = malloc(name_len);
  		if (name == NULL)
  		{
! 			pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
  			return POOL_END;
  		}
- 		sprintf(name, "\"%s\"", p + 1);
  		pending_function = del_prepared_list;
  		pending_prepared_stmt = malloc(sizeof(PreparedStatement));
  		if (pending_prepared_stmt == NULL)
--- 2709,2743 ----
  			stmt = unnamed_statement;
  		else
  		{
! 			name = strdup(stmt_name);
  			if (name == NULL)
  			{
! 				pool_error("SimpleForwardToBackend: strdup failed: %s", strerror(errno));
  				return POOL_END;
  			}
  
  			stmt = lookup_prepared_statement_by_statement(&prepared_list, name);
  			free(name);
  		}
  
! 		if (*portal_name == '\0')
  			unnamed_portal = stmt;
  		else
  		{
  			if (stmt->portal_name)
  				free(stmt->portal_name);
! 			stmt->portal_name = strdup(portal_name);
  		}
  
  	}
  	else if (kind == 'C' && *p == 'S' && *(p + 1))
  	{
! 		name = strdup(p+1);
  		if (name == NULL)
  		{
! 			pool_error("SimpleForwardToBackend: strdup failed: %s", strerror(errno));
  			return POOL_END;
  		}
  		pending_function = del_prepared_list;
  		pending_prepared_stmt = malloc(sizeof(PreparedStatement));
  		if (pending_prepared_stmt == NULL)


pgpool-general-jp メーリングリストの案内