Bug #10020
closedTestEnv#test_memory_leak_*, Fiddle::TestPointer#test_no_memory_leak, and Test_StringModifyExpand#test_modify_expand_memory_leak on Solaris
Description
Solaris 10 にて、以下のように memory leak 検出テストの Failure が出ます。(r46762 で確認)
Solarisデフォルトのlibcのmallocでは、freeしてもOSにメモリを返さないのが原因と考えています。
メモリ関係デバッグ用のライブラリ libumem を使い、UMEM_OPTIONS=backend=mmap を指定すると、freeしたら直ちにOSにメモリを返すようになるようです。
dynamic link な実行プログラムなら、LD_PRELOAD=libumem.so UMEM_OPTIONS=backend=mmap をセットしてコマンドを実行ということになります。
test/ruby/envutil.rb の assert_no_memory_leak 内で invoke_ruby する際にこれらの環境変数をセットできればいいのですが、以下4点が課題と思います。
- 特定のOSに特異的な変更をどう入れるか?
- これらの環境変数が元からセットされていた時の挙動
- static link のrubyの場合
- tcmalloc など、別の malloc をリンク指定されていた場合にどうなる?
References:
- http://stackoverflow.com/questions/346352/meaning-of-size-and-rss-values-in-prstat-output
- http://docs.oracle.com/cd/E23824_01/html/821-1465/umem-free-3malloc.html
51) Failure:
TestEnv#test_memory_leak_shift [/XXXXX/test/ruby/test_env.rb:543]:
[ruby-dev:48332] [Bug #9983].
size: 38502400 => 155942912.
Expected 4.050212765957447 to be < 2.0.
52) Failure:
TestEnv#test_memory_leak_aset [/XXXXX/test/ruby/test_env.rb:514]:
[ruby-dev:48323] [Bug #9977].
size: 21725184 => 97222656.
Expected 4.475113122171946 to be < 2.0.
53) Failure:
Fiddle::TestPointer#test_no_memory_leak [/XXXXX/test/fiddle/test_pointer.rb:235]:
rss: 8568832 => 12984320.
Expected 1.5152963671128108 to be < 1.5.
55) Failure:
Test_StringModifyExpand#test_modify_expand_memory_leak [/XXXXX/test/-ext-/string/test_modify_expand.rb:7]:
rb_str_modify_expand().
size: 13303808 => 30179328.
Expected 2.268472906403941 to be < 1.5.
Updated by ngoto (Naohisa Goto) over 10 years ago
- Related to Bug #10010: Error in TestEnv#test_memory_leak_* on Solaris added
Updated by ngoto (Naohisa Goto) over 10 years ago
TestEnv#test_memory_leak_* に関しては、
Illumos(旧OpenSolaris)のソース usr/src/lib/libc/port/gen/getenv.c を見る限り、
setenv() 内で malloc にて確保した領域を unsetenv() で free する事は無いように見えます。
つまり、少なくとも Solaris 10 / Illumos では、setenv(3C) と unsetenv(3C) を繰り返すと(malloc関数の種類に関わらず)メモリ使用量は増える一方のような感じです。
https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/gen/getenv.c
Updated by ngoto (Naohisa Goto) over 10 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
Applied in changeset r46791.
- test/ruby/envutil.rb (assert_no_memory_leak): On Solaris 9 or later,
if possible, execute child ruby with environment variables
LD_PRELOAD=libumem.so UMEM_OPTIONS="backend=mmap". With these
variables, freed memory is immediately returned to the OS.
[Bug #10020] [ruby-dev:48391]
Updated by ngoto (Naohisa Goto) over 10 years ago
r46791 にて、Solaris 9 以降で、以下を満たす場合に、それらの環境変数をセットして invoke_ruby するように変更しました。
- 環境変数 LD_PRELOAD, LD_PRELOAD_64 (または LD_PRELOAD_32), UMEM_OPTIONS がセットされていない
- LD_PRELOAD=libumem.so UMEM_OPTIONS=backend=mmap を付けてrubyを実行して正常終了
- テストケース独自に、それらとコンフリクトする環境変数を与えていない
上記したように、Solaris10のsetenv/unsetenv関係の実装により、 TestEnv#test_memory_leak_shift と TestEnv#test_memory_leak_shift はFailureのままですが、いったんこのissueは閉じます。
Updated by naruse (Yui NARUSE) over 10 years ago
Naohisa Goto wrote:
r46791 にて、Solaris 9 以降で、以下を満たす場合に、それらの環境変数をセットして invoke_ruby するように変更しました。
- 環境変数 LD_PRELOAD, LD_PRELOAD_64 (または LD_PRELOAD_32), UMEM_OPTIONS がセットされていない
- LD_PRELOAD=libumem.so UMEM_OPTIONS=backend=mmap を付けてrubyを実行して正常終了
- テストケース独自に、それらとコンフリクトする環境変数を与えていない
上記したように、Solaris10のsetenv/unsetenv関係の実装により、 TestEnv#test_memory_leak_shift と TestEnv#test_memory_leak_shift はFailureのままですが、いったんこのissueは閉じます。
これ、failureのままよりskipしてしまったほうがいいのではないでしょうか。