[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]

[webdav-jp:0437] Tru64 UNIX で mod_dav を利用する場合のパッチ



古澤と申します。このメーリングリストへの投稿は、初めてになります。
Tru64 UNIX で WebDAV 環境を構築してトラブルが発生したのですが
なんとか解決できたので、ご報告します。

使用しているバージョンは以下の通りで、WebDAV Resources JPの情報を
参考にしながら、WebDAVの環境を構築しています。

	OS: Tru64 UNIX Version 5.1
	Apache: 1.3.24
	mod_dav: 1.0.3
	mod_encoding: 20020611a
	クライアント: WindowsXP Professional

このような環境で動作確認をしたのですが、クライアント側から
いろいろとオペレーションすると、サーバ側で httpd が次々と
落ちて core を吐いてしまいました。酷いときには、WebDAV の
フォルダを開いただけで core を吐くので、とても使えない状態でした。

こういう時に、どんな風にデバッグするものなのか判らなかったのですが、
少なくとも mod_dav から呼ばれるどこかが怪しいのだろうと思い、
printf を埋め込みまくって調査したところ、問題箇所がありましたので
報告します。

動作が怪しい箇所は、dav_fs_dbm.c にある dav_dbm_fetch() の中の

	*(datum *) pvalue = DAV_DBM_FETCH(db->file, D2G(key));

の代入のところのようです。ここで pvalue というのは、dav_datum * 型ですが
datum * 型にキャストされています。

dav_datum は、mod_dav.h で

	typedef struct {
		char *dptr;
		size_t dsize;
	} dav_datum;

と定義されており、また datum は、sdbm.h で

	typedef struct {
		char *dptr;
		int dsize;
	} datum;

と定義されています。
違いは、dsize の型が、一方は size_t で、他方は int である事です。
Tru64 UNIX の場合、int は 4バイトで、size_t は 8バイトあります。

この場合、printf を使ったデバッグ出力を見ると、次のような動作をしているようです。

dav_props.c(853): sizeof(char *) = 8
dav_props.c(854): sizeof(int)    = 4
dav_props.c(855): sizeof(size_t) = 8
dav_props.c(856): value = {0, (size_t)0}
dav_props.c(857): value = {0,    (int)0}
sdbm/sdbm_pair.c(114): val = {140071f5d, (size_t)36}
sdbm/sdbm_pair.c(115): val = {140071f5d,    (int)36}
dav_props.c(865): value = {140071f5d, (size_t)4294967332}
dav_props.c(866): value = {140071f5d,    (int)36}
[Thu Jun 13 12:05:45 2002] [notice] child pid 223108 exit signal Segmentation fault (11), possible coredump in /usr/local/apache/var

この問題を解決するために、構造体 datum の dsize の型を int から size_t に
変更すると、綺麗に動いてくれるようです。この時のデバッグ出力は、

dav_props.c(856): value = {0, (size_t)0}
dav_props.c(857): value = {0,    (int)0}
sdbm/sdbm_pair.c(114): val = {14007475d, (size_t)36}
sdbm/sdbm_pair.c(115): val = {14007475d,    (int)36}
dav_props.c(865): value = {14007475d, (size_t)36}
dav_props.c(866): value = {14007475d,    (int)36}

こうなります。

このような修正方法が適切なのかは判断できませんが、
この状態で使ってみて様子をみようと思います。
この修正のパッチを以下に添付します。

また mod_encoding においても、LOG() の定義が、GCC 拡張や C99 拡張を
使っているために、Tru64 UNIX 標準の cc では動作しませんでした。
これは、CPP が引数を完全に展開しないためで、コンパイルはできてしまうのですが、
実行時に、期待する引数が得られないために、アクセスバイオレーションに
なってしまっていました。

この件は、LOG2() というマクロを定義して回避しました。

以上のような変更で、WebDAV 環境が作れたので
これからいろいろと試してみようと思います。
-- 
FURUSAWA Kazumi <kazumi@xxxxxxxxxxxxxxxxx>

diff -rc /tmp/mod_dav-1.0.3-1.3.6/dav_props.c /usr/local/src/mod_dav-1.0.3-1.3.6/dav_props.c
*** /tmp/mod_dav-1.0.3-1.3.6/dav_props.c        2001年11月05日 16時08分21秒
--- /usr/local/src/mod_dav-1.0.3-1.3.6/dav_props.c      2002年06月13日 12時02分26秒
***************
*** 849,859 ****
--- 849,870 ----
      if (propdb->db != NULL) {
        key.dptr = DAV_GDBM_NS_KEY;
        key.dsize = DAV_GDBM_NS_KEY_LEN;
+ #ifdef TRU64DEBUG
+       fprintf(stderr, "%s(%d): sizeof(char *) = %d\n", __FILE__, __LINE__, sizeof(char *));
+       fprintf(stderr, "%s(%d): sizeof(int)    = %d\n", __FILE__, __LINE__, sizeof(int)   );
+       fprintf(stderr, "%s(%d): sizeof(size_t) = %d\n", __FILE__, __LINE__, sizeof(size_t));
+       fprintf(stderr, "%s(%d): value = {%p, (size_t)%lu}\n", __FILE__, __LINE__, value.dptr, (size_t)value.dsize);
+       fprintf(stderr, "%s(%d): value = {%p,    (int)%lu}\n", __FILE__, __LINE__, value.dptr,    (int)value.dsize);
+ #endif
        if ((err = (*propdb->db_hooks->fetch)(propdb->db, key,
                                              &value)) != NULL) {
            /* ### push a higher-level description? */
            return err;
        }
+ #ifdef TRU64DEBUG
+       fprintf(stderr, "%s(%d): value = {%p, (size_t)%lu}\n", __FILE__, __LINE__, value.dptr, (size_t)value.dsize);
+       fprintf(stderr, "%s(%d): value = {%p,    (int)%lu}\n", __FILE__, __LINE__, value.dptr,    (int)value.dsize);
+ #endif
      }
      if (value.dptr == NULL) {
        dav_propdb_metadata m = {
diff -rc /tmp/mod_dav-1.0.3-1.3.6/sdbm/sdbm.h /usr/local/src/mod_dav-1.0.3-1.3.6/sdbm/sdbm.h
*** /tmp/mod_dav-1.0.3-1.3.6/sdbm/sdbm.h        1999年02月13日 03時50分21秒
--- /usr/local/src/mod_dav-1.0.3-1.3.6/sdbm/sdbm.h      2002年06月13日 12時08分22秒
***************
*** 49,58 ****
--- 49,66 ----
  #define sdbm_dirfno(db)       ((db)->dirf)
  #define sdbm_pagfno(db)       ((db)->pagf)

+ #ifdef __alpha
+ #include <stddef.h>
  typedef struct {
        char *dptr;
+       size_t dsize;
+ } datum;
+ #else
+ typedef struct {
+       char *dptr;
        int dsize;
  } datum;
+ #endif

  extern datum nullitem;

diff -rc /tmp/mod_dav-1.0.3-1.3.6/sdbm/sdbm_pair.c /usr/local/src/mod_dav-1.0.3-1.3.6/sdbm/sdbm_pair.c
*** /tmp/mod_dav-1.0.3-1.3.6/sdbm/sdbm_pair.c   1999年02月13日 03時50分21秒
--- /usr/local/src/mod_dav-1.0.3-1.3.6/sdbm/sdbm_pair.c 2002年06月13日 12時05分27秒
***************
*** 12,17 ****
--- 12,20 ----
  #include "sdbm_pair.h"

  #include <string.h>   /* for memset() */
+ #ifdef TRU64DEBUG
+ #include <stdio.h>
+ #endif


  #define exhash(item)  sdbm_hash((item).dptr, (item).dsize)
***************
*** 107,112 ****
--- 110,119 ----

        val.dptr = pag + ino[i + 1];
        val.dsize = ino[i] - ino[i + 1];
+ #ifdef TRU64DEBUG
+       fprintf(stderr, "%s(%d): val = {%p, (size_t)%lu}\n", __FILE__, __LINE__, val.dptr, (size_t)val.dsize);
+       fprintf(stderr, "%s(%d): val = {%p,    (int)%u}\n",  __FILE__, __LINE__, val.dptr,    (int)val.dsize);
+ #endif
        return val;
  }