Gauche:Bugs:log1
最新のもの: Gauche:Bugs
- testing system ... failed. (0.6.7.1) on Linux 2.4.18
- errorf に format 文字列と矛盾するパラメータをわたしたときのふるまい (0.6.7.1)
- SRFI-19のmake-time (0.6.7.1)
- MT-safeでないコード (0.6.7.1)
- SRFI-27のrandom-source-randomize!でrandom seedがrandomizeされない (0.6.6)
- Solaris8/sparc でコンパイル失敗 (0.6.6)
- FreeBSDでsys-times (また、それを利用しているgauche.time) がエラーになる (0.6.4)
- HP-UX11.0でコンパイルが失敗する (0.6.4)
- 比較関数つきの sort が遅い
- cons が遅い (勘違い発覚)
- ces-convert の to-code で iso-2022-jp を指定すると固まる
- port->string が遅い
- close-output-port を2回呼ぶと固まる
- gosh.core
- slib:transcript の出力が、size 0 になります。
- シグナルハンドラをセットしておくと、readの最中にシグナルが入った時にreadがEOFを返す (0.6.1)
testing system ... failed. (0.6.7.1) on Linux 2.4.18
nobsun 2003/03/27 00:36:35 PST Kernel を rebuild した Linux 2.4.18 (Debian Woody 3.0)上でのことです。
# make test ... testing system ... failed. discrepancies found. Errors are: test access: expects (#t #t #f #t) => got (#t #t #t #t) test access: expects (#t #t #f #f) => got (#t #t #t #t) test access: expects (#t #f #f #f) => got (#t #t #t #f) ...
- Shiro (2003/03/29 21:56:26 PST): access(2)の実装は結構怪しいのがあるみたい なのです。既にFreeBSDとDarwinではsys-accessはaccess(2)を使わずに stat(2)で代用しています。 いっそのこと全部stat(2)使用に置き換えてしまおうかな。
- Shiro (2003/06/03 00:57:19 PDT): このエラーですが、どうもある環境下では、 別プロセスでかけたchmodの情報が伝わるのに時間がかかるようです。 accessの前にstatしてもaccessの戻り値が変わらないので、 authentication moduleかなんかでキャッシュしているのかなあ。 実は今までのFreeBSDでのstat(2)の代用コードは間違っていたことに気づき、 0.7では全てaccess(2)を使うように戻してありますが、テストコードの方で ディレイを入れたら、私の試せる環境では全てテストが通るようになりました。
errorf に format 文字列と矛盾するパラメータをわたしたときのふるまい (0.6.7.1)
ねるWiki:ねる 2003/03/13 17:05:53 PST: (errorf "hoge" "hage") とかしたとき gosh が "Error occurred in error handler" でおとされてしまいます。ダブルフォルト扱いなのでしょうが、フォーマット文字列まちがいで殺されてしまうと、ちょっとびっくりします。
- Shiro: そうか。何らかの方法で救済した方が良いですね。考えてみます。
SRFI-19のmake-time (0.6.7.1)
Shiro (2003/02/18 01:14:39 PST): SRFI-19のmake-timeの引数の順序を今まで勘違いして ました。スペックでは
make-time type nanosecond second
ですが、Gaucheの実装もドキュメントも間違って
make-time type second nanosecond
となっています。SRFI-19のリファレンス実装が間違っているのを気づかずに 流用して、さらにドキュメントもリファレンス実装から起こしたため 今まで気づきませんでした。
CVSにあるsrfi-19.scm, v 1.11で修正されています。
MT-safeでないコード (0.6.7.1)
Shiro (2003/02/14 04:17:46 PST): Gauche:SXMLでRDFに上げた、RSSを取得する ルーチンをマルチスレッドで走らせる、ということをやってたんですが、 GaucheのMT-safeでないコードでつまづきまくりです。とほほ。
- autoloadのローダー。requireはMT-safeなんですが、autoloadシンボルに ヒットしてrequireを呼ぶところがMT-safeじゃないんで、複数のスレッドが 同時にautoloadシンボルを見た時にrace conditionが起こります。
- <sockaddr-in>のallocatorメソッド:こっちの方が深刻。 ホスト名を渡してソケットを作るところで (gethostbyaddr_rではなく)gethostbyaddrを呼んじゃってるのでした… スレッド内でmake-client-socket等を使ってるコードは全部ここでつまづく 可能性があります。
SRFI-27のrandom-source-randomize!でrandom seedがrandomizeされない (0.6.6)
Shiro (2002/12/21 16:54:27 PST): mt-random-set-seed!にバグがあり、seedが bignumの時に常に同一のseedが使われるようになってしまっていました。 パッチ:
*** mt-lib.stub 24 Jul 2002 15:38:50 -0000 1.7 --- mt-lib.stub 22 Dec 2002 00:53:14 -0000 *************** *** 16,23 **** (define-type <f64vector> "ScmF64Vector*") (define-cproc mt-random-set-seed! (mt::<mersenne-twister> init) ! "if (SCM_EXACTP(init)) { Scm_MTInitByUI(mt, Scm_GetUInteger(init)); #if !defined(__CYGWIN__) } else if (SCM_U32VECTORP(init)) { Scm_MTInitByArray(mt, SCM_U32VECTOR_ELEMENTS(init), SCM_U32VECTOR_SIZE(init)); --- 16,29 ---- (define-type <f64vector> "ScmF64Vector*") (define-cproc mt-random-set-seed! (mt::<mersenne-twister> init) ! "if (SCM_INTP(init)) { Scm_MTInitByUI(mt, Scm_GetUInteger(init)); + } else if (SCM_BIGNUMP(init)) { + int i; unsigned long s = 0; + for (i=0; i<SCM_BIGNUM_SIZE(init); i++) { + s ^= SCM_BIGNUM(init)->values[i]; + } + Scm_MTInitByUI(mt, s); #if !defined(__CYGWIN__) } else if (SCM_U32VECTORP(init)) { Scm_MTInitByArray(mt, SCM_U32VECTOR_ELEMENTS(init), SCM_U32VECTOR_SIZE(init));
Solaris8/sparc でコンパイル失敗 (0.6.6)
In file included from sha1.c:8: sha.h:59: sys/cdefs.h: ファイルもディレクトリもありません。 make[2]: *** [sha1.o] Error 1 make[2]: Leaving directory `/export/home/sakae/Gauche-0.6.6/ext/digest' # uname -a SunOS eqv 5.8 Generic_108528-10 sun4u sparc SUNW,Ultra-60 # cat /etc/release Solaris 8 1/01 s28s_u3wos_08 SPARC Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. Assembled 28 November 2000 FreeBSDから同名のファイルを持ってきたら無事にコンパイル成功 testもOKになりました。 sakae (2002/12/17 04:12:19 PST)
Shiro (2002/12/17 06:02:56 PST): ccはSunのやつをお使いですか? SourceForgeのSolaris8/sparc/gccでは、 該当ファイルは /opt/sfw/include/ の下にありました。
コンパニオンCDから入れた gcc です。 gcc -v Reading specs from /opt/sfw/lib/gcc-lib/sparc-sun-solaris2.8/2.95.2/specs gcc version 2.95.2 19991024 (release)
ちなみに#include <sys/cdefs.h>を削ったら通ります? 通るようなら configureでヘッダの有無をチェックするように変更します。
In file included from sha1.c:9: sha.h:61: syntax error before `extern' sha1.c:10: syntax error before `typedef' make[2]: *** [sha1.o] Error 1
残念ながら NG でした。/opt/sfw/include/ は、何かの拍子に入る所ですよね。 どんなパッケージに含まれているのでしょう? ちなみに、コンパニオンCDの中身は 全部入れたと記憶してます。(Solarisって面倒なので嫌い ^^;)
FreeBSDでsys-times (また、それを利用しているgauche.time) がエラーになる (0.6.4)
Shiro gauche-devel MLで出たのでこちらにも書いておきます。 とりあえずこのパッチを。
*** ext/auxsys/auxsyslib.stub 17 Oct 2002 12:44:28 -0000 1.11 --- ext/auxsys/auxsyslib.stub 24 Jul 2002 15:38:50 -0000 1.10 *************** *** 134,141 **** (define-cproc sys-times () " struct tms info; ScmObj h = SCM_NIL, t; ! clock_t r = times(&info); ! if (r == (clock_t)-1) Scm_SysError(\"times failed\"); SCM_APPEND1(h, t, Scm_MakeInteger(info.tms_utime)); SCM_APPEND1(h, t, Scm_MakeInteger(info.tms_stime)); SCM_APPEND1(h, t, Scm_MakeInteger(info.tms_cutime)); --- 134,141 ---- (define-cproc sys-times () " struct tms info; ScmObj h = SCM_NIL, t; ! int r = Scm_SysCall(times(&info)); ! if (r < 0) Scm_SysError(\"times failed\"); SCM_APPEND1(h, t, Scm_MakeInteger(info.tms_utime)); SCM_APPEND1(h, t, Scm_MakeInteger(info.tms_stime)); SCM_APPEND1(h, t, Scm_MakeInteger(info.tms_cutime));
HP-UX11.0でコンパイルが失敗する (0.6.4)
HP-UX11.00 + HP標準の cc で Gauche-0.6.4 をコンパイルしたら, cc: "uvlib.c", line 9263: error 1539: Cannot do arithmetic with pointers to objects of unknown size. と出てエラーになります。0.6.3では何の問題もなく通っていました。 ./configureのオプション指定は
$ env CC="cc" ./configure --prefix=$HOME --with-local=$HOME --with-slib=$HOME/share/guile/slib
です。 あと,この環境で共有ライブラリを有効にするにはどうしたらよいか,どなたかご存知ありませんか? dynamic-load がことごとくエラーになるので,SLIBもiconvも使えません。 -- そり (2002/10/17 01:34:38 PDT)
- Shiro: 環境が無いのでデバッグできないのですが、該当箇所のエラーを見るに、void*のまま演算をやってしまったのがまずかったようです。とりあえず、ext/uvector/uvlib.stub.shを以下のように修正してみて下さい。
=================================================================== RCS file: /cvsroot/gauche/Gauche/ext/uvector/uvlib.stub.sh,v retrieving revision 1.20 diff -r1.20 uvlib.stub.sh 308c308 < SCM_RETURN(Scm_MakeUVector(SCM_CLASS(klass), dstsize, v->elements + start*srcalign)); --- > SCM_RETURN(Scm_MakeUVector(SCM_CLASS(klass), dstsize, (char*)v->elements + start*srcalign)); 325c325 < r = Scm_Getz(v->elements + start*eltsize, (end-start)*eltsize, port); --- > r = Scm_Getz((char*)v->elements + start*eltsize, (end-start)*eltsize, port); 337c337 < Scm_Putz(v->elements + start*eltsize, (end-start)*eltsize, port); --- > Scm_Putz((char*)v->elements + start*eltsize, (end-start)*eltsize, port);
- そり: 無事にコンパイル通りました。こういうことでよかったんですね。ありがとうございました。
比較関数つきの sort が遅い
satoru 比較関数つきの sort が遅いことに気づきました。(2002/10/09 03:28:12 PDT)
% gosh -V Gauche scheme interpreter, version 0.6.3 [euc-jp,pthreads] % time gosh -e '(sort (port->string-list (current-input-port)))' < /usr/share/dict/words 0.61s total : 0.60s user 0.01s system 100% cpu % time gosh -e '(sort (port->string-list (current-input-port)) string<?)' < usr/share/dict/words 8.13s total : 7.84s user 0.34s system 100% cpu % time gosh -e '(port->string-list (current-input-port))' < /usr/share/dict/words 0.28s total : 0.28s user 0.00s system 100% cpu
ちなみに、Rubyだとこのくらいでした。
% time ruby -e 'readlines.sort' /usr/share/dict/words 0.25s total : 0.26s user 0.01s system 105% cpu % time ruby -e 'readlines.sort {|a, b| a <=>b}' /usr/share/dict/words 2.23s total : 2.25s user 0.01s system 101% cpu % time ruby -e 'readlines' /usr/share/dict/words 0.10s total : 0.09s user 0.02s system 109% cpu
テキスト処理のプログラムを Gauche でばりばり書いているので、同じくらい速くなるとうれしいです。
- Shiro: Olin ShiversがSRFI-32 ( http://srfi.schemers.org/srfi-32/srfi-32.html ) でソートライブラリを提案しているので、 それのfinalizeを待って対応したいと思います。(2002/10/13 15:20:54 PDT)
cons が遅い (勘違い発覚)
satoru cons が遅いことに気づきました。(2002/10/09 02:30:04 PDT])
もともとは srfi-1 の filter が遅いのに気づいたんですが、 もとを正すと、どうも cons が遅いのが原因のようです。
% gosh -V Gauche scheme interpreter, version 0.6.3 [euc-jp,pthreads] % cat foo.scm (use srfi-1) ;; 80文字より短い行だけを抽出する (filter (lambda (x) (< (string-length x) 80)) (port->string-list (current-input-port))) % time gosh foo.scm < /usr/share/dict/words 461.83s total : 460.59s user 0.23s system 99% cpu
Pentium III 1 GHz の計算機を使っています。filter に限らず
(define (enumerate-interval low high) (if (> low high) '() (cons low (enumerate-interval (+ low 1) high)))) (enumerate-interval 1 100000)
のように、再帰して cons しまくって長いリストを作るコードが全般的に遅いようです。 再帰が遅いのではなく、遅いのは cons のようです。 foo.scm の例では 80 の部分を 0 にすると、filter の結果が空リストになるので、 0.3秒程度で返ってきました。
- Shiro: あーっと、これはconsのせいではなくて、 再帰が深くなってスタックオーバーフローが発生しているためだと思われます。 (試しに末尾再帰版を作って比べて見て下さい)。 現在の実装のスタックオーバーフローハンドラはちょいと手抜きなんですが、 露見してしまいましたね。 とりあえずの対策としては、なるべく末尾再帰を使って頂けると助かります (末尾再帰して最後にreverse!する方が、再帰より速いです)。 (2002/10/09 02:48:40 PDT)
- satoru ありゃりゃ。早とちりしてしまいました。 とりあえず、filter は次のコードで速くなりました。 srfi-1 の filter をそのまま使うともうれつに遅いのが悲しいです。
(define (filter predicate items) (let loop ((result '()) (items items)) (cond ((null? items) (reverse! result)) ((predicate (car items)) (loop (cons (car items) result) (cdr items))) (else (loop result (cdr items))))))
- satoru そういえば、guile だと末尾再帰じゃない再帰はすぐにスタックオーバーフローでこけるので、嫌になったのを思い出しました。Gauche だと遅くはなってもなかなかこけませんね。
- Shiro SRFI-1 の実装の方も末尾再帰に直しておきます。 (2002/10/11 11:16:38 PDT)
ces-convert の to-code で iso-2022-jp を指定すると固まる
satoru Red Hat Linux 7.2 + Gauche 0.6.3 で次のコードを実行すると固まることに気づきました。(2002/09/25 20:06:43 PDT)
% gosh -u gauche.charconv gosh> (ces-convert "あいう" "eucjp" "iso2022jp") "\x1b$B$\"$$$&\x1b(B" gosh> (ces-convert "あいう" "eucjp" "iso-2022-jp") ;; 返って来ない
上のほうは jconv.c のコードが使われていて、下は iconv(3) が動いているのかなあ。 jconv.c の conv_supports には
{ "iso-2022-jp", JCODE_ISO2022JP },
を加えた方がいいかも。
- Shiro: "iso-2022-jp" でもjconvを使うようにするのが一番安直ですが、 iconvの呼び方を間違えている可能性も高いので調査してみます。
このへんのcharsetの正式な表記ってどこかにまとまっていませんかね。 ご存知の方いらっしゃいましたら教えて下さい。
- Shiro: あと、下の「port->stringが遅い」にも関連するのですが、 ces-convertのコードもかなり遅いことに気づきました。 原因は、マルチスレッド化されてから ポートアクセスに排他制御が入ることになったんですが、 排他制御する必要のないポートにまで通常の方法で文字単位/バイト単位で アクセスしているためです。
- skimu: Gauche:NetBSD のやり方で作った Gauche 0.6.3 では正常に動きました。スレッド絡み?
- skimu: Gauche:メール ではまったとき、うっかり上のような変更が欲しいなぁと思ってしまったのですが、この手ののエイリアスは scheme レベルで解決した方が、柔軟性があってうれしいなぁすぐに思い直しました。 (ces-normalize-charset-name "iso-2022-jp") -> "ISO2022JP" 見たいな感じ?
- Shiro: バグ判明。iso2022jpのリセットシーケンス絡みで、buffered port とcharconvの間でプロトコルの不一致がありました。
- Shiro: 直りました。パッチをMLに投げときます。お急ぎの方は ext/charconv/jconv.c, v 1.10 を使って下さい。
port->string が遅い
satoru port->string が遅いことに気づきました。(2002/09/19 10:27:16 PDT)
(use srfi-19) (use srfi-13) (define (benchmark message thunk) (let ((start-time (current-time))) (thunk) (let ((elapsed-time (time-difference (current-time) start-time))) (format #t "~a: ~a.~a\n" message (time-second elapsed-time) (time-nanosecond elapsed-time))))) (benchmark "port->string" (lambda () (call-with-input-file "/usr/share/dict/words" (lambda (port) (port->string port))))) (benchmark "port->string-list" (lambda () (call-with-input-file "/usr/share/dict/words" (lambda (port) (port->string-list port))))) % gosh -V Gauche scheme interpreter, version 0.6.2 [euc-jp,pthreads] % gosh test.scm port->string: 0.627169000 port->string-list: 0.221794000
Gauche のソースコードをみると
for (;;) { SCM_GETC(ch, port); if (ch == EOF) break; SCM_PUTC(ch, out); }
というループなのでいかにも遅そうであります。
- Shiro: 実は上記のCのコードは呼ばれていなかったことが判明。 port->stringはSchemeで再定義されていました。 んで、遅くなっていた主要因はむしろ一文字毎に入力と出力ポートをロック していたためだったので、そのへんをごにょごにょしてScheme定義版でも そこそこ速くしました。依然としてport->string-listよりは遅いですが… 0.6.4に入ります。(2002/10/12 06:59:06 PDT)
close-output-port を2回呼ぶと固まる
satoru gauche 0.6.2 で次のコードを実行すると固まることに気づきました。
(let ((port (open-output-file "foo.txt"))) (display "foo\n" port) (close-output-port port) (close-output-port port))
Red Hat Linux 7.3 + Gauche 0.6.2 です。(2002/09/18 11:15:58 PDT)
- Shiro: 修正しました。0.6.3に入ります (port.c,v 1.80) (2002/09/18 13:27:38 PDT)
gosh.core
Gauche 0.6 を M-x run-scheme で emacs から使っていて、emacsを強制終了させると、 gosh.coreができますが、これは仕様でしょうか? 環境は、emacs 20.7 + FreeBSD 4.6-stable です。--sakae (2002/07/31 07:26:45 PDT)
- Shiro: バグです。こちらでも再現しました。調査中 (2002/07/31 11:56:03 PDT)
- Shiro: 親emacsから終了時にsignal (SIGHUP)を受ける→デフォルトのシグナルハンドラが起動→エラーメッセージを出そうとする→でもterminalは閉じられているのでエラーになる→エラーメッセージを出そうとする→無限ループ、という具合になって、 スタックを喰い潰してSEGVしている模様。(2002/07/31 12:17:54 PDT)
- Shiro: 直したものをversion 0.6.1としてリリースしました。
- 完(感)動しました。Thanks Shiro さん。--sakae (2002/08/02 04:50:32 PDT)
- 藤井: 私も M-x run-scheme で使っているのですが、 gosh が kill -1 でも死なないのが気になります。よって C-x k でバッファが亡くなってもプロセスが残ります。
- Shiro: ふーむ。ちょっとad hocですが、インタラクティブモードの時は SIGHUPはデフォルトでプロセスを終了させるようにしておくのが良いのかなあ。
- Shiro: SIGHUP, SIGQUIT, SIGTERMについては、シグナルを受けたら exitするハンドラをデフォルトとすることにしました (dynamic stackのunwind 等は行われます)。近日中に出る0.6.2に入ります。 (2002/08/29 00:25:24 PDT)
slib:transcript の出力が、size 0 になります。
gosh> (use slib) (#<module slib> #<module gauche.interactive>) gosh> (require 'transcript) : gosh> (transcript-on "./test.log") #<oport ./test.log 0x810d460> gosh> (gauche-architecture-directory) "/usr/local/lib/gauche/0.6.1/i386-unknown-freebsd4.6" gosh> (slib:report) SLIB "2d4" on gauche "0.6.1" on UNIX (IMPLEMENTATION-VICINITY) is "/usr/local/share/gauche/0.6.1/lib/" (LIBRARY-VICINITY) is "/usr/local/share/slib/" (SCHEME-FILE-SUFFIX) is ".scm" Loaded *MODULES* are: ("/usr/local/lib/scm/slib/trnscrpt") loaded *FEATURES* : transcript Implementation *FEATURES* : srfi-28 srfi-27 srfi-25 srfi-23 srfi-22 srfi-19 srfi-18 srfi-17 srfi-14 srfi-13 srfi-11 srfi-9 srfi-8 srfi-6 srfi-4 srfi-2 srfi-1 srfi-0 bignum complex real rational inexact vicinity source rev5-report eval values dynamic-wind macro delay multiarg-apply char-ready? rev4-optional-procedures rev4-report ieee-p1178 multiarg/and- with-file ieee-floating-point full-continuation srfi defmacro record string-port sort object->string format system getenv program-arguments current-time Implementation *CATALOG* : (schelog . "/usr/local/lib/scm/slib/schelog/schelog") |...|
#<undef> gosh> (transcript-off) #f gosh> (exit) cons:sakae$ ls -l test.log -rw-r--r-- 1 sakae kuma 0 8 13 20:22 test.log
transcriptでは、read/write等を書き換えているようですが、そのせいでしょうか? --sakae (2002/08/13 04:41:58 PDT)
- Shiro: slibのtranscriptは、read/writeを置き換えることで 標準のread-eval-printループにフックをかませるようにしているようですが、 Gaucheの標準のread-eval-printループは直接組込みのreadやwrite手続きを呼んで いるため、slibで再定義した方が呼ばれないのです。 (それに、read-blockやwrite-byte, format等の組込み入出力手続きも Schemeレベルのreadやwriteを経由しないため、たとえread-eval-printループで readやwriteを置き換えてもうまく動作しないと思います)。 作るなら、ファイルにログを取れるような入出力ポートを作ってやるほうが 確実のように思えます。ちょっと考えてみます。 (2002/08/14 23:41:12 PDT)
シグナルハンドラをセットしておくと、readの最中にシグナルが入った時にreadがEOFを返す (0.6.1)
Shiro (2002/08/16 18:04:31 PDT): gauche-dev MLの方で報告があったのでこちらにも メモっときます。 例えば対話環境で、
(set-signal-handler! SIGINT (cut display <>))
のようにしてハンドラをセットした後、"gosh>" のプロンプトが出ている時に SIGINTを送るとインタプリタが終了してしまいます。
MLの方にパッチを送っておきました。 しばらくすればMLのアーカイブで参照できると思います。