Gauche:Bugs:log10

Gauche:Bugs:log10


Linux/AMD64のdouble->half

Rui (2007/05/14 20:35:58 PDT): Lingrに書いた件。Linux/AMD64でsrc/test-arith.cの次のテストに失敗するようです。

test_half("double->half, rounding", 0x3ffe,
          Scm_DoubleToHalf(1.99853515625));  /* m=#b1111111110.10 */
 testing double->half, rounding, expects 3ffe =>ERROR: got 3fff

備前さんの話だとNetBSD/amd64では次のエラーがでるとのこと。エラーになるテストが違います。

testing double->half, rounding, expects 3fff =>ERROR: got 3ffe

string-upcase!/downcase! が引数を要求する? (0.8.10)

srfi-13 で (string-downcase! str) とするとエラーになります。

gosh> (use srfi-13)
#<undef>
gosh> (define s (list->string (string->list "HELLO"))) ;; mutable string のつもり
s
gosh> s
"HELLO"
gosh> (string-downcase s) ;; これは期待通り。(副作用なし)
"hello"
gosh> s
"HELLO"
gosh> (string-downcase! s) ;; ここが期待とは違う。(副作用あり!)
*** ERROR: real number required: #<undef>
Stack Trace:
_______________________________________
gosh> (string-downcase! s 0 1) ;; start と end を与えると動く。
"hELLO"
gosh> s
"hELLO"
gosh> (string-downcase! s 0) ;; start=0 だと動かないんだけど、
*** ERROR: real number required: #<undef>
Stack Trace:
_______________________________________
gosh> (string-downcase! s 1) ;; start=1 だと動く。
"hello"
gosh> s
"hello"

Gauche 0.8.8 までは動いていたんですけど, Gauche 0.8.10 にバージョンアップしたら動かなくなってしまいました。yuki (2007/07/31 06:54:23 PDT)

(hash-table-put! (make-hash-table 'string=?) () 1) でsegmentation fault(0.8.10)

'string=?を比較関数としたハッシュテーブルに、キー()で値を入れると、セグメンテーション違反になりました。 環境は、Linux(Fedora core 3) i386 32bitです。

gensymで生成したシンボルとstring->symbolで生成したシンボルが一致しない (0.8.10)

koguro(2007/07/10 07:25:32 PDT): もしかしたら gensym の使い方が間違っているのかもしれませんが、以下のようなケースで一致すると思われるシンボルの比較が不一致となります。

gosh> (define a (gensym))
a
gosh> a
G1
gosh> (eq? a (string->symbol "G1"))
#f

-2007/07/10 07:53:55 PDT: gensymはどのシンボルとも異なるシンボルを生成します。そのため、string->symbolで同じシンボルが生成されては意味がなくなりますし、できません。この例の場合はGaucheにおけるgensymで生成されたシンボルに対する外部表現が普通のシンボルのものと区別が付かないことが問題なのだと思います。(LISP/Schemeは少しかじっただけの初心者なので外してるかも知れません。どなたかフォローをお願いします)

open-input-uvectorに渡したベクタがGCされない (0.8.10)

shinya (2007/07/05 02:16:55 PDT):

gosh> (use gauche.uvector)
#<undef>
gosh> (use gauche.vport)
#<undef>
gosh> (define wv (make-weak-vector 2))
wv
gosh> (define buf (make-u8vector 1))
buf
gosh> (define in (open-input-uvector buf))
in
gosh> (weak-vector-set! wv 0 buf)
#<undef>
gosh> (weak-vector-set! wv 1 in)
#<undef>
gosh> wv
#,(<weak-vector> 2 #u8(0) #<buffered-input-port #f 00A284D0>)
gosh> (set! buf #f)
#f
gosh> (set! in #f)
#f
gosh> (gc)
#<undef>
gosh> (gc)
#<undef>
gosh> wv
#,(<weak-vector> 2 #u8(0) #f)

open-input-uvectorの替わりに下のtest1を使っても同様にGCされませんが、test2だとGCされるので、letrecがあやしいように思います。

(define (test1 uvector)
  (letrec ((filler (lambda (vec) (u8vector-length uvector))))
    (make <buffered-input-port>
      :fill filler)))

(define (test2 uvector)
  (let1 filler (lambda (vec) (u8vector-length uvector))
    (make <buffered-input-port>
      :fill filler)))

inline展開されるbuiltin関数のbindを後から変更したときの動作

(2007/07/02 02:49:36 PDT): compile.scmを読んでいて、どうなんだろう?と思い下記の例を実行するとsiscと動作が異なります。siscと同じ動作にしようと思うと#<subr continuation>を起動したときに、inline展開を剥しまくるか再コンパイルしないといけなくなるので、「現在の動作が仕様」と言ってしまうのが良いかもしれません。

gosh>  (define (f)
(let1 x #f
  (call/cc (lambda (c) (set! x c)))
  (display (+ 3 4))
  x))
f
gosh> (define g (f))
7g
gosh> (g)
7g
gosh> (define + -)
+
gosh> (g)
7g

siscだと(g)でdisplayされるのは-1になります。また、(g)の結果が#<subr continuation>ではなくgと表示されるのが面白いですね。 -- dsk

Segmentation fault

2007/06/28 03:42:25 PDT SICPの問題3.23(dequeueを作る)で作ったプログラムを走らせたら Segmentation faultに遭遇しました。

Shiro(2007/07/01 00:55:09 PDT): 再現プログラムはちょっと長いので消しときました。 原因は、errorの出力ルーチンが循環構造のあるオブジェクトをちゃんと 処理していなかったことにありました。これだけで再現します:

gosh> (error "foo" '#0=(#0#))
Segmentation fault

たぶんこれで大丈夫じゃないかな。

--- src/scmlib.scm      16 Apr 2007 03:47:13 -0000      1.13
+++ src/scmlib.scm      1 Jul 2007 07:54:43 -0000
@@ -234,7 +234,7 @@
           (if (null? args)
             (get-output-string p)
             (begin (display " " p)
-                   (write (car args) p)
+                   (write/ss (car args) p)
                    (loop (cdr args)))))))
     (define (scan-keys args)
       (let loop ((args args)
@@ -265,9 +265,9 @@
            (if (null? msgs)
              (apply make fmt keys)
              (apply make fmt
-                    :message (apply format #f msgs)
+                    :message (apply format/ss #f msgs)
                     keys))))
-        (else (make <error> :message (apply format #f fmt args))))))
+        (else (make <error> :message (apply format/ss #f fmt args))))))
 
     (values error errorf)))
 

identity が undocumented (0.8.10 and CVS HEAD)

(2007/06/27 04:39:27 PDT):意外なことに、identity関数のエントリーがない!?

エンディアンを変えたときにwrite-blockが余計なデータを出力する(0.8.10)

koguro(2007/06/16 22:59:15 PDT): write-blockでエンディアンを変更してデータを出力するとデータを余分に出力してしまうようです。

gosh> (use gauche.uvector)
#<undef>
gosh> (call-with-output-string (lambda (out) 
                                  (write-block (make-u16vector 1) out 
                                               0 -1 'big-endian)))
"\0\0\0V\0\0\0\0\0?\0V\0\0"
gosh> (call-with-output-string (lambda (out) 
                                  (write-block (make-u16vector 1) out 
                                               0 -1 'little-endian)))
"\0\0"

(x86の場合)

http-getやhttp-postがキーワード引数 sink と flusher を無視する(CVS HEAD)

(2007/06/05 21:36:25 PDT): 新しい let-keywords に対応する途中だったのかしら。

--- lib/rfc/http.scm    2 Mar 2007 07:39:10 -0000       1.11
+++ lib/rfc/http.scm    6 Jun 2007 04:30:26 -0000
@@ -125,25 +125,25 @@
          (values code
                  headers
                  (and has-content?
-                      (let ((sink    (open-output-string))
-                            (flusher (lambda (sink _) (get-output-string sink))))
+                      (let-keywords options
+                         ((sink    (open-output-string))
+                          (flusher (lambda (sink _) (get-output-string sink)))
+                          . #f)
                         (receive-body in headers sink flusher))))))))
 
   (let-keywords options
-      ((sink    (open-output-string))
-       (flusher (lambda (sink h) (get-output-string sink)))
-       (host    (server->host server))
+      ((host    (server->host server))
        (no-redirect #f)
        . restopts)
     (let1 has-content? (not (eq? request 'HEAD))
       (if no-redirect
-        (%send-request request server host request-uri has-content? options)
+        (%send-request request server host request-uri has-content? restopts)
         (let loop ((history (list (values-ref (canonical-uri request-uri host) 0)))
                    (server server)
                    (host host)
                    (request-uri request-uri))
           (receive (code headers body)
-              (%send-request request server host request-uri has-content? options)
+              (%send-request request server host request-uri has-content? restopts)
             (cond ((and (string-prefix? "3" code)
                         (assoc "location" headers))
                    => (lambda (loc)

condでsegmentation fault (0.8.10)

% gosh                                                                                                                                                            
gosh> (cond (1 . 2))
zsh: segmentation fault (core dumped)  gosh

ついでにこれも。

 (case 0 (else 1 . 2))

ext/netでmake testが止まります

0.8.10です。既知の事であれば、すみませんが。

ext/netでのmake checkが、Testing net ...と出たまま戻ってきません。^Cで止めると、以下のようにfailed以降を表示します。

 $ uname 
Linux ****** 2.4.31-v2 #1 SMP Thu Aug 25 15:40:42 JST 2005 i686 i686 i386 GNU/Linux
 $ cd ext/net ; make check
GAUCHE_TEST_RECORD_FILE=../..//test.record ../..//src/gosh -ftest -I. test.scm > test.log
Testing net ...                                                  failed.
discrepancies found.  Errors are:
test getsockname/getpeername: expects #t => got #f
test udp client socket: expects "ABC" => got #<error "unhandled signal 2 (SIGINT)">
 $ 

他のcheck(test)は問題有りません。net周りの仕様が変わったためでしょうか。


CVS HEAD(2007/05/17 03:01:27 PDT)で2fails

OSはNetBSD current(4.99.19)です。

Testing net ...                                                  failed.
discrepancies found.  Errors are:
test getprotobyname: expects (("ip" 0) ("tcp" 6) ("udp" 17)) => got (("ip" 4) ("tcp" 6) ("udp" 17))
test getprotobynumber: expects (#t #t #t) => got (#f #t #t)

ということで2箇所failします。cut-sea:2007/05/17 03:01:27 PDT


Gauche 0.8.10 のリファレンス 10.10.2「時間に関する問い合わせ」の用語について

Modified Julian Day が「改訂ユリウス日」と訳されていますが、通常は「修正ユリウス日」と訳すと思います。 2007/05/17 02:42:55 PDT


Linux/AMD64のsockaddr-addr

Rui (2007/05/14 20:35:58 PDT): Lingrに書いた件。(sockaddr-addr <sockaddr-in6>)のテストがLinux/AMD64で通りません。ntohlがint32_tでなければいけないので。

--- Gauche-0.8.10.orig/ext/net/netlib.stub      2007-04-18 11:08:29.000000000 +0900
+++ Gauche-0.8.10/ext/net/netlib.stub   2007-05-13 20:49:11.000000000 +0900
@@ -88,16 +88,16 @@
     (expr "sym_inet6"))

   (define-cmethod sockaddr-addr ((addr "Scm_SockAddrIn6Class"))
-    "#define BN_SIZE (16 / SIZEOF_LONG)
-  ScmSockAddrIn6 *a = (ScmSockAddrIn6*)addr;
-  u_long values[BN_SIZE];
-  u_long *p = (u_long*)a->addr.sin6_addr.s6_addr;
+    "ScmSockAddrIn6 *a = (ScmSockAddrIn6*)addr;
+  ScmUInt32 values[4];
+  ScmUInt32 *p = (ScmUInt32*)a->addr.sin6_addr.s6_addr;
   int i;
-  ScmObj bn;
+  ScmObj bn = Scm_MakeBignumFromUI(ntohl(*p++));

-  for (i = 0; i < BN_SIZE; i++) values[BN_SIZE-i-1] = ntohl(*p++);
-  bn = Scm_MakeBignumFromUIArray(1, values, BN_SIZE);
-  SCM_RETURN(Scm_NormalizeBignum(SCM_BIGNUM(bn)));")
+  for (i=0; i<3; i++) {
+    bn = Scm_LogIor(Scm_Ash(bn, 32), Scm_MakeBignumFromUI(ntohl(*p++)));
+  }
+  SCM_RETURN(bn);")

   (define-cmethod sockaddr-port ((addr "Scm_SockAddrIn6Class"))
     "  ScmSockAddrIn6 *a = (ScmSockAddrIn6*)addr;

BrainFuckでコアダンプ(CVS HEAD)

skimuさんのbfc.scmでquine.bをコンパイルして生成したschemeコードを 評価するとセグメンテーションフォールトでコアダンプします。
NetBSD currentとubuntu 7.04で確認。 どうやらコンパイルして生成したコードの尻から3つめの、 少し大きめのloop式の前までは評価できているけど、 そのloop式を含めるとアウトになるようです。cut-sea:2007/05/10 05:42:18 PDT


rfc.ftp の call-with-ftp-connection (CVS HEAD)

tabe(2007/04/29 20:56:02 PDT) 関数内部で ftp-login に引数を :user でなく :username で渡す必要があるようです。

gosh> (use rfc.ftp)
#<undef>
gosh> (call-with-ftp-connection "tabe@localhost" ftp-help)
WARNING: unknown keyword :user
"214-The following commands are recognized.\n ABOR ACCT ALLO APPE CDUP CWD  DELE EPRT EPSV FEAT HELP LIST MDTM MKD\n MODE NLST NOOP OPTS PASS PASV PORT PWD  QUIT REIN REST RETR RMD  RNFR\n RNTO SITE SIZE SMNT STAT STOR STOU STRU SYST TYPE USER XCUP XCWD XMKD\n XPWD XRMD"
gosh> 

パッチ:

Index: lib/rfc/ftp.scm
===================================================================
RCS file: /cvsroot/gauche/Gauche/lib/rfc/ftp.scm,v
retrieving revision 1.5
diff -c -r1.5 ftp.scm
*** lib/rfc/ftp.scm     2 Mar 2007 07:39:10 -0000       1.5
--- lib/rfc/ftp.scm     30 Apr 2007 03:37:44 -0000
***************
*** 73,79 ****
    (receive (user host port) (uri-decompose-authority uri)
      (let1 conn (apply ftp-login host
                        (cond-list
!                        (user @ (list :user user))
                         (port @ (list :port port))
                         (#t   @ keys)))
        (unwind-protect (proc conn)
--- 73,79 ----
    (receive (user host port) (uri-decompose-authority uri)
      (let1 conn (apply ftp-login host
                        (cond-list
!                        (user @ (list :username user))
                         (port @ (list :port port))
                         (#t   @ keys)))
        (unwind-protect (proc conn)

Bignumと#i1/0の比較がエラーになる (0.8.10)

shinya(2007/04/28 03:22:42 PDT): Bignumとinfinityを比較するとエラーになります

gosh> (< 10000000000000 #i1/0)
*** ERROR: can't convert inf to an integer
Stack Trace:
_______________________________________

パッチ

Index: number.c
===================================================================
RCS file: /cvsroot/gauche/Gauche/src/number.c,v
retrieving revision 1.146
diff -u -r1.146 number.c
--- number.c    26 Mar 2007 23:59:54 -0000      1.146
+++ number.c    28 Apr 2007 10:16:15 -0000
@@ -2318,9 +2318,12 @@
             if (r > 0) return 1;
             return 0;
         }
-        if (SCM_BIGNUMP(arg1))
-            return Scm_BignumCmp(SCM_BIGNUM(Scm_MakeBignumFromDouble(SCM_FLONUM_VALUE(arg0))),
-                                 SCM_BIGNUM(arg1));
+        if (SCM_BIGNUMP(arg1)) {
+            double r = SCM_FLONUM_VALUE(arg0) - Scm_BignumToDouble(SCM_BIGNUM(arg1));
+            if (r < 0) return -1;
+            if (r > 0) return 1;
+            return 0;
+        }
         if (SCM_RATNUMP(arg1)) {
             double r = SCM_FLONUM_VALUE(arg0) - Scm_GetDouble(arg1);
             if (r < 0) return -1;
@@ -2334,8 +2337,7 @@
             return Scm_BignumCmp(SCM_BIGNUM(arg0),
                                  SCM_BIGNUM(Scm_MakeBignumFromSI(SCM_INT_VALUE(arg1))));
         if (SCM_FLONUMP(arg1))
-            return Scm_BignumCmp(SCM_BIGNUM(arg0),
-                                 SCM_BIGNUM(Scm_MakeBignumFromDouble(SCM_FLONUM_VALUE(arg1))));
+            return -Scm_NumCmp(arg1, arg0);
         if (SCM_BIGNUMP(arg1))
             return Scm_BignumCmp(SCM_BIGNUM(arg0), SCM_BIGNUM(arg1));
         if (SCM_RATNUMP(arg1)) {

mapが多値を返す (0.8.10)

齊藤(2007/04/27 20:48:15 PDT):最後の要素の2個目以降の値がmapの返り値になっているようです。R5RSを読み返しても明確に規定されていることでは無いようですが、奇妙な挙動に見えます。

gosh> (map (cut apply values <>) '((1 2) (3 4) (5 6)))
(1 3 5)
6

拡張ライブラリのコンパイルでwarningが出る (0.8.10)

Shiro(2007/04/26 20:33:31 PDT):

diff -u -r1.23 port.h
--- port.h      16 Apr 2007 03:47:13 -0000      1.23
+++ port.h      27 Apr 2007 03:32:59 -0000
@@ -349,21 +349,21 @@
 SCM_EXTERN ScmObj Scm_MakeInputStringPort(ScmString *str, int privatep);
 SCM_EXTERN ScmObj Scm_MakeOutputStringPort(int privatep);
 
-#if defined(GAUCHE_API_0_9) || defined(LIBGAUCHE_BODY)
+#if defined(GAUCHE_API_0_8_10) || defined(GAUCHE_API_0_9) || defined(LIBGAUCHE_BODY)
 SCM_EXTERN ScmObj Scm_GetOutputString(ScmPort *port, int flags);
 SCM_EXTERN ScmObj Scm_GetOutputStringUnsafe(ScmPort *port, int flags);
 SCM_EXTERN ScmObj Scm_GetRemainingInputString(ScmPort *port, int flags);
 
+#else  /* !defined(GAUCHE_API_0_8_10) && !defined(GAUCHE_API_0_9) && !defined(LIBGAUCHE_BODY) */
+#define Scm_GetOutputString(p) Scm__GetOutputStringCompat(p)
+#define Scm_GetOutputStringUnsafe(p) Scm__GetOutputStringUnsafeCompat(p)
+#define Scm_GetRemainingInputString(p) Scm__GetRemainingInputStringCompat(p)
+
 /* For backward compatibility */
 SCM_EXTERN ScmObj Scm__GetOutputStringCompat(ScmPort *port);
 SCM_EXTERN ScmObj Scm__GetOutputStringUnsafeCompat(ScmPort *port);
 SCM_EXTERN ScmObj Scm__GetRemainingInputStringCompat(ScmPort *port);
-
-#else  /* !defined(GAUCHE_API_0_9) && !defined(LIBGAUCHE_BODY) */
-#define Scm_GetOutputString(p) Scm__GetOutputStringCompat(p)
-#define Scm_GetOutputStringUnsafe(p) Scm__GetOutputStringUnsafeCompat(p)
-#define Scm_GetRemainingInputString(p) Scm__GetRemainingInputStringCompat(p)
-#endif /* !defined(GAUCHE_API_0_9) && !defined(LIBGAUCHE_BODY) */
+#endif /* !defined(GAUCHE_API_0_8_10) && !defined(GAUCHE_API_0_9) && !defined(LIBGAUCHE_BODY) */
 
 /*================================================================
  * Other type of ports

sys-realpathが使えない (0.8.10)

Shiro(2007/04/26 20:33:31 PDT): ext/sys/auxsys.scmにtypoがあります。

--- auxsys.scm  28 Mar 2007 22:29:56 -0000      1.19
+++ auxsys.scm  23 Apr 2007 08:32:53 -0000      1.20
@@ -52,7 +52,7 @@
 ;; define alternatives if the platform doesn't support...
 
 (cond-expand
- ((not gauche.sys.reaplath)
+ ((not gauche.sys.realpath)
   (define sys-realpath #f))             ; make autoload happy
  (else))
 

force-output の 定義 (0.8.10)

齊藤(2007/04/21 23:35:29 PDT): slibのreplを使うとプロンプトの表示がおかしいです。現行ではforce-outputは何もしていませんが、flushすればいいんじゃないでしょうか。こんなカンジで。

(define (force-output . arg) (apply flush arg) #t)

プロファイラを使うとポートがGCされない (0.8.10)

shinya(2007/04/21 04:28:54 PDT): プロファイラを利用するとポートがGCされないようです。次のようにして確認しました。

$ cat port-test.scm
(use gauche.collection)

(define port-table (make-weak-vector 300))

(dotimes (cnt 300)
  (format #t "cnt:~d active:~d\n"
          cnt (length (filter identity port-table)))
  (call-with-output-file #`"test-file-,|cnt|"
    (lambda (out)
      (weak-vector-set! port-table cnt out)
      (write "test" out))))
$ gosh -ptime port-test.scm
cnt:0 active:0
cnt:1 active:1
  :
(省略)
  :
cnt:253 active:253
cnt:254 active:254
active buffered port table overflow

Shiro(2007/08/06 20:34:28 PDT): このコードの場合、call-with-output-fileがoutへのポインタを保持した ScmSubrを生成していて、それがプロファイリングに記録されちゃっているようです。 プロファイラはサンプリングにせよコールカウントにせよオブジェクトへのポインタを 保持するので、GCされないオブジェクトが出てくるのはある意味仕方ないです (ポインタをdisguiseしたりweakに記録することにより「GCされない」問題は解決 しますが、そうするとプロファイル時に記録されたオブジェクトが集計時にGCされて しまっている可能性があり、正しい集計が行えません)。

ただ、この特定の問題に関してはclose時に内部ポートテーブルの内容をクリアする ことで対応可能だと思います。

あと、ScmSubrのサンプリングは名前だけ記録する、とかにしても余分な オブジェクトが生き残ってしまうケースが減らせるかもしれません。

Shiro(2007/08/09 19:05:17 PDT): とりあえず内部ポートテーブルがfullになる問題には 対応しました。

ext/net/net.c の typo (0.8.10)

齊藤(2007/04/20 05:12:37 PDT): 532行目

static void init_winwock(void)

Last modified : 2012/02/23 03:10:55 UTC