Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
1. BioRuby
Running Ruby on Solaris
Naohisa Goto / 後藤直久
Genome Information Research Center, Research
Institute for Microbial Diseases, Osaka Univ.
大阪大学微生物病研究所附属遺伝情報実験センター
Email: ngoto@gen-info.osaka-u.ac.jp
Twitter: @ngotogenome
GitHub: ngoto
2. BioRuby
Who am I ? / 自己紹介
Name: Naohisa Goto / 名前: 後藤 直久
Affiliation: Genome Information Research Center,
Research Institute for Microbial Diseases, Osaka University
所属: 大阪大学微生物病研究所附属遺伝情報実験センター
Position: Assistant Professor / 役職: 助教
Twitter: @ngotogenome
GitHub: ngoto
Email: ngoto@gen-info.osaka-u.ac.jp
First Ruby experience: 1.2.6 (compiled in 22/Jun/1999)
3. BioRuby
Who am I ? / 自己紹介
First Ruby experience: 1.2.6
compiled in 22/Jun/1999
Using Ruby for genome data analysis
BioRuby developer since 2001
CRuby committer since July/2011
as a platform maintainer of Solaris
RubySpec committer since Oct/2015.
4. BioRuby
My Activities: BioRuby
Bioinformatics software library and tools written
in the Ruby Language
Rubyで書かれた生物情報科学(バイオインフォマティ
クス)用ライブラリとツール集
Free software (Ruby License)
http://bioruby.org/
https://github.com/bioruby/bioruby
% gem install bio
6. BioRuby
Our Servers for Genome Data Analysis
Fujitsu PRIMEQUEST1800E2
CPU: Xeon E7-8870 x 8 (80 cores)
Memory: 2TB
OS: RedHat Enterprise Linux 6.5
Fujitsu SPARC Enterprise M5000
CPU: SPARC64VII 2.66GHz x 4
Memory: 512GB
OS: Solaris10
Fujitsu PRIMERGY RX200 x 18
CPU: Xeon X5690 x2 (12 cores)
Memory: 96GB
OS: RedHat Enterprise Linux 6.5
DDN GridScaler
3TB SATA HDD x 600 = 1.8PB
(Actual capacity 1.2PB)
7. 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%29
https://ja.wikipedia.org/wiki/Solaris
8. BioRuby
History of Solaris
1983 SunOS 1.0
…
1988/12 SunOS 4.0
1992/6 Solaris 2.0 (= SunOS 5.0)
…
1997/7 Solaris 2.6
1998/11 Solaris 7 (= Solaris 2.7 = SunOS 5.7)
…
2005/1 Solaris 10
2011/11 Solaris 11
9. BioRuby
Features of Solaris / 特徴
Cutting-edge features / 先端機能
Solaris Container (Zone)
ZFS
DTrace
RBAC (Role-Based Access Control)
…
Backward compatibility / 後方互換性
Old binary can be run without changes
古いバイナリがそのまま動く
10. 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!
11. BioRuby
Supported Architecture
SPARC
Original hardware sold by Oracle, Fujitsu, etc.
"SPARC Solaris"
x64 (x86-64, AMD64, Intel 64)
PC (IBM PC/AT compatible architecture)
"Intel Solaris"
12. BioRuby
SPARC Processor
RISC instruction set architecture
Big-endian
Developed by Sun Microsystems since 1987
SPARC is a registered trademark of SPARC
International, Inc. since 1989
The SPARC architecture is fully open, non-
proprietary and royalty free.
Current versions:
SPARC V8 (32-bit) and SPARC V9 (64-bit)
13. 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 / ソフトの入手が容易
14. 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 / 科学の再現性のため
15. BioRuby
How I became a Ruby Committer
1. 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 を数回繰り返す
16. BioRuby
How to build Ruby on Solaris
Recommended requirements
GNU Tar
GNU Bash
GNU Make
GNU Binutils
OpenSSL
Requirements to build from SVN head
GNU Autoconf
GNU Bison
Libffi
Ruby
17. BioRuby
PATH is important
Two or more variants for a command may exist
in different directories
e.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
18. BioRuby
C/C++ Compilers on Solaris
Oracle 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
19. BioRuby
Standards
Solaris 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 standards
e.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
20. BioRuby
64-bit compile
Solaris is 64-bit OS, but most binaries are 32-bit
For keeping backward compatibility?
Compiler's default: 32-bit compile
64-bit compile option in CFLAGS
GCC: -m64
Oracle Solaris Studio (Sun Studio) 12.x: -m64
Sun Studio (Sun Workshop) 11 or earlier:
SPARC: -xarch=v9
x86 (Intel): -xarch=generic64
Fujitsu C Compiler (fcc): -KV9
21. BioRuby
64-bit compile: 64-bit Library
Solaris is 64-bit OS, but most binaries are 32-bit
All 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ビットのライブラリはインスールされ忘れている事が多い。
22. 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)
23. BioRuby
Extra Libraries
Library 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 CPPFLAGS
e.g. CPPFLAGS="-I/usr/local/64/include"
24. BioRuby
LD_LIBRARY_PATH considered harmful
LD_LIBRARY_PATH and derivatives for runtime
shared library path.
LD_LIBRARY_PATH for both 32- and 64-bit
LD_LIBRARY_PATH_32 for 32-bit
LD_LIBRARY_PATH_64 for 64-bit
They should only be used for temporary use.
Don't set LD_LIBRARY_PATH globally
Don't set in .cshrc, .login, .profile, etc.
25. BioRuby
64-bit build name
Even 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.10
Intel Solaris 10: --build=x86_64-pc-solaris2.10
% ./configure --help
(snip)
System types:
--build=BUILD configure for building on BUILD [guessed]
29. BioRuby
Typical Bugs on Solaris, SPARC
Typo inside #if .. #endif conditions
Conflict of names
File name, function, macro, …
Endian
Word alignment
30. 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))
31. BioRuby
Simple Fix: Conflict of names
(r37604) [ruby-dev:46414] [Bug #7287]
Solaris has "atomic.h" in /usr/include
There 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
34. 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;
}
35. BioRuby
Word Alignment
On 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 4D
Address: 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
37. BioRuby
Most Bugs are non-specific
Most bugs occurred on Solaris were NOT specific
to the platform but would affect all platforms.
Difference of platform can reveal hidden bugs
Different OS
Different memory management
Different CPU architecture
Endian
Alignment
Different compiler
38. BioRuby
Integer Overflow
(r32757) [ruby-dev:43284] [Bug #4456]
s+(n) overflows when n is very large
s: pointer; n: value coming from user's Ruby code
On 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
39. 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;
}
40. BioRuby
transcode.c: fix race condition
(r51037) [ruby-dev:49106] [Bug #11277]
https://bugs.ruby-lang.org/issues/11277
Summary:
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>'
41. 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'.
42. BioRuby
Conclusions
It 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.
異なる環境で実行したら、隠れたバグが見つかることがある
のが、多様な環境をサポートするのが良い理由の一つ。