[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]
[webdav-jp:0437] Tru64 UNIX で mod_dav を利用する場合のパッチ
- To: webdav-jp@xxxxxxxx
- Subject: [webdav-jp:0437] Tru64 UNIX で mod_dav を利用する場合のパッチ
- From: FURUSAWA Kazumi <kazumi@xxxxxxxxxxxxxxxxx>
- Date: Thu, 13 Jun 2002 20:45:13 +0900
- Delivered-to: webdav-jp@begi.net
- Posted: Thu, 13 Jun 2002 20:44:35 +0900
- User-agent: Wanderlust/2.8.1 (Something) SEMI/1.14.3 (Ushinoya) FLIM/1.14.3 (Unebigoryōmae) APEL/10.3 Emacs/20.7 (i386--freebsd) MULE/4.0 (HANANOEN)
古澤と申します。このメーリングリストへの投稿は、初めてになります。
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;
}