おまぬけ活動日誌

最近のツッコまれどころ

この日誌から Google してもらう


2007年12月27日(Thu) 今日もどんより [同日]

MacBookは三年保証にして買うことが多いのだそうだ。壊れやすいの?

このホストでruby-1.9.0-0を作ってみる

昨日はquotaをあふれさせちゃったので別のアカウントで。

$ uname -srm
NetBSD 3.0.2_PATCH alpha
$ bzcat /tmp/ruby-1.9.0-0.tar.bz2 | tar xvf -
$ cd ruby-1.9.0-0/
$ ./configure --prefix=$HOME/ruby-1.9.0-0
$ make
$ make test
  <中略>
test_thread.rb ....miniruby: Error detected by libpthread: Invalid wait time.
Detected by file "/home/builds/ab/netbsd-3-1-RELEASE/src/lib/libpthread/pthread_cond.c", line 186, function "pthread_cond_timedwait".
See pthread(3) for information.
  <中略>
#760 test_thread.rb:32:in `<top (required)>': 
     5000.times{|e|
       (1..2).map{
         Thread.new{
         }
       }.each{|e|
         e.join(1000000000)
       }
     }
  #=> "" (expected "5000")  
FAIL 1/821 tests failed
*** Error code 1

Stop.
  <後略>

再現させる最小のコードは下記かな?ulimitをunlimitedにして、

$ ./miniruby -ve 'Thread.new{}.join(1000000000)'
ruby 1.9.0 (2007-12-25 revision 14709) [alpha-netbsd3.0.2.]
miniruby: Error detected by libpthread: Invalid wait time.
Detected by file "/home/builds/ab/netbsd-3-1-RELEASE/src/lib/libpthread/pthread_cond.c", line 186, function "pthread_cond_timedwait".
See pthread(3) for information.
Abort trap (core dumped)
$ gdb miniruby miniruby.core
GNU gdb 5.3nb1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "alpha--netbsd"...
Core was generated by `miniruby'.
Program terminated with signal 6, Aborted.
Reading symbols from /usr/lib/libpthread.so.0...done.
Loaded symbols for /usr/lib/libpthread.so.0
Reading symbols from /usr/lib/librt.so.0...done.
Loaded symbols for /usr/lib/librt.so.0
Reading symbols from /usr/lib/libcrypt.so.0...done.
Loaded symbols for /usr/lib/libcrypt.so.0
Reading symbols from /usr/lib/libm.so.0...done.
Loaded symbols for /usr/lib/libm.so.0
Reading symbols from /usr/lib/libc.so.12...done.
Loaded symbols for /usr/lib/libc.so.12
Reading symbols from /usr/libexec/ld.elf_so...done.
Loaded symbols for /usr/libexec/ld.elf_so
#0  0x000000016027d880 in kill () from /usr/lib/libc.so.12
(gdb) bt
#0  0x000000016027d880 in kill () from /usr/lib/libc.so.12
#1  0x00000001601b4968 in pthread__errorfunc () from /usr/lib/libpthread.so.0
#2  0x00000001601b15a8 in pthread_cond_timedwait ()
   from /usr/lib/libpthread.so.0
#3  0x00000001201063a0 in native_sleep (th=0x1201be000, tv=0x1ffffe128)
    at thread_pthread.c:445
#4  0x00000001201074d0 in sleep_timeval (th=0x1fa5, tv=
      {tv_sec = 5907375700, tv_usec = 5907377072}) at thread.c:616
#5  0x0000000120107590 in sleep_wait_for_interrupt (th=0x1201be000, 
    sleepsec=999999999.99999571) at thread.c:637
#6  0x0000000120107324 in thread_join (target_th=0x1203b5800, delay=0)
    at thread.c:485
#7  0x00000001201073a0 in thread_join_m (argc=8101, argv=0x3b9ac9ff, 
    self=999995) at thread.c:566
#8  0x0000000120102e98 in call_cfunc (func=0x120107330 <thread_join_m>, 
    recv=4834850840, len=1660940288, argc=0, argv=0x5f) at vm_insnhelper.c:281
#9  0x00000001201048dc in vm_call_cfunc (th=0x1201be000, reg_cfp=0x1202bfeb0, 
    num=1, id=7234316346693281124, recv=4834850840, klass=4834874760, 
    flag=999995, mn=0x2064696c61766e49, blockptr=0x6d69742074696177)
    at vm_insnhelper.c:371
#10 0x00000001201036f0 in vm_call_method (th=0x1201be000, 
    cfp=0x6465746365746564, num=1, blockptr=0x0, flag=0, id=4136, 
    mn=0x1202e35d0, recv=2334106421097295433, klass=4834874760)
    at vm_insnhelper.c:503
#11 0x00000001200fdd44 in vm_eval (th=0x1201be000, initial=4834721456)
    at ruby.h:894
#12 0x00000001201014a4 in vm_eval_body (th=0xa7) at vm.c:1148
#13 0x0000000120101898 in rb_iseq_eval (iseqval=4834851480) at vm.c:1357
#14 0x00000001200391fc in ruby_exec_node (n=0x1201be0e0, 
    file=0x1 <Address 0x1 out of bounds>) at eval.c:229
#15 0x00000001200392b0 in ruby_run_node (n=0x1601b6654) at eval.c:259
#16 0x0000000120014174 in main (argc=1612408404, argv=0x1601b6bb0, 
    envp=0xf423b) at main.c:39
(gdb) 

joinの引数が大きすぎるんだろうね。いや、必ずしもそうじゃないみたいだ。

中途半端に仕事に戻る。

NetBSDのtimespec

上のバックトレースで、sleep_timeval()にtv_usecがわたっているのに対して、pthread_cond_timedwait()の受けとるconst struct timespecのメンバがマイクロ秒なのかどうかが気になった。

/usr/include/sys/time.hを見るとstruct timespecのメンバはtv_nsecで、ナノ秒を取りそうなことがわかった。また、Rubyのthread_pthread.cの413行でちゃんとマイクロ秒をナノ秒に変換していた。

-DTHREAD_DEBUGしてmakeするとthead_debugが何か教えてくれるかな。

$ rm -f thread.o
$ make cflags=-DTHREAD_DEBUG miniruby
$ ./miniruby -e 'Thread.new{}.join(1000000000)'
0x1ffe00000 - create: 0x1203a5800 (0)0x1ffe00000 - thread_join (thid: 0x162e00000)
0x1ffe00000 - native_sleep 999999999
0x1ffe00000 - native_sleep: pthread_cond_timedwait start (-2096164855, 18650000)
miniruby: Error detected by libpthread: Invalid wait time.
Detected by file "/home/builds/ab/netbsd-3-1-RELEASE/src/lib/libpthread/pthread_cond.c", line 186, function "pthread_cond_timedwait".
See pthread(3) for information.
Abort trap

ts.tv_secが負になっちゃってるんだね。んー…thred_debugの引数の型キャストを信じれば、%ldが変なんだ。

$ diff -u thread_pthread.c{.orig,}
--- thread_pthread.c.orig       2007-12-24 18:35:17.000000000 -1000
+++ thread_pthread.c    2007-12-27 14:43:45.000000000 -1000
@@ -440,7 +440,7 @@
            }
            else {
                int r;
-               thread_debug("native_sleep: pthread_cond_timedwait start (%ld, %ld)\n",
+               thread_debug("native_sleep: pthread_cond_timedwait start (%lu, %ld)\n",
                             (unsigned long)ts.tv_sec, ts.tv_nsec);
                r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond,
                                           &th->interrupt_lock, &ts);

と編集してもう一度minirubyを作る。

$ ./miniruby -e 'Thread.new{}.join(1000000000)'
0x1ffe00000 - create: 0x1203a5800 (0)0x1ffe00000 - thread_join (thid: 0x162e00000)
0x1ffe00000 - native_sleep 999999999
0x1ffe00000 - native_sleep: pthread_cond_timedwait start (18446744071613387011, 87061000)
miniruby: Error detected by libpthread: Invalid wait time.
Detected by file "/home/builds/ab/netbsd-3-1-RELEASE/src/lib/libpthread/pthread_cond.c", line 186, function "pthread_cond_timedwait".
See pthread(3) for information.
Abort trap

えーと。かなりでかい。が、型キャストしなきゃ負。 /usr/include/sys/time.hに戻る。timespecの定義は下記の通り

/*
 * Structure defined by POSIX.1b to be like a timeval.
 */
struct timespec {
  time_t  tv_sec;   /* seconds */
  long  tv_nsec;  /* and nanoseconds */
};

time_tは/usr/include/time.hで

typedef     _BSD_TIME_T_    time_t;

とされていて、_BSD_TIME_T_は、

$ grep _BSD_TIME_T_ /usr/include/*/*.h
/usr/include/alpha/ansi.h:#define       _BSD_TIME_T_            int             /* time() */
/usr/include/machine/ansi.h:#define     _BSD_TIME_T_            int             /* time() */
/usr/include/sys/stat.h:#if defined(_LP64)      /* XXXX  && _BSD_TIME_T_ == int */
/usr/include/sys/types.h:#ifdef _BSD_TIME_T_
/usr/include/sys/types.h:typedef        _BSD_TIME_T_            time_t;
/usr/include/sys/types.h:#undef _BSD_TIME_T_

とされている。うーん。int?

と、また中途半端に終わる。

と言ったーにアカウントを作ってみた (twitter.com)

…と思ったら既にFllowersが1に。ありがとうございます。

どちらかというとおもしろくない、本職の作業記録をつけていこうと思ってます。よろしくお願いします。(何をよろしく?)

[memo] 追加したフォントを現在のXのセッションで使えるようにする

Font インストールより、

$ grep efont-unicode /etc/X11/xorg.conf

などして調べた、追加したフォントのパスを

xset +fp /usr/share/X11/fonts/efont-unicode/

などとしてXサーバに知らせてあげる。

日本 Ruby 会議 2008 (rubyist.net)

今年はつくばなんですね〜などと眺めてたら、ある出張の直前だということが判明。はてさて参加できるかどうか。


作り手とその取り巻きだけが楽しんでる間は本物じゃない。その中身が理解できない人々の生活を変えてこそ本物だ


zunda <zunda at freeshell.org>