Error in TestEnv#test_memory_leak_* on Solaris

Issue #10010 has been updated by Nobuyoshi N…

Naohisa G. wrote:

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

定数の初期化はロードされてモジュール定義のときですから、まだテストでPATHが変更される前です。

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

使えるpsを探すようにしてみました。

diff --git a/test/ruby/memory_status.rb b/test/ruby/memory_status.rb
index f8e097a..9bdaa73 100644
--- a/test/ruby/memory_status.rb
+++ b/test/ruby/memory_status.rb
@@ -82,8 +82,18 @@ module Memory
       end
     end
   else
-    PSCMD = ["ps", "-ovsz=","-orss=", "-p"]
     PAT = /^\s*(\d+)\s+(\d+)$/
+    PSCMD = nil;
+    ENV["PATH"].split(File::PATH_SEPARATOR).find {|path|
+      next if path.empty?
+      pscmd = [File.join(path, "ps"), "-ovsz=", "-orss=", "-p"]
+      begin
+        break pscmd if PAT =~ IO.popen(pscmd + [$$.to_s], "r", err: 
[:child, :out], &:read)
+      rescue
+        next
+      end
+    }
+    raise MiniTest::Skip, "ps command not found" unless PSCMD

     keys << :size << :rss
     def self.read_status

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'