[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 メーリングリストの案内