Error in TestEnv#test_memory_leak_* on Solaris

Issue #10010 has been updated by Naohisa G…

TestEnv#test_memory_leak_* では、子プロセス内のコードで ENV.clear を呼んでいて、
上記コードもその子プロセス内で呼ばれることになるため、つまり、
上記コードを通る際には ENV[PATH]は nil になった状態です。
このため、ENV[“PATH”].split の部分でエラーになると思います。

以下のようにPATHを保存して最後に復旧するようにしたら、Errorは出なくなりました。(Failureにはなりますが、OSのメモリ管理の方針によると思われます。)

Index: test/ruby/test_env.rb
===================================================================
--- test/ruby/test_env.rb  (revision 46727)
+++ test/ruby/test_env.rb  (working copy)
@@ -512,22 +512,26 @@
   def test_memory_leak_aset
     bug9977 = '[ruby-dev:48323] [Bug #9977]'
     assert_no_memory_leak([], <<-'end;', "5_000.times(&doit)", bug9977, 
limit: 2.0)
+      path = ENV['PATH']
       ENV.clear
       k = 'FOO'
       v = (ENV[k] = 'bar'*5000 rescue 'bar'*1500)
       doit = proc {ENV[k] = v}
       500.times(&doit)
+      ENV['PATH'] = path
     end;
   end

   def test_memory_leak_select
     bug9978 = '[ruby-dev:48325] [Bug #9978]'
     assert_no_memory_leak([], <<-'end;', "5_000.times(&doit)", bug9978, 
limit: 2.0)
+      path = ENV['PATH']
       ENV.clear
       k = 'FOO'
       (ENV[k] = 'bar'*5000 rescue 'bar'*1500)
       doit = proc {ENV.select {break}}
       500.times(&doit)
+      ENV['PATH'] = path
     end;
   end

@@ -541,11 +545,13 @@
   def test_memory_leak_shift
     bug9983 = '[ruby-dev:48332] [Bug #9983]'
     assert_no_memory_leak([], <<-'end;', "5_000.times(&doit)", bug9983, 
limit: 2.0)
+      path = ENV['PATH']
       ENV.clear
       k = 'FOO'
       v = (ENV[k] = 'bar'*5000 rescue 'bar'*1500)
       doit = proc {ENV[k] = v; ENV.shift}
       500.times(&doit)
+      ENV['PATH'] = path
     end;
   end
 end

これでも、Solarisで /usr/ucb を /usr/bin や /bin より先に PATH に入れていた場合は救えません。


Bug #10010: Error in TestEnv#test_memory_leak_* on Solaris

  • Author: Naohisa G.
  • Status: Feedback
  • Priority: Normal
  • Assignee: Nobuyoshi N.
  • Category:
  • Target version: current: 2.2.0
  • ruby -v: ruby 2.2.0dev (2014-07-04) [sparc64-solaris2.10]
  • Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN

r46550 くらい以降、Solaris 10 にて make test-all 中、以下のエラーが発生します。
(r44686 にて確認)

test/envutil.rb の 438行目にて、:size や :rss
用の情報が、OS側の何らかの理由で示されず、その結果ハッシュにも格納されず、 a または b が nil
になることがあるのに、それに対応していないのが原因と思います。

なお、Solaris では、/proc/self/status は struct pstatus_t
の内容のバイナリを返しますが、それには全く対応していないので、nil
になるか、偶然バイナリ値が何かに一致した場合にでたらめな値が返されるかのいずれかになります。

 53) Error:
TestEnv#test_memory_leak_shift:
NoMethodError: undefined method `>' for nil:NilClass
    /XXXXX/test/ruby/envutil.rb:438:in `block in assert_no_memory_leak'
    /XXXXX/test/ruby/envutil.rb:435:in `each'
    /XXXXX/test/ruby/envutil.rb:435:in `assert_no_memory_leak'
    /XXXXX/test/ruby/test_env.rb:543:in `test_memory_leak_shift'

 54) Error:
TestEnv#test_memory_leak_select:
NoMethodError: undefined method `>' for nil:NilClass
    /XXXXX/test/ruby/envutil.rb:438:in `block in assert_no_memory_leak'
    /XXXXX/test/ruby/envutil.rb:435:in `each'
    /XXXXX/test/ruby/envutil.rb:435:in `assert_no_memory_leak'
    /XXXXX/test/ruby/test_env.rb:525:in `test_memory_leak_select'

 55) Error:
TestEnv#test_memory_leak_aset:
NoMethodError: undefined method `>' for nil:NilClass
    /XXXXX/test/ruby/envutil.rb:438:in `block in assert_no_memory_leak'
    /XXXXX/test/ruby/envutil.rb:435:in `each'
    /XXXXX/test/ruby/envutil.rb:435:in `assert_no_memory_leak'
    /XXXXX/test/ruby/test_env.rb:514:in `test_memory_leak_aset'