Ruby ã® CI ç¶ææ¥ã¨ããã®ã¯ãããªæãã¨ããäºä¾ç´¹ä»ã
CIã観å¯ãã
Rubyã®CIãã¨ãã©ã次ã®ããã«å¤±æãã¦ãã¾ããã
1) Error: TestM17N#test_object_inspect_external: Encoding::CompatibilityError: incompatible character encodings: UTF-8 and UTF-16BE /tmp/ruby/v2/src/trunk-test-random/test/ruby/test_m17n.rb:311:in `encode' /tmp/ruby/v2/src/trunk-test-random/test/ruby/test_m17n.rb:311:in `inspect' /tmp/ruby/v2/src/trunk-test-random/test/ruby/test_m17n.rb:313:in `inspect' /tmp/ruby/v2/src/trunk-test-random/test/ruby/test_m17n.rb:313:in `test_object_inspect_external'
http://ci.rvm.jp/logfiles/brlog.trunk-test-random.20200322-221411
ãªããä¾å¤ãçºçãã¦ãã¾ããå¿ ãåç¾ããããã§ã¯ãªããæå ã§åç¾ãã§ããªãã®ã§ãããæ¥ã«æ°åç¨åº¦å¤±æãç¶ãã¦ãã¦é¬±é¶ãããã¹ãã§ããããã®ãã°ã ãè¦ã¦åé¡ç®æãç¹å®ã§ãããã¨ã¹ãã¼ã§ãã
åé¡ãåãåãã
ã¾ããããã ã¢ããã¨ããããã¦ã³ã®ä¸¡é¢ãã観å¯ã試ã¿ã¾ãã
ããã ã¢ãã観å¯ãã¤ã¾ãä¾å¤çºçç®æãã観å¯ãã¾ããã¨ã©ã¼ã¡ãã»ã¼ã¸ã® "incompatible character encodings" ã§æ¤ç´¢ããã¨ã5ç®æã»ã©rb_raiseãã¦ããç®æãããã¾ãããããããã©ãã§çºåãã¦ããã®ããããããã¾ããã§ããã
ããããã¦ã³è¦³å¯ã¯ã失æãã¦ãããã¹ããè¦ããã¨ã§ãã
def test_object_inspect_external ... Encoding.default_external = Encoding::UTF_16BE ... def o.inspect "abc".encode(Encoding.default_external) end assert_equal '[abc]', [o].inspect ... end
åé¡ãåãåããããã«ãinspect ãç¡é¢ä¿ã§ãããã¨ã確ããããã®ã§ããããã®ãã¹ãã ãåãåºãã¦ãåé¡ãåç¾ããªãã®ã§ã確ããããã¨ãã§ãã¾ãããããã§ã"abc".encode(Encoding.default_external)
ã ãã§ä¾å¤ãåºããã©ããããããã®ã¨ã³ã³ã¼ãã£ã³ã°ãå¦ãªãã¨ã«ãªã£ã¦ããªãããªã©ããããã°åºåãããã³ã¼ãããã¹ãã«çªã£è¾¼ãã§ããã°ããCIã観å¯ãããã¨ã«ãã¾ããã
ãããã°æ å ±ãéãã
ç¿æCIãè¦ãã¨ããã§ãã失æãèµ·ãã¦ãã¾ããããããã°åºåãè¦ãã¨ã"abc".encode(Encoding.default_external)
åä½ã§ä¾å¤ãèµ·ãããã¨ã確èªã§ãã¾ãããã¾ãããããã®ã¨ã³ã³ã¼ãã£ã³ã°ãæå¾
éããæå¤æ§ã¯ãªãã£ãã
ã¨ãããã¨ã§åé¡ã¯ã»ã¼ç¹å®ã§ããã®ã§ãããããããã¡ãã£ã¨èãã¦ãã©ãããçµç·¯ã§ãã®ä¾å¤ãæãããããã¯ãããã¾ããã§ãããããã§ãä¾å¤çºçæã® C ã®ã¹ã¿ãã¯ãã¬ã¼ã¹ãæ¡åãããã¨ã試ã¿ã¾ãã次ã®ãããªãããã°ã³ã¼ãããã¹ãã³ã¼ãã«ã³ããããã¾ããã
TracePoint.new(:raise) do |tp| Process.kill(:SEGV, $$) end.enable { "abc".encode(Encoding.default_external) }
TracePoint ã£ã¦ãããã風ã«ã¤ãããã®ãªãã§ãããã
åé¡ãåæãã
ã¾ãç¿æãCIã失æãã¦ãã¦ç¡äºCã®ã¹ã¿ãã¯ãã¬ã¼ã¹ãåãã¾ããã
String#encode ãå¼ã°ãã¦ãã raise ãèµ·ããã¾ã§ã®ãã¬ã¼ã¹ã
/tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(rb_raise+0x94) [0x7fc6c5e4cf74] /tmp/ruby/v2/src/trunk-test-random/error.c:2689 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(enc_compatible_p+0x0) [0x7fc6c5e32d80] /tmp/ruby/v2/src/trunk-test-random/encoding.c:915 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(rb_enc_check) (null):0 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(rb_file_expand_path_internal+0x109) [0x7fc6c5e61cf9] /tmp/ruby/v2/src/trunk-test-random/file.c:3640 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(rb_file_expand_path_internal+0x847) [0x7fc6c5e62437] /tmp/ruby/v2/src/trunk-test-random/file.c:3746 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(rb_find_file_ext+0x3fb) [0x7fc6c5e62f3b] /tmp/ruby/v2/src/trunk-test-random/file.c:6330 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(require_internal+0x2dc) [0x7fc6c5eb044c] /tmp/ruby/v2/src/trunk-test-random/load.c:909 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(rb_require_string+0x23) [0x7fc6c5eb2173] /tmp/ruby/v2/src/trunk-test-random/load.c:1111 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(load_transcoder_entry+0xa8) [0x7fc6c5fe7908] /tmp/ruby/v2/src/trunk-test-random/transcode.c:386 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(load_transcoder_entry+0x14) [0x7fc6c5feb5d0] /tmp/ruby/v2/src/trunk-test-random/transcode.c:372 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(rb_econv_open) /tmp/ruby/v2/src/trunk-test-random/transcode.c:943 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(str_transcode0+0x268) [0x7fc6c5feed28] /tmp/ruby/v2/src/trunk-test-random/transcode.c:2275 /tmp/ruby/v2/build/trunk-test-random/libruby.so.2.8.0(str_encode+0x64) [0x7fc6c5fef3f4] /tmp/ruby/v2/src/trunk-test-random/transcode.c:2763
åé¡ãåæããã®ã«ååãªæ å ±ãåãã¾ãããããããã¨ã«ãåCé¢æ°ã®å®è£ ã解èªãã¦ããã¾ãã1æéãããããã°ããçµæã¨ãã¦ã
Encoding.default_external = Encoding::UTF_16BE
ã¨ãããã¨ã§ããã¡ã¤ã«ã·ã¹ãã ã®ã¨ã³ã³ã¼ãã£ã³ã°ã UTF-16BE ã¨ã¿ãªãããããã«ãªã- ãã®ã㨠String#encode ã«ãã£ã¦ Encoding::UTF_16BE ã®å®ä½ããã¼ãããããã¨ãã
- ãã®ãã¼ãã®éãLOAD_PATHã®æååï¼UTF-8ï¼ãç¸å¯¾ãã¹ã®ã¨ããã«ã¬ã³ããã£ã¬ã¯ããªï¼UTF-16BEï¼ã¨çµåãããã¨ãã¦ä»¶ã®ä¾å¤ãæãããã
ã¨ããç¾è±¡ã§ããã¨ä»®èª¬ãç«ã¦ããã¾ããã
ãã®ç¾è±¡èªä½ããã°ãã©ããã¯å¤æãé£ããããã¡ã¤ã«ã·ã¹ãã ã UTF-16BE ãªãã° LOAD_PATH ã« UTF-8 æååãå ¥ããã®ãããããããã§ããã®ä¾å¤èªä½ã¯æ£å½ãããããªããã§ãç¾å®åé¡ã¨ãã¦ããã¾ã® Ruby ã¯ãã¡ã¤ã«ã·ã¹ãã ã ASCII-compatible ã§ãªãã¨ã³ã³ã¼ãã£ã³ã°ã®å ´åããµãã¼ããã¦ãªãæ°ãããã®ã§ãã¡ãã£ã¨å¾®å¦ã
仮説ãæ¤è¨¼ãã
ãã®ä»®èª¬ããã¨ã«ãåç¾ã³ã¼ããä½ãã¾ãããããã°åºåãã¯ãã¿ã¤ã¤30åã»ã©ããã°ãã¨ã次ã®ã³ã¼ãã§ä»¶ã®ä¾å¤ã観測ã§ãã¾ããã
$LOAD_PATH << "no_existing_dir" Encoding.default_external = Encoding::UTF_16BE load "dummy.rb" #=> incompatible character encodings: UTF-8 and UTF-16BE
åå¨ãããã£ã¬ã¯ããªã¸ã®ç¸å¯¾ãã¹ã $LOAD_PATH ã«è¿½å ããã¨å é¨çã«çµ¶å¯¾ãã¹ã«å¤æãããã®ã§ãåé¡ã¯çºç¾ãã¾ãããåå¨ããªããã£ã¬ã¯ããªãå ããã¨ãããåç¾ã®ãã¤ã³ãã§ããã
ã¨ãããã¨ã§ããã®åé¡ã¯ããä½ãã®ãã¹ããåå¨ããªããã£ã¬ã¯ããªã $LOAD_PATH ã«è¿½å ãã¦ãããããã®å¾ã件ã®ãã¹ããå®è¡ããã¨ä¾å¤ãæãããããã¨ããç¾è±¡ã§ããå¯è½æ§ãé«ã¾ãã¾ããã
åé¡ã®ãã¹ããæ¢ã
ãã¹ãã®ä¸ã§ $LOAD_PATH ãããã£ã¦ããã³ã¼ããå ¨é¨è¦ã¦ããã¾ãããããããã£ãã®ã§é¢åã§ããããã»ã¨ãã©ã®ç®æã¯çµ¶å¯¾ãã¹ãå ¥ãã¦ããã®ã§ãä¸å¯§ã«è¦ã¦ããã°è¦ã¤ãããã¾ããã
case ENV['JSON'] when 'pure' $:.unshift 'lib' require 'json/pure' when 'ext' $:.unshift 'ext', 'lib' require 'json/ext' else $:.unshift 'ext', 'lib' require 'json' end
https://github.com/ruby/ruby/blob/13e9551b97d6bb9fcd09283692f6090f4c418059/test/json/test_helper.rb
ã¾ãã JSON ã®ãã¹ããåå ã¨ã¯ãæåã®åé¡ããã¯æ³åã§ããªãã§ããã
ã¡ãªã¿ã«ããã㯠JSON ã gem ã¨ãã¦éçºããã¨ãã®ããã¯ã®ããã§ãï¼JSONã¯pure Rubyå®è£ ã¨Cå®è£ ã®2ã¤ãæã£ã¦ãã¦ãç°å¢å¤æ°ã«ãã£ã¦ãã¹ã対象ãå¶å¾¡ã§ããããã«ãã¦ããï¼ãããã Ruby ã«ãã³ãã«ãããç¶æ³ä¸ã§ã¯å¸¸ã«Cå®è£ ã使ãã®ã§ããã®ããã¯ã¯ç¡æå³ã§ãã
æå ã§åç¾ããã
ãããåå ã§ãããã¨ã確èªããããã«ã¯ãjson ã¨ä»¶ã®ãã¹ãã ããå®è¡ããã°ããã§ãã
$ make test-all TESTS="json ruby/m17n -n test_object_inspect_external" Run options: --seed=94886 "--ruby=./miniruby -I../ruby.src/lib -I. -I.ext/common ../ruby.src/tool/runruby.rb --extout=.ext -- --disable-gems" --excludes-dir=../ruby.src/test/excludes --name=!/memory_leak/ -n test_object_inspect_external # Running tests: [1/1] TestM17N#test_object_inspect_external/home/mame/work/ruby.src/test/ruby/test_m17n.rb:319: [BUG] Segmentation fault at 0x000003e80000751d ...
ç¡äºåé¡ãåç¾ãã¾ãããã¨ãããã¨ã§ããããåå ã¨ãããã¨ã§ééããªãããã§ãï¼ã²ãã£ã¨ãããä»ã«ããããããããªããã©ï¼ã
ããã£ã¨åç¾ããã¨æ¸ãã¦ãã¾ããã2ã¤ãã¤ã³ããããã¾ãã
- in-place build ã§ã¯åç¾ãã¾ããï¼ã«ã¬ã³ããã£ã¬ã¯ããªã«ãã¾ãã¾ ext ã lib ãåå¨ããã®ã§çºåæ¡ä»¶ãæºãããªãï¼ãout-of-place ã®ã¨ã㯠lib ãåå¨ããªãã®ã§çºåãã¾ããï¼åé¡ã®CIã管çãã¦ããããã ããã out-of-place build æ´¾ã ã¨ããç¥èãããã¨æå©ãï¼
-n test_object_inspect_external
ã«ãã£ã¦ã件ã®ãã¹ãã ããå®è¡ãããã¨ãå¿ è¦ã§ãããªããªããä»ã® M17N ã®ãã¹ããå ã«å®è¡ãã㨠UTF_16BE ã®ãªã¼ããã¼ããå ã«è¡ããã¦ãã¾ããåé¡ã®ãã¹ãã§ãã¡ã¤ã«ãã¼ããè¡ãããªããªã£ã¦åç¾ããªããªãã
ä¿®æ£ãã
ããã§ç¸å¯¾ãã¹ãå ¥ããªããã°å¤§ä¸å¤«ãªã®ã§ãéã«çµ¶å¯¾ãã¹ã«ãã¦ããã¾ãããããã§æå ã§ã¯åé¡ãåç¾ãããªããªãã¾ãããã³ãããã㦠CI 観å¯ç¶ç¶ä¸ã
ã¾ã¨ã
Ruby ã® CI ãã¨ãã©ã失æããç¾è±¡ã®èª¿æ»ã¨ä¿®æ£ã®äºä¾ç´¹ä»ã§ãããJSON ã®ãã¹ãã M17N ã®ãã¹ãã失æãããã¨ããªããªãé£ããã§ãããä»åã¯ãã¹ãã®ä¿®æ£ã ãã§æ¸ã¿ã¾ããããæ¬ä½å´ã®ä¿®æ£ãå¿ è¦ã«ãªãå ´åããã¡ããããã¾ããã¾ããããã¯Rubyã®ç¥èã§å®çµãã¦ããåé¡ã§ããããã·ã¹ãã ããã°ã©ãã³ã°ã®ç¥èãè¦æ±ããããããªãã¨ãå¤ãã§ããRubyã®å質ãããã¤ã®ã¯ç·åæ ¼éæã