Bug #1919

sparc-solaris-2.10 で 1.9.2-preview1 がビルドできない

Added by ngoto (Naohisa Goto) almost 3 years ago. Updated about 1 year ago.

Status:Closed Start date:08/10/2009
Priority:Normal Due date:
Assignee:matz (Yukihiro Matsumoto) % Done:

0%

Category:core
Target version:1.9.2
ruby -v:ruby 1.9.2dev (2009-07-18 trunk 24186) [sparc-solaris2.10]

Description

ruby 1.9.2-preview1 が SPARC 上の Solaris10 で make に失敗します。

手動で二分検索をやってみたところ、r23240 は make install-nodoc できましたが
r23241 は make に失敗しました。

以下、1.9.2-preview1 にて make が失敗するところの抜粋です。
(ファイルの場所は一部マスクしています)

$ export PATH=/usr/local/64/bin:/usr/local/bin:/usr/ccs/bin:/usr/xpg4/bin:/usr/bin:/bin:/usr/openwin/bin:/usr/dt/bin:/usr/X11/bin:/usr/sfw/bin
$ CC=gcc-4.3 CFLAGS="-m64 -I/usr/local/64/include" CXX=g++-4.3 CXXFLAGS="-m64 -I/usr/local/64/include" LDFLAGS="-m64 -L/usr/local/64/lib -R/usr/local/64/lib" ./configure --prefix=/XXXXX/testruby/sparc/1.9.2-preview1
$ gcc-4.3 --version
gcc-4.3 (GCC) 4.3.3
(中略)
$ make
(中略)
./miniruby -I./lib -I.ext/common -I./- -r./ext/purelib.rb  ./enc/make_encmake.rb --builtin-encs="ascii.o us_ascii.o unicode.o utf_8.o" --builtin-transes="newline.o" enc.mk 
./enc/depend:5: [BUG] Segmentation fault
ruby 1.9.2dev (2009-07-18 trunk 24186) [sparc-solaris2.10]

-- control frame ----------
c:0012 p:---- s:0058 b:0058 l:000057 d:000057 CFUNC  :each
c:0011 p:---- s:0056 b:0056 l:000055 d:000055 CFUNC  :grep
c:0010 p:0013 s:0052 b:0052 l:000698 d:000051 BLOCK  ./enc/depend:5
c:0009 p:---- s:0049 b:0049 l:000048 d:000048 FINISH
c:0008 p:---- s:0047 b:0047 l:000046 d:000046 CFUNC  :open
c:0007 p:0100 s:0043 b:0043 l:000698 d:0024f8 EVAL   ./enc/depend:5
c:0006 p:---- s:0025 b:0025 l:000024 d:000024 FINISH
c:0005 p:---- s:0023 b:0023 l:000022 d:000022 CFUNC  :eval
c:0004 p:0062 s:0016 b:0016 l:000015 d:000015 METHOD /XXXXX/src/64gcc/ruby-1.9.2-preview1/lib/erb.rb:753
c:0003 p:0571 s:0012 b:0012 l:000698 d:0008f8 EVAL   ./enc/make_encmake.rb:41
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:000698 d:000698 TOP   
---------------------------
./enc/make_encmake.rb:41:in `<main>'
/XXXXX/src/64gcc/ruby-1.9.2-preview1/lib/erb.rb:753:in `result'
/XXXXX/src/64gcc/ruby-1.9.2-preview1/lib/erb.rb:753:in `eval'
./enc/depend:5:in `<main>'
./enc/depend:5:in `open'
./enc/depend:5:in `block in <main>'
./enc/depend:5:in `grep'
./enc/depend:5:in `each'

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

異常終了
make: *** [enc.mk] Error 134
$ 

以下は、同様に r23241 にて make が失敗するところの抜粋です。
configure のオプションは上記と prefix 以外は同じです。

$ make
./miniruby -I./lib -I.ext/common -I./- -r./ext/purelib.rb  ./enc/make_encmake.rb --builtin-encs="ascii.o us_ascii.o unicode.o utf_8.o" --builtin-transes="newline.o" enc.mk 
./enc/depend:5: [BUG] Segmentation fault
ruby 1.9.2dev (2009-04-21) [sparc-solaris2.10]

-- control frame ----------
c:0012 p:---- s:0058 b:0058 l:000057 d:000057 CFUNC  :each
c:0011 p:---- s:0056 b:0056 l:000055 d:000055 CFUNC  :grep
c:0010 p:0013 s:0052 b:0052 l:001a48 d:000051 BLOCK  ./enc/depend:5
c:0009 p:---- s:0049 b:0049 l:000048 d:000048 FINISH
c:0008 p:---- s:0047 b:0047 l:000046 d:000046 CFUNC  :open
c:0007 p:0100 s:0043 b:0043 l:001a48 d:002078 EVAL   ./enc/depend:5
c:0006 p:---- s:0025 b:0025 l:000024 d:000024 FINISH
c:0005 p:---- s:0023 b:0023 l:000022 d:000022 CFUNC  :eval
c:0004 p:0059 s:0016 b:0016 l:000015 d:000015 METHOD /XXXXX/src/64gcc/trunk-23241/lib/erb.rb:753
c:0003 p:0571 s:0012 b:0012 l:001a48 d:0010f8 EVAL   ./enc/make_encmake.rb:41
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:001a48 d:001a48 TOP   
---------------------------
./enc/make_encmake.rb:41:in `<main>'
/XXXXX/src/64gcc/trunk-23241/lib/erb.rb:753:in `result'
/XXXXX/src/64gcc/trunk-23241/lib/erb.rb:753:in `eval'
./enc/depend:5:in `<main>'
./enc/depend:5:in `open'
./enc/depend:5:in `block in <main>'
./enc/depend:5:in `grep'
./enc/depend:5:in `each'

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

異常終了
make: *** [enc.mk] Error 134
$

そして、r23240 にて make check を行ったところ、
1回だけ以下のFAILが出ましたが、それ以後は再現しませんでした。

#753 test_io.rb:11:in `<top (required)>': 
     begin
       require "io/nonblock"
       r, w = IO.pipe
       w.nonblock = true
       w.write_nonblock("a" * 100000)
       w.nonblock = false
       t1 = Thread.new { w.write("b" * 4096) }
       t2 = Thread.new { w.write("c" * 4096) }
       sleep 0.5
       r.sysread(4096).length
       sleep 0.5
       r.sysread(4096).length
       t1.join
       t2.join
     rescue LoadError
     end
  #=> not finished in 10 seconds  [ruby-dev:32566]
FAIL 1/935 tests failed
make: *** [btest-ruby] Error 1

そして、上記のFAILが出ない場合は、以下の場所で止まります。

$ make check
(略)
PASS all 935 tests
./miniruby -I./lib -I.ext/common -I./- -r./ext/purelib.rb  "./bootstraptest/runner.rb" --ruby="ruby"  ./KNOWNBUGS.rb
2009-08-10 23:30:18 +0900
Driver is ruby 1.9.2dev (2009-04-21) [sparc-solaris2.10]
Target is ruby 1.9.2dev (2009-04-21) [sparc-solaris2.10]


KNOWNBUGS.rb .
PASS all 1 tests
./miniruby -I./lib -I.ext/common -I./- -r./ext/purelib.rb  ./runruby.rb --extout=.ext  -- "./test/runner.rb" 
libc and libm not found: ./test/runner.rb <libc> <libm>
Gem::Indexer tests are being skipped.  Install builder gem.
Loaded suite ./test/runner
Started
...................................................................................................F/XXXXX/src/64gcc/trunk-23240/test/dl/test_func.rb:44: [BUG] Segmentation fault
ruby 1.9.2dev (2009-04-21) [sparc-solaris2.10]

-- control frame ----------
c:0022 p:---- s:0087 b:0087 l:000086 d:000086 CFUNC  :[]
c:0021 p:0040 s:0083 b:0082 l:002290 d:000081 BLOCK  /XXXXX/src/64gcc/trunk-23240/test/dl/test_func.rb:44
c:0020 p:---- s:0078 b:0078 l:000077 d:000077 FINISH
c:0019 p:---- s:0076 b:0076 l:000075 d:000075 CFUNC  :call
c:0018 p:0047 s:0071 b:0071 l:001378 d:000070 BLOCK  /XXXXX/src/64gcc/trunk-23240/.ext/common/dl/func.rb:67
c:0017 p:---- s:0066 b:0066 l:000065 d:000065 FINISH
c:0016 p:---- s:0064 b:0064 l:000063 d:000063 CFUNC  :call
c:0015 p:---- s:0062 b:0062 l:000061 d:000061 CFUNC  :call
c:0014 p:0053 s:0058 b:0058 l:000057 d:000057 METHOD /XXXXX/src/64gcc/trunk-23240/.ext/common/dl/func.rb:37
c:0013 p:0163 s:0051 b:0051 l:002290 d:002290 METHOD /XXXXX/src/64gcc/trunk-23240/test/dl/test_func.rb:48
c:0012 p:0041 s:0045 b:0045 l:000044 d:000044 METHOD /XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:440
c:0011 p:0096 s:0039 b:0039 l:000019 d:000038 BLOCK  /XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:419
c:0010 p:---- s:0033 b:0033 l:000032 d:000032 FINISH
c:0009 p:---- s:0031 b:0031 l:000030 d:000030 CFUNC  :each
c:0008 p:0026 s:0028 b:0028 l:000019 d:000027 BLOCK  /XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:413
c:0007 p:---- s:0025 b:0025 l:000024 d:000024 FINISH
c:0006 p:---- s:0023 b:0023 l:000022 d:000022 CFUNC  :each
c:0005 p:0080 s:0020 b:0020 l:000019 d:000019 METHOD /XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:412
c:0004 p:0153 s:0015 b:0015 l:000014 d:000014 METHOD /XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:392
c:0003 p:0041 s:0007 b:0007 l:000688 d:000006 BLOCK  /XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:333
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:001358 d:001358 TOP   
---------------------------
/XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:333:in `block in autorun'
/XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:392:in `run'
/XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:412:in `run_test_suites'
/XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:412:in `each'
/XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:413:in `block in run_test_suites'
/XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:413:in `each'
/XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:419:in `block (2 levels) in run_test_suites'
/XXXXX/src/64gcc/trunk-23240/lib/minitest/unit.rb:440:in `run'
/XXXXX/src/64gcc/trunk-23240/test/dl/test_func.rb:48:in `test_qsort1'
/XXXXX/src/64gcc/trunk-23240/.ext/common/dl/func.rb:37:in `call'
/XXXXX/src/64gcc/trunk-23240/.ext/common/dl/func.rb:37:in `call'
/XXXXX/src/64gcc/trunk-23240/.ext/common/dl/func.rb:37:in `call'
/XXXXX/src/64gcc/trunk-23240/.ext/common/dl/func.rb:67:in `block in bind'
/XXXXX/src/64gcc/trunk-23240/.ext/common/dl/func.rb:67:in `call'
/XXXXX/src/64gcc/trunk-23240/test/dl/test_func.rb:44:in `block in test_qsort1'
/XXXXX/src/64gcc/trunk-23240/test/dl/test_func.rb:44:in `[]'

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

異常終了
make: *** [test-all] Error 134

config.h - ruby-1.9.2-preview1/.ext/include/sparc-solaris2.10/ruby/config.h (6.9 kB) ngoto (Naohisa Goto), 08/11/2009 12:49 pm

History

Updated by nobu (Nobuyoshi Nakada) almost 3 years ago

なかだです。

At Mon, 10 Aug 2009 23:40:36 +0900,
Naohisa Goto wrote in [ruby-dev:39060]:
> ruby 1.9.2-preview1 が SPARC 上の Solaris10 で make に失敗します。
> 
> 手動で二分検索をやってみたところ、r23240 は make install-nodoc できましたが
> r23241 は make に失敗しました。

http://docs.sun.com/app/docs/doc/819-2243/readdir-r-3c?a=view を
みると、_POSIX_PTHREAD_SEMANTICSがないとreaddir_r()がPOSIX準拠に
ならないようですね。

これでどうでしょうか。


Index: configure.in
===================================================================
--- configure.in	(revision 24493)
+++ configure.in	(working copy)
@@ -743,4 +743,8 @@ esac

 case "$target_os" in
+when(solaris*)
+		RUBY_APPEND_OPTIONS(CPPFLAGS, -D_POSIX_PTHREAD_SEMANTICS)
+		LIBS="-lm $LIBS"
+		;;
 when(nextstep*)	;;
 when(openstep*)	;;


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

Updated by ngoto (Naohisa Goto) almost 3 years ago

Solaris の readdir_r について調べてみたところ、
"readdir_r considered harmful"
http://womble.decadentplace.org.uk/readdir_r-advisory.html
という文章を見つけました。これによると、

> On Linux (with glibc) and most versions of Unix, struct dirent
> is large enough to hold maximum-length names from most filesystems,
> so this is safe (though > wasteful). This is not true of Solaris
> and BeOS, where the d_name member is an array of length 1. 

とのことでした。どうやら Solaris では、struct dirent entry のメモリを
確保する際、ファイル名の長さを考慮に入れた十分な長さを自前で確保する
必要があるようです。

> これでどうでしょうか。

config.h を示すのを忘れていました。
1.9.2-preview1の場合のconfig.hをredmine上にて添付します。
autoconf (バージョン 2.61 を使用)が自動的に
  #define _POSIX_PTHREAD_SEMANTICS 1
を追加してくれていたようです。

パッチも念のため試しましたが、やはりダメでした。
この場合の config.h の実質的な変更点は、添付のものから
#define _ALL_SOURCE 1
の行が抜けただけでした。

Updated by ngoto (Naohisa Goto) almost 3 years ago

後藤といいます。自己レスです。

On Tue, 11 Aug 2009 12:49:55 +0900
Naohisa Goto wrote:

> Solaris の readdir_r について調べてみたところ、
> "readdir_r considered harmful"
> http://womble.decadentplace.org.uk/readdir_r-advisory.html
> という文章を見つけました。これによると、
> 
> > On Linux (with glibc) and most versions of Unix, struct dirent
> > is large enough to hold maximum-length names from most filesystems,
> > so this is safe (though > wasteful). This is not true of Solaris
> > and BeOS, where the d_name member is an array of length 1. 
> 
> とのことでした。どうやら Solaris では、struct dirent entry のメモリを
> 確保する際、ファイル名の長さを考慮に入れた十分な長さを自前で確保する
> 必要があるようです。

とりあえずは、共用体にして無理矢理メモリを確保すると、make は通り、
make install できました。以下にパッチを添付します。

より正しくは、上記文章のように毎回 fpathconf を呼び出して
ファイル名の最大長を取得し、それを元にメモリを確保する必要が
あるのだとは思いますが、とりあえずのパッチです。

相変わらずdlのテストは失敗しますが、dlについては、別チケットを
作りたいと思います。


Index: dir.c
===================================================================
--- dir.c	(revision 24578)
+++ dir.c	(working copy)
@@ -491,6 +491,39 @@
 # define IF_HAVE_READDIR_R(something) /* nothing */
 #endif

+#if defined SIZEOF_STRUCT_DIRENT_TOO_SMALL
+# include <limits.h>
+# define NAME_MAX_FOR_STRUCT_DIRENT 255
+# if defined NAME_MAX
+#  if NAME_MAX_FOR_STRUCT_DIRENT < NAME_MAX
+#   undef  NAME_MAX_FOR_STRUCT_DIRENT
+#   define NAME_MAX_FOR_STRUCT_DIRENT NAME_MAX
+#  endif
+# endif
+# if defined _POSIX_NAME_MAX
+#  if NAME_MAX_FOR_STRUCT_DIRENT < _POSIX_NAME_MAX
+#   undef  NAME_MAX_FOR_STRUCT_DIRENT
+#   define NAME_MAX_FOR_STRUCT_DIRENT _POSIX_NAME_MAX
+#  endif
+# endif
+# if defined _XOPEN_NAME_MAX
+#  if NAME_MAX_FOR_STRUCT_DIRENT < _XOPEN_NAME_MAX
+#   undef  NAME_MAX_FOR_STRUCT_DIRENT
+#   define NAME_MAX_FOR_STRUCT_DIRENT _XOPEN_NAME_MAX
+#  endif
+# endif
+# define DEFINE_STRUCT_DIRENT \
+  union { \
+    struct dirent dirent; \
+    char dummy[offsetof(struct dirent, d_name) + \
+	       NAME_MAX_FOR_STRUCT_DIRENT + 1]; \
+  }
+# define STRUCT_DIRENT(entry) ((entry).dirent)
+#else
+# define DEFINE_STRUCT_DIRENT struct dirent
+# define STRUCT_DIRENT(entry) (entry)
+#endif
+
 /*
  *  call-seq:
  *     dir.read => string or nil
@@ -508,11 +541,11 @@
 {
     struct dir_data *dirp;
     struct dirent *dp;
-    IF_HAVE_READDIR_R(struct dirent entry);
+    IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);

     GetDIR(dir, dirp);
     errno = 0;
-    if (READDIR(dirp->dir, dirp->enc, &entry, dp)) {
+    if (READDIR(dirp->dir, dirp->enc, &STRUCT_DIRENT(entry), dp)) {
 	return rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc);
     }
     else if (errno == 0) {	/* end of stream */
@@ -546,12 +579,12 @@
 {
     struct dir_data *dirp;
     struct dirent *dp;
-    IF_HAVE_READDIR_R(struct dirent entry);
+    IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);

     RETURN_ENUMERATOR(dir, 0, 0);
     GetDIR(dir, dirp);
     rewinddir(dirp->dir);
-    while (READDIR(dirp->dir, dirp->enc, &entry, dp)) {
+    while (READDIR(dirp->dir, dirp->enc, &STRUCT_DIRENT(entry), dp)) {
 	rb_yield(rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc));
 	if (dirp->dir == NULL) dir_closed();
     }
@@ -1270,11 +1303,11 @@
     if (magical || recursive) {
 	struct dirent *dp;
 	DIR *dirp;
-	IF_HAVE_READDIR_R(struct dirent entry);
+	IF_HAVE_READDIR_R(DEFINE_STRUCT_DIRENT entry);
 	dirp = do_opendir(*path ? path : ".", flags);
 	if (dirp == NULL) return 0;

-	while (READDIR(dirp, enc, &entry, dp)) {
+	while (READDIR(dirp, enc, &STRUCT_DIRENT(entry), dp)) {
 	    char *buf = join_path(path, dirsep, dp->d_name);
 	    enum answer new_isdir = UNKNOWN;

Index: configure.in
===================================================================
--- configure.in	(revision 24578)
+++ configure.in	(working copy)
@@ -750,6 +750,10 @@
 esac

 case "$target_os" in
+when(solaris*)
+		AC_DEFINE(SIZEOF_STRUCT_DIRENT_TOO_SMALL, 1)
+		LIBS="-lm $LIBS"
+		;;
 when(nextstep*)	;;
 when(openstep*)	;;
 when(rhapsody*)	;;


-- 
後藤 直久  ngoto@gen-info.osaka-u.ac.jp

Updated by matz (Yukihiro Matsumoto) almost 3 years ago

まつもと ゆきひろです

In message "Re: [ruby-dev:39132] Re: [Bug #1919] sparc-solaris-2.10  で 1.9.2-preview1  がビルドできない"
    on Wed, 19 Aug 2009 22:42:58 +0900, Naohisa GOTO <ngoto@gen-info.osaka-u.ac.jp> writes:

|> Solaris の readdir_r について調べてみたところ、
|> "readdir_r considered harmful"
|> http://womble.decadentplace.org.uk/readdir_r-advisory.html
|> という文章を見つけました。これによると、
|> 
|> > On Linux (with glibc) and most versions of Unix, struct dirent
|> > is large enough to hold maximum-length names from most filesystems,
|> > so this is safe (though > wasteful). This is not true of Solaris
|> > and BeOS, where the d_name member is an array of length 1. 
|> 
|> とのことでした。どうやら Solaris では、struct dirent entry のメモリを
|> 確保する際、ファイル名の長さを考慮に入れた十分な長さを自前で確保する
|> 必要があるようです。
|
|とりあえずは、共用体にして無理矢理メモリを確保すると、make は通り、
|make install できました。以下にパッチを添付します。

ありがとうございます。取り込みます。fpathconfを使ったパッチ
が提供されればそれも考慮します。

Updated by yugui (Yuki Sonoda) over 2 years ago

  • Category set to core
  • Status changed from Open to Assigned
  • Assignee set to matz (Yukihiro Matsumoto)
  • Priority changed from Normal to High
  • Target version set to 1.9.2

Updated by naruse (Yui NARUSE) over 2 years ago

  • Status changed from Assigned to Feedback
  • Priority changed from High to Normal

Updated by mame (Yusuke Endoh) about 2 years ago

  • Status changed from Feedback to Closed
遠藤です。

[ruby-dev:39132] で提示されたとりあえずのパッチは r24585 で
取り込まれたようなので close します。ありがとうございました。

よりよいパッチができたら、reopen するか何かしてください。

-- 
Yusuke Endoh <mame@tsg.ne.jp>

Also available in: Atom PDF