[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freewnn:00195] Re: FreeWnn-1.1.1-a012 がタイムアウトします



片山@PFUです。

Date: Wed, 13 Oct 1999 22:51:50 +0900 (JST)
From: Katsuomi Hamajima/濱嶋克臣 <hamajima@nagoya.ydc.co.jp>

>ldexp(),erand48(),drand48()のソースを見ていたら、FreeBSDの3.2と2.2.8では
>変わっていないのでもしかしたらと思ったら、やっぱり2.2.8でも再現しました

これを見て、こちら(FreeBSD 2.2.7)でも試してみたら再現しました。

死んだ時の浮動小数点レジスターの状態が、

%st(7)    valid 3ffad6b7532510100000  0.0524209
%st(6)    valid 3ffe83b2a61f63780000  0.514445
%st(5)    valid 3ffee2dab15b2a230000  0.886149
%st(4)    valid 3ffde7733be0c5e40000  0.452051
%st(3)    valid 3ffa8114b578d1500000  0.0315139
%st(2)    valid 3ffbdc28131f7fe00000  0.107498
%st(1)    valid 3ffec5f1927996570000  0.773217
%st(0) => valid c004c000000000000000  -48

となって、全レジスターが有効で、更にロードしようとしてレジスター・
スタック・オーバーフローを起こしていました。

もしやと思って drand48 を呼出している部分を逆アセンブルしてみた
ら、

0x12212:        call   0x1d274 <_DYNAMIC+628> ; drand48
0x12217:        movl   %eax,%edx    ; retval -> edx
0x12219:        movl   %ebx,%eax    ; hindo
0x1221b:        sarl   $0x2,%eax    ; (hindo >> 2)
0x1221e:        incl   %eax         ; (hindo >> 2) + 1
0x1221f:        fld1                ; (double)1
0x12221:        pushl  %eax
0x12222:        fidivl (%esp,1)     ; (double)1 / ((hindo >> 2) + 1)
0x12225:        addl   $0x4,%esp
0x12228:        pushl  %edx         ; push retval
0x12229:        ficompl (%esp,1)    ; retval < (double)1 / …

となっていて、drand48() が整数型と思われているようです。このため、
hindo_set が呼ばれる度に浮動小数点レジスターが潰れていきます。(^^;

>いと発生しないようです。[freewnn:00185]で片山@PFUさんが書かれたサン
>プルでは、何か条件が足らないようです(サンプルは2.2.8でも問題なく動きまし
>た)

あのプログラムでは <stdlib.h> をインクルードしていたので動いてし
まっていたようです。

取り敢えず、

――――ここから――――ここから――――ここから――――ここから――――
--- do_hindo_s.c.ORG	Wed Sep 29 02:11:28 1999
+++ do_hindo_s.c	Thu Oct 14 17:44:49 1999
@@ -102,6 +102,7 @@
 {
 #ifdef HAVE_DRAND48
 #define RAND()  drand48()
+extern double drand48();
 #else
 #ifndef HAVE_RAND_MAX
 #define RAND_MAX ((1U<<31) - 1)
――――ここまで――――ここまで――――ここまで――――ここまで――――

のように、drand48() の宣言を入れると死ななくなります。

本来はここに drand48() の宣言を直接書くのではなく、<stdlib.h> を
インクルードすべきです。

ところで、“#define RAND_MAX ((1U<<31) - 1)”ですが、K&R C でエ
ラーになってしまいますので、

#define RAND_MAX (((unsigned)1<<31) - 1)

としておいて下さい。

Date: Thu, 14 Oct 1999 18:00:06 +0900 (JST)
From: Katsuomi Hamajima/濱嶋克臣 <hamajima@nagoya.ydc.co.jp>

>IA-32知っている人、教えてください

済みません。IA-32 って、何でしょうか。

>表示されるデータの一行目最後にある "top" が減っています。たしか8087系は
>registerをstackのようにして使うと本で読んだことがありますが、これが直接
>的な原因なのでしょうか?

はい。そうです。

># registerが8本で、8回目に落ちる。うーん、すじつまはあっているように思
># える

これは、文節が一つの時ですよね。「私の名前は中野です。」なら、3
回目に落ちるはずです。

>にしくさんのところのOpenBSD/i386では起らないようなので、これが原因なら
>drand48()でなくFreeBSDのfloating registerの扱い方がおかしいということに
>なります

OpenBSD/i386 では、どこかのインクルードファイルに drand48() の宣
言が入っているのではないでしょうか。
--
片山@PFU