running ruby on solaris (rubykaigi 2015, 12/dec/2015)
TRANSCRIPT
BioRuby
Running Ruby on SolarisNaohisa Goto / 後藤直久
Genome Information Research Center, Research Institute for Microbial Diseases, Osaka Univ.大阪大学微生物病研究所附属遺伝情報実験センターEmail: [email protected]: @ngotogenomeGitHub: ngoto
BioRuby
Who am I ? / 自己紹介
Name: Naohisa Goto / 名前 : 後藤 直久
Affiliation: Genome Information Research Center, Research Institute for Microbial Diseases, Osaka University所属 : 大阪大学微生物病研究所附属遺伝情報実験センター
Position: Assistant Professor / 役職 : 助教
Twitter: @ngotogenomeGitHub: ngotoEmail: [email protected]
First Ruby experience: 1.2.6 (compiled in 22/Jun/1999)
BioRuby
Who am I ? / 自己紹介
First Ruby experience: 1.2.6compiled in 22/Jun/1999
Using Ruby for genome data analysisBioRuby developer since 2001
CRuby committer since July/2011as a platform maintainer of Solaris
RubySpec committer since Oct/2015.
BioRuby
My Activities: BioRubyBioinformatics software library and tools
written in the Ruby LanguageRuby で書かれた生物情報科学(バイオインフォマティクス)用ライブラリとツール集
Free software (Ruby License)http://bioruby.org/https://github.com/bioruby/bioruby% gem install bio
BioRuby
Next-Generation DNA Sequencers
Performance: > 50Gb/day!
次世代シークエンサー
BioRuby
Our Servers for Genome Data Analysis
Fujitsu PRIMEQUEST1800E2CPU: Xeon E7-8870 x 8 (80 cores)Memory: 2TBOS: RedHat Enterprise Linux 6.5
Fujitsu SPARC Enterprise M5000CPU: SPARC64VII 2.66GHz x 4Memory: 512GBOS: Solaris10
Fujitsu PRIMERGY RX200 x 18CPU: Xeon X5690 x2 (12 cores)Memory: 96GB OS: RedHat Enterprise Linux 6.5
DDN GridScaler3TB SATA HDD x 600 = 1.8PB(Actual capacity 1.2PB)
BioRuby
What is Solaris?"Solaris is a Unix operating system originally
developed by Sun Microsystems."「 Solaris (ソラリス)はサン・マイクロシステムズ(サン)によって開発され、 UNIX として認証を受けたオペレーティングシステム (OS) である。」
"Oracle Solaris, as it is named as of 2010, has been owned by Oracle Corporation since the Sun acquisition by Oracle in January 2010."「 2010 年 1 月 27 日のオラクルによるサン買収に伴い、現在の開発は同社が担っている。」
Proprietary, closed source / 商用、ソース非公開https://en.wikipedia.org/wiki/Solaris_%28operating_system%29https://ja.wikipedia.org/wiki/Solaris
BioRuby
History of Solaris 1983SunOS 1.0
…1988/12 SunOS 4.01992/6 Solaris 2.0 (= SunOS 5.0)
…1997/7 Solaris 2.61998/11 Solaris 7 (= Solaris 2.7 = SunOS
5.7)…
2005/1 Solaris 102011/11 Solaris 11
BioRuby
Features of Solaris / 特徴
Cutting-edge features / 先端機能Solaris Container (Zone)ZFSDTraceRBAC (Role-Based Access Control)…
Backward compatibility / 後方互換性Old binary can be run without changes古いバイナリがそのまま動く
BioRuby
Demo: Binary in 1999 works!
The old binary "ruby_1.2.6" build in Jun 22 1999 works on Solaris 10 today without modification!
BioRuby
Supported ArchitectureSPARC
Original hardware sold by Oracle, Fujitsu, etc."SPARC Solaris"
x64 (x86-64, AMD64, Intel 64)PC (IBM PC/AT compatible architecture)
"Intel Solaris"
BioRuby
SPARC ProcessorRISC instruction set architectureBig-endian
Developed by Sun Microsystems since 1987SPARC is a registered trademark of SPARC
International, Inc. since 1989The SPARC architecture is fully open, non-
proprietary and royalty free.Current versions:
SPARC V8 (32-bit) and SPARC V9 (64-bit)
BioRuby
Why I started using Solaris?I've been using Solaris on SPARC since
1999, simply because they have been available in our institute. / 所属組織にあったから、 1999 年から使用。
In 1990's, Solaris and SPARC was the best choice of scientific computing.1990 年代、 Solaris と SPARC は科学技術演算に最適だった。De-facto standard / 事実上の標準Availability of software was good / ソフトの入手
が容易
BioRuby
Why do I still use Solaris?Today, our main machines are Linux.We still maintain a SPARC Solaris server
For the past software / 昔のソフトを使うためFor reproducibility of science / 科学の再現性のた
め
BioRuby
How I became a Ruby Committer1. Report a bug on Solaris / バグを報告• Including build failure, test failure/error
2. Report patch for the bug / パッチを書いて送る
3. Repeat 1..2 several times / 1,2 を数回繰り返す
BioRuby
How to build Ruby on SolarisRecommended requirements
GNU TarGNU BashGNU MakeGNU BinutilsOpenSSL
Requirements to build from SVN headGNU AutoconfGNU BisonLibffiRuby
BioRuby
PATH is importantTwo or more variants for a command may
exist in different directoriese.g. make
/usr/ccs/bin/make/usr/xpg4/bin/make/usr/sfw/bin/gmake/usr/local/bin/make (installed by system admin)…
Setting appropriate PATH is important!The order of directories in PATH is also
important
BioRuby
C/C++ Compilers on SolarisOracle Solaris Studio
Latest version: 12.4 (Nov/2014)Former names: Sun Studio, Sun Workshop/opt/SolarisStudio12.4/bin/cc
GCC/usr/sfw/bin/gcc (version 3.4.3)/opt/csw/bin/gcc, /usr/local/bin/gcc, …
Fujitsu C Compiler (fcc)Latest version: ??? (I'm using 5.6 (Nov/2006))/opt/FSUNf90/bin/fcc
BioRuby
StandardsSolaris supports multiple standards, including:
System V Interface Definition Edition 3 (SVID) X/Open ANSI C (C90) POSIX.1-2001 (SUSv3) ISO C (C99)
Compile-time options for selecting some standardse.g. -D_XOPEN_SOURCE=500 for SUSv2.
Since Ruby 2.3, -D_XOPEN_SOURCE=xxx is automatically added.
Behaviors may be changed with the selected standards.See "man standards"For libm (Math) functions, see
http://docs.oracle.com/cd/E37069_01/html/E39019/z4000ac610479.html
BioRuby
64-bit compileSolaris is 64-bit OS, but most binaries are
32-bitFor keeping backward compatibility?
Compiler's default: 32-bit compile
64-bit compile option in CFLAGSGCC: -m64Oracle Solaris Studio (Sun Studio) 12.x: -m64Sun Studio (Sun Workshop) 11 or earlier:
SPARC: -xarch=v9x86 (Intel): -xarch=generic64
Fujitsu C Compiler (fcc): -KV9
BioRuby
64-bit compile: 64-bit LibrarySolaris is 64-bit OS, but most binaries are
32-bitAll major compiler's defaults are 32-bit
64-bit libraries are often forgotten to be installed, especially for installation by hand without using package management system. パッケージ管理システムを使わない手動インストールの場合、 64 ビットのライブラリはインスールされ忘れている事が多い。
BioRuby
Default Library Search Path"crle" shows default library search path
Equivalent of "ldconfig" in Linux and *BSD."crle" for 32-bit, "crle -64" for 64-bit
% crle
Default configuration file (/var/ld/ld.config) not found Platform: 32-bit MSB SPARC Default Library Path (ELF): /lib:/usr/lib (system default) Trusted Directories (ELF): /lib/secure:/usr/lib/secure (system default)
% crle -64
Default configuration file (/var/ld/64/ld.config) not found Platform: 64-bit MSB SPARCV9 Default Library Path (ELF): /lib/64:/usr/lib/64 (system default) Trusted Directories (ELF): /lib/secure/64:/usr/lib/secure/64 (system default)
BioRuby
Extra LibrariesLibrary locations (not in the default search
path) should be specified in LDFLAGS-L for static libraries, -R for shared libraries.Example for GCC and Oracle Solaris Studio 12:
LDFLAGS="-m64 -L/usr/local/64/lib -R/usr/local/64/lib"
C header file locations should also be specified in CPPFLAGSe.g. CPPFLAGS="-I/usr/local/64/include"
BioRuby
LD_LIBRARY_PATH considered harmfulLD_LIBRARY_PATH and derivatives for
runtime shared library path. LD_LIBRARY_PATH for both 32- and 64-bitLD_LIBRARY_PATH_32 for 32-bitLD_LIBRARY_PATH_64 for 64-bit
They should only be used for temporary use.
Don't set LD_LIBRARY_PATH globallyDon't set in .cshrc, .login, .profile, etc.
BioRuby
64-bit build nameEven when setting 64-bit compile option, build
name guessed by ./configure would be the same as that of 32-bit compile.(32-bit) SPARC Solaris 10: sparc-sun-solaris2.10(32-bit) Intel Solaris 10: i386-pc-solaris2.10
Setting build name for 64-bit compile is recommended.SPARC Solaris 10: --build=sparc64-sun-
solaris2.10Intel Solaris 10: --build=x86_64-pc-solaris2.10
% ./configure --help(snip)System types: --build=BUILD configure for building on BUILD [guessed]
BioRuby
Example of ./configureCompiler: Oracle Solaris Studio 12.464-bit compile
% setenv PATH /opt/SolarisStudio12.4/bin:/usr/local/64/bin:/usr/local/bin:/usr/ccs/bin:/usr/xpg4/bin:/usr/bin:/bin:/usr/open-win/bin:/usr/dt/bin:/usr/X11/bin:/usr/sbin
% unsetenv LD_LIBRARY_PATH% unsetenv LD_LIBRARY_PATH_32% unsetenv LD_LIBRARY_PATH_64% setenv CC "cc"% setenv CXX "CC"% setenv CPPFLAGS "-I/usr/local/64/include"% setenv CFLAGS "-xO3 -m64"% setenv CXXFLAGS $CFLAGS% setenv LDFLAGS "-m64 -L/usr/local/64/lib -R/usr/local/64/lib"% setenv DLDFLAGS $LDFLAGS% ./configure --prefix=/home/xxxx/testruby/2.3.0
--build=sparc64-sun-solaris2.10 --with-tclConfig-dir=/usr/local/64/lib --with-tkConfig-dir=/usr/local/64/lib
BioRuby
makechecking if make is GNU make... yeschecking for nroff... /usr/bin/nroff.ext/include/sparc64-solaris2.10/ruby/config.h updatedconfigure: ruby library version = 2.3.0configure: creating ./config.statusconfig.status: creating GNUmakefileconfig.status: creating Makefileconfig.status: creating ruby-2.3.pc% make V=1
cc -xO3 -xtarget=sparc64viiplus -m64 -DRUBY_EXPORT -I/usr/local/64/include -I. -I.ext/include/sparc64-solaris2.10 -I./include -I. -o parse.o -c parse.c"parse.y", line 1256: operands have incompatible types: void ":" int(snip)cc: acomp failed for parse.cmake: *** [parse.o] Error 2
BioRuby
Reporting Bug via bugs.ruby-lang.org
BioRuby
Typical Bugs on Solaris, SPARCTypo inside #if .. #endif conditionsConflict of names
File name, function, macro, …
EndianWord alignment
BioRuby
Simple Bug Fix: Typo
(r36290) [Bug #6689][ruby-dev:45904]Only affected on Solaris, because it was inside #if.The person who wrote the original line (@nobu)
did not (and could not) test the code on 64-bit Solaris.
Even for the super programmer, it is difficult to check such code without building and running on the platform.
#elif defined(__sun) #include <atomic.h> # if SIZEOF_SIZE_T == SIZEOF_LONG # define ATOMIC_SIZE_ADD(var, val) atomic_add_long(&(var), (val)) # define ATOMIC_SIZE_SUB(var, val) atomic_add_long(&(var), -(val)) # define ATOMIC_SIZE_INC(var) atomic_inc_ulong(&(var)) # define ATOMIC_SIZE_DEC(var) atomic_dec_ulong(&(var))-# define ATOMIC_SIZE_EXCHANGE(var, val) atomic_swap_long(&(var), (val))+# define ATOMIC_SIZE_EXCHANGE(var, val) atomic_swap_ulong(&(var), (val))
BioRuby
Simple Fix: Conflict of names(r37604) [ruby-dev:46414] [Bug #7287]
Solaris has "atomic.h" in /usr/includeThere was "atomic.h" in Ruby source
Only the latter was loaded, but both were needed
Renamed "atomic.h" to "ruby_atomic.h" in Ruby source code
BioRuby
Big-Endian and Little-Endian
1A2B3C4D
4D3C2B1A
Big-Endian(SPARC, etc.)
Little-Endian(x86_64, etc.)
xx+1x+2x+3
(32-bit integer)1A 2B 3C 4D
xx+1x+2x+3
BioRuby
Big-Endian and Little-Endian
000000001A2B3C4D
4D3C2B1A00000000
Big-Endian(SPARC, etc.)
Little-Endian(x86_64, etc.)
xx+1x+2x+3x+4x+5x+6x+7
(64-bit integer)00 00 00 00 1A 2B 3C 4D
xx+1x+2x+3x+4x+5x+6x+7
BioRuby
Endian Bug Fix
(r37996) [ruby-core:50292] [Bug #7463]
--- a/ext/openssl/ossl_ssl.c+++ b/ext/openssl/ossl_ssl.c@@ -569,10 +569,12 @@ static VALUE ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded) { int len = RSTRING_LENINT(cur);+ char len_byte; if (len < 1 || len > 255) ossl_raise(eSSLError, "Advertised protocol must have length 1..255"); /* Encode the length byte */- rb_str_buf_cat(encoded, (const char *) &len, 1);+ len_byte = len;+ rb_str_buf_cat(encoded, &len_byte, 1); rb_str_buf_cat(encoded, RSTRING_PTR(cur), len); return Qnil; }
BioRuby
Word AlignmentOn SPARC, n-byte (= n * 8 bit) integer or
float data must be put at a memory address equal to some multiple of the word size n.
1A 2B 3C 4DAddress: 0x100 0x101 0x102 0x103 0x104 0x105 0x106 0x107
1A 2B 3C 4D
1A 2B 3C 4D
1A 2B 3C 4D
1A 2B 3C 4D
OK
OK
Bus Error
Bus Error
Bus Error
BioRuby
Alignment Bug Fix+#if !defined(INFINITY) || !defined(NAN)+union bytesequence4_or_float {+ unsigned char bytesequence[4];+ float float_value;+};+#endif
#ifdef HAVE_INFINITY #elif !defined(WORDS_BIGENDIAN) /* BYTE_ORDER == LITTLE_ENDIAN */-const unsigned char rb_infinity[] = "\x00\x00\x80\x7f";+const union bytesequence4_or_float rb_infinity = { 0x00, 0x00, 0x80, 0x7f }; #else-const unsigned char rb_infinity[] = "\x7f\x80\x00\x00";+const union bytesequence4_or_float rb_infinity = { 0x7f, 0x80, 0x00, 0x00 }; #endif
-RUBY_EXTERN const unsigned char rb_infinity[];-# define INFINITY (*(float *)rb_infinity)+RUBY_EXTERN const union bytesequence4_or_float rb_infinity;+# define INFINITY (rb_infinity.float_value)
(r33502) [Bug #5469] [ruby-dev: 44657]
BioRuby
Most Bugs are non-specificMost bugs occurred on Solaris were NOT
specific to the platform but would affect all platforms.
Difference of platform can reveal hidden bugsDifferent OSDifferent memory managementDifferent CPU architecture
EndianAlignment
Different compiler
BioRuby
Integer Overflow(r32757) [ruby-dev:43284] [Bug #4456]
s+(n) overflows when n is very larges: pointer; n: value coming from user's Ruby
codeOn i386 Linux, it overflows with very large n such as
(2**31-1)On 32-bit SPARC Solaris, it overflows with relatively
smaller value, due to the different memory management.
Calculation order was changed to prevent overflow-#define NEEDS(n) do if (s + (n) >= endp - 1) goto err; while (0)+#define NEEDS(n) do if (s >= endp || (n) >= endp - s - 1) goto err; while (0) #define FILL_PADDING(i) do { \ if (!(flags & BIT_OF(LEFT)) && precision > (i)) { \ NEEDS(precision); \
BioRuby
Forgotten "+1"(r48999) [ruby-dev:48779] [Bug #10646]
The allocated memory size of ptr includes the region to record its size, and thus "+1" must be needed.During make test-all, SEGV observed only on Solaris, but
apparently all platforms should be affected.
--- a/gc.c+++ b/gc.c@@ -7674,5 +7674,5 @@ wmap_final_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)if (j < i) {- ptr = ruby_sized_xrealloc2(ptr, j, sizeof(VALUE), i);+ ptr = ruby_sized_xrealloc2(ptr, j + 1, sizeof(VALUE), i); ptr[0] = j; *value = (st_data_t)ptr; }
BioRuby
transcode.c: fix race condition(r51037) [ruby-dev:49106] [Bug #11277]https://bugs.ruby-lang.org/issues/11277Summary:The bug was first observed only on Solaris. I found that it also occurred on Linux, after
investigation. I found a simple reproduction code.
Fixed by @nobu
% ruby --disable=gems -e '(0..2).collect { |_| Thread.new { p "\u3042".encode("EUC-JP") }}.each { |t| t.join }' -e:1: warning: failed to load encoding (EUC-JP); use ASCII-8BIT instead-e:1:in `encode': code converter not found (UTF-8 to EUC-JP) (Encoding::ConverterNotFoundError) from -e:1:in `block (2 levels) in <main>'
BioRuby
make test-all: 0 failures, 0 errors% make test-all TESTS=-v V=1(snip)XMLRPC::ClientTest#test_new2_ssl_custom_port = 0.00 s = .XMLRPC::ClientTest#test_new2_user_password = 0.00 s = .XMLRPC::ClientTest#test_request = 0.03 s = .
Finished tests in 1537.222241s, 10.3446 tests/s, 1451.5078 assertions/s.
15902 tests, 2231290 assertions, 0 failures, 0 errors, 49 skips
ruby -v: ruby 2.3.0dev (2015-12-01) [sparc64-solaris2.10]make: Nothing to be done for `test-all'.
BioRuby
ConclusionsIt is very difficult to write code with no bugs
without building and running the code, even for super programmers.たとえ神プログラマであっても、ビルド・実行せずにバグの無いコードを書くのは難しい。
Running on different platforms would reveal hidden bugs. That's one of the reasons why it is good to maintain various platforms.異なる環境で実行したら、隠れたバグが見つかることがあるのが、多様な環境をサポートするのが良い理由の一つ。