[pgcluster: 78] load balancer
川村 純一
jkawa @ m.email.ne.jp
2004年 2月 4日 (水) 14:15:16 JST
川村と申します。
FreeBSD 5.2R 上で PGCluster-1.0.6b を動かしていますが、ロードバランサを
経由して空文字列をフィールドとして持つテーブルにアクセスすると、signal 11
が飛んで pglb が core dump してしまう現象が起きています。
直接マスタDBなりクラスタサーバなりに接続して同じテーブルにアクセスしても
この問題は起きません。
gdb で追ってみると、AsciiRow() 内の snprintf() で落ちているようです。
(gdb) where
#0 0x2813d378 in __vfprintf () from /lib/libc.so.5
#1 0x28139323 in snprintf () from /lib/libc.so.5
#2 0x0804e01b in AsciiRow (frontend=0x8057080, backend=0x80570c0,
num_fields=28) at pool_process_query.c:480
#3 0x0804d9dd in pool_process_query (frontend=0x8057080, backend=0x80570c0,
connection_reuse=0) at pool_process_query.c:225
#4 0x0804a6e1 in PGRdo_child (recv_sock=4, cluster_p=0x30048000, use_pool=1)
at child.c:299
#5 0x0804ad82 in do_pooling_child (sig=30) at child.c:582
#6 <signal handler called>
#7 0x280daa0f in sigsuspend () from /lib/libc.so.5
#8 0x280d1178 in pause () from /lib/libc.so.5
#9 0x0804a919 in PGRcreate_child (fd=3, cluster_p=0x30048000) at child.c:372
#10 0x0804a286 in PGRpre_fork_children (fd=3, ptr=0x30048000) at child.c:133
#11 0x0804c09b in load_balance_main () at main.c:385
#12 0x0804caea in main (argc=3, argv=0xbfbfed70) at main.c:859
#13 0x080492c2 in _start ()
ソースを追ってみたところ、AsciiRow() での処理において、そのフィールドを
処理するかどうかの分岐条件を NULL かどうかだけで見ていて空文字列のフィー
ルドを弾けず、その結果空文字列フィールドのデータを格納する領域を確保し
ようとして malloc(0) が call されてしまい、その返り値であるポインタ変数
buf に snprintf() でアクセスし、signal 11 が飛んでしまう、という現象が
起こっているように思います。
とりあえず size が 0 の場合は以降の処理を行わないというコードを追加して
ひとおり動作はしているようですが、adhoc な感は否めません。この場合、ど
のように修正するのがよいのでしょうか。
念のため、こちらで行った修正を付けておきます。
-----------------------------------------------------------------------
*** pool_process_query.c.orig Wed Feb 4 13:47:18 2004
--- pool_process_query.c Wed Feb 4 13:50:42 2004
***************
*** 459,478 ****
pool_write(frontend, &size, sizeof(int));
size = htonl(size) - 4;
! buf = malloc(size);
! if (buf == NULL)
{
! show_error("AsciiRow: out of memory");
! return POOL_END;
! }
! /* actual data */
! if (pool_read(backend, buf, size) < 0)
! return POOL_END;
! pool_write(frontend, buf, size);
! snprintf(msgbuf, Min(sizeof(msgbuf), size), "%s", buf);
! show_debug("AsciiRow: len:%d data: %s", size, msgbuf);
! free(buf);
}
mask >>= 1;
}
--- 459,481 ----
pool_write(frontend, &size, sizeof(int));
size = htonl(size) - 4;
! if (size > 0)
{
! buf = malloc(size);
! if (buf == NULL)
! {
! show_error("AsciiRow: out of memory");
! return POOL_END;
! }
! /* actual data */
! if (pool_read(backend, buf, size) < 0)
! return POOL_END;
! pool_write(frontend, buf, size);
! snprintf(msgbuf, Min(sizeof(msgbuf), size), "%s", buf);
! show_debug("AsciiRow: len:%d data: %s", size, msgbuf);
! free(buf);
! }
}
mask >>= 1;
}
-----------------------------------------------------------------------
--
川村 純一 (Junichi Kawamura)
mailto: jkawa @ m.email.ne.jp
pgcluster メーリングリストの案内