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