Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112024-02-21T02:44:55ZRuby Issue Tracking System
Redmine Ruby master - Bug #20285 (Assigned): Stale inline method caches when refinement modules are reopenedhttps://bugs.ruby-lang.org/issues/202852024-02-21T02:44:55Zjhawthorn (John Hawthorn)
<p>This is essentially the same issue as <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: refinement (Closed)" href="https://bugs.ruby-lang.org/issues/11672">#11672</a>, but for inline method caches rather than class caches.</p>
<p>In Ruby 3.3 we started using inline caches for refinements. However, we weren't clearing inline caches when defined on a reopened refinement module.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">C</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">R</span>
<span class="n">refine</span> <span class="no">C</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">m</span>
<span class="ss">:foo</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">using</span> <span class="no">R</span>
<span class="k">def</span> <span class="nf">m</span>
<span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">m</span>
<span class="k">end</span>
<span class="k">raise</span> <span class="k">unless</span> <span class="ss">:foo</span> <span class="o">==</span> <span class="n">m</span><span class="p">()</span>
<span class="k">module</span> <span class="nn">R</span>
<span class="n">refine</span> <span class="no">C</span> <span class="k">do</span>
<span class="k">alias</span> <span class="n">m</span> <span class="n">m</span>
<span class="k">def</span> <span class="nf">m</span>
<span class="ss">:bar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">m</span><span class="p">()</span>
<span class="k">raise</span> <span class="s2">"expected :bar, got </span><span class="si">#{</span><span class="n">v</span><span class="p">.</span><span class="nf">inspect</span><span class="si">}</span><span class="s2">"</span> <span class="k">unless</span> <span class="ss">:bar</span> <span class="o">==</span> <span class="n">v</span>
</code></pre>
<p>This will raise in Ruby 3.3 as the inline cache finds a stale refinement, but passes in previous versions.</p> Ruby master - Bug #20237 (Assigned): Unable to unshare(CLONE_NEWUSER) in Linux because of timer t...https://bugs.ruby-lang.org/issues/202372024-02-05T04:59:20Zhanazuki (Kasumi Hanazuki)
<a name="Backgrounds"></a>
<h2 >Backgrounds<a href="#Backgrounds" class="wiki-anchor">¶</a></h2>
<p><a href="https://man7.org/linux/man-pages/man2/unshare.2.html" class="external">unshare(2)</a> is a syscall in Linux to move the calling process into a fresh execution context. With <code>unshare(CLONE_NEWUSER)</code> you can move a process into a new <a href="https://man7.org/linux/man-pages/man7/user_namespaces.7.html" class="external">user_namespace(7)</a>, where the process gains the full capability on the resources within the namespace. This is fundamental for Linux containers to achieve privilege separation. <code>unshare(CLONE_NEWUSER)</code> requires the calling process to be single-threaded (or no background threads are running). So, it is often invoked after <code>fork(2)</code> as forking propagates only the calling thread to the child process.</p>
<a name="Problem"></a>
<h2 >Problem<a href="#Problem" class="wiki-anchor">¶</a></h2>
<p>It becomes a problem that Ruby 3.3 on Linux uses timer threads even for a single-<code>Thread</code>ed application. Because <code>Kernel#fork</code> spawns a thread in the child process before the control returns to the user code, there is no chance to call <code>unshare(CLONE_NEWUSER)</code> in Ruby.</p>
<p>The following snippet is a reproducer of this problem. This program first forks and then shows the user namespace to which the process belongs before and after calling unshare(2). It also shows the threads of the child process after forking.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">p</span><span class="p">(</span><span class="no">RUBY_DESCRIPTION</span><span class="p">:)</span>
<span class="nb">require</span> <span class="s1">'fiddle/import'</span>
<span class="k">module</span> <span class="nn">C</span>
<span class="kp">extend</span> <span class="no">Fiddle</span><span class="o">::</span><span class="no">Importer</span>
<span class="n">dlload</span> <span class="s1">'libc.so.6'</span>
<span class="n">extern</span> <span class="s1">'int unshare(int flags)'</span>
<span class="no">CLONE_NEWUSER</span> <span class="o">=</span> <span class="mh">0x10000000</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">raise_system_call_error</span>
<span class="k">raise</span> <span class="no">SystemCallError</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">Fiddle</span><span class="p">.</span><span class="nf">last_error</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">pid</span> <span class="o">=</span> <span class="nb">fork</span> <span class="k">do</span>
<span class="nb">system</span><span class="p">(</span><span class="s2">"ps -O tid -T -p #$$"</span><span class="p">)</span>
<span class="nb">system</span><span class="p">(</span><span class="s2">"ls -l /proc/self/ns/user"</span><span class="p">)</span>
<span class="k">if</span> <span class="no">C</span><span class="p">.</span><span class="nf">unshare</span><span class="p">(</span><span class="no">C</span><span class="o">::</span><span class="no">CLONE_NEWUSER</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span>
<span class="no">C</span><span class="p">.</span><span class="nf">raise_system_call_error</span> <span class="c1"># => EINVAL with Ruby 3.3</span>
<span class="k">end</span>
<span class="nb">system</span><span class="p">(</span><span class="s2">"ls -l /proc/self/ns/user"</span><span class="p">)</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="no">Process</span><span class="p">.</span><span class="nf">wait2</span><span class="p">(</span><span class="n">pid</span><span class="p">)</span>
</code></pre>
<p>The program successfully changes the user namespace with Ruby 3.2, but it raises EINVAL with Ruby 3.3. You can see Ruby 3.3 has two threads running after forking.</p>
<pre><code>% rbenv shell 3.2 && ruby ./test.rb
{:RUBY_DESCRIPTION=>"ruby 3.2.3 (2024-01-18 revision 52bb2ac0a6) [x86_64-linux]"}
PID TID S TTY TIME COMMAND
1585787 1585787 S pts/12 00:00:00 ruby ./test.rb
lrwxrwxrwx 1 kasumi kasumi 0 Feb 5 02:25 /proc/self/ns/user -> 'user:[4026531837]'
lrwxrwxrwx 1 nobody nogroup 0 Feb 5 02:25 /proc/self/ns/user -> 'user:[4026532675]'
[1585787, #<Process::Status: pid 1585787 exit 0>]
% rbenv shell 3.3 && ruby ./test.rb
{:RUBY_DESCRIPTION=>"ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux]"}
PID TID S TTY TIME COMMAND
1585849 1585849 S pts/12 00:00:00 ruby ./test.rb
1585849 1585851 S pts/12 00:00:00 ruby ./test.rb
lrwxrwxrwx 1 kasumi kasumi 0 Feb 5 02:25 /proc/self/ns/user -> 'user:[4026531837]'
./test.rb:10:in `raise_system_call_error': Invalid argument (Errno::EINVAL)
from ./test.rb:24:in `block in <main>'
from ./test.rb:19:in `fork'
from ./test.rb:19:in `<main>'
[1585849, #<Process::Status: pid 1585849 exit 1>]
% rbenv shell master && ruby ./test.rb
{:RUBY_DESCRIPTION=>"ruby 3.4.0dev (2024-02-04T16:05:02Z master 8bc6fff322) [x86_64-linux]"}
PID TID S TTY TIME COMMAND
1585965 1585965 S pts/12 00:00:00 ruby ./test.rb
1585965 1585967 S pts/12 00:00:00 ruby ./test.rb
lrwxrwxrwx 1 kasumi kasumi 0 Feb 5 02:25 /proc/self/ns/user -> 'user:[4026531837]'
./test.rb:10:in `raise_system_call_error': Invalid argument (Errno::EINVAL)
from ./test.rb:24:in `block in <main>'
from ./test.rb:19:in `fork'
from ./test.rb:19:in `<main>'
[1585965, #<Process::Status: pid 1585965 exit 1>]
</code></pre>
<a name="Workaround"></a>
<h2 >Workaround<a href="#Workaround" class="wiki-anchor">¶</a></h2>
<p>My workaround is to rebuild ruby with <code>rb_thread_stop_timer_thread</code> and <code>rb_thread_start_timer_thread</code> exported, and use a C-ext that stops the timer thread before calling <code>unshare</code>. This seems not robust because the process cannot know when the terminated thread is reclaimed by the kernel, after which the process is considered single-threaded.</p>
<pre><code class="c syntaxhl" data-language="c"><span class="cp">#define _GNU_SOURCE 1
#include</span> <span class="cpf"><sched.h></span><span class="cp">
#include</span> <span class="cpf"><ruby/ruby.h></span><span class="cp">
</span>
<span class="k">static</span> <span class="n">VALUE</span> <span class="nf">Unshare_s_unshare</span><span class="p">(</span><span class="n">VALUE</span> <span class="n">_self</span><span class="p">,</span> <span class="n">VALUE</span> <span class="n">rflags</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">int</span> <span class="k">const</span> <span class="n">flags</span> <span class="o">=</span> <span class="n">NUM2INT</span><span class="p">(</span><span class="n">rflags</span><span class="p">);</span>
<span class="n">rb_thread_stop_timer_thread</span><span class="p">();</span>
<span class="n">usleep</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span> <span class="c1">// FIXME: It takes some time for the kernel to remove the stopped thread?</span>
<span class="kt">int</span> <span class="k">const</span> <span class="n">ret</span> <span class="o">=</span> <span class="n">unshare</span><span class="p">(</span><span class="n">flags</span><span class="p">);</span>
<span class="n">rb_thread_start_timer_thread</span><span class="p">();</span>
<span class="k">if</span><span class="p">(</span><span class="n">ret</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="n">rb_sys_fail_str</span><span class="p">(</span><span class="n">rb_sprintf</span><span class="p">(</span><span class="s">"unshare(%#x)"</span><span class="p">,</span> <span class="n">flags</span><span class="p">));</span>
<span class="k">return</span> <span class="n">Qnil</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">RUBY_FUNC_EXPORTED</span> <span class="kt">void</span>
<span class="nf">Init_unshare</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
<span class="n">VALUE</span> <span class="n">rb_mUnshare</span> <span class="o">=</span> <span class="n">rb_define_module</span><span class="p">(</span><span class="s">"Unshare"</span><span class="p">);</span>
<span class="n">rb_define_singleton_method</span><span class="p">(</span><span class="n">rb_mUnshare</span><span class="p">,</span> <span class="s">"unshare"</span><span class="p">,</span> <span class="n">Unshare_s_unshare</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">rb_define_const</span><span class="p">(</span><span class="n">rb_mUnshare</span><span class="p">,</span> <span class="s">"CLONE_NEWUSER"</span><span class="p">,</span> <span class="n">INT2FIX</span><span class="p">(</span><span class="n">CLONE_NEWUSER</span><span class="p">));</span>
<span class="p">}</span>
</code></pre>
<a name="Questions"></a>
<h2 >Questions<a href="#Questions" class="wiki-anchor">¶</a></h2>
<ul>
<li>Is this a limitation of Ruby?</li>
<li>Is it safe (or even possible) to stop the timer thread during execution?
<ul>
<li>If so, can we export it as the public API?</li>
<li>But it may not so useful for this problem as explained in the workaround.</li>
</ul>
</li>
<li>Is it guaranteed that no other threads are running after forks?</li>
<li>Are there any better ways to solve this issue?
<ul>
<li>Can we somehow delay the start of the timer thread after forking, or hook into <code>fork</code> to run some code in the child process immediately after it spawns.</li>
<li>Can they be Ruby API instead of C API?</li>
</ul>
</li>
</ul> Ruby master - Bug #20158 (Assigned): Ractor affects Coverage resultshttps://bugs.ruby-lang.org/issues/201582024-01-07T15:12:34Zjanosch-x (Janosch Müller)
<p>I have a large rspec test suite. I found that if I call a Ractor, the Coverage results are strongly affected, i.e. almost all files appear to be uncovered. This happens even if I only ever call a Ractor before the library or rspec are required.</p>
<p>Unfortunately, I was not able to build a simple repro yet.</p>
<p>I assume it is a timing thing and only affects larger suites, or it only happens if there are multiple files, and maybe if the library lazily requires its sub-modules?</p>
<p>However, I guess this should produce the same results when added to the spec_helper.rb of other large suites:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># Ractor.new { nil } # uncomment this to affect coverage results</span>
<span class="nb">require</span> <span class="s1">'coverage'</span>
<span class="no">Coverage</span><span class="p">.</span><span class="nf">start</span>
<span class="c1"># require library, set up rspec etc. </span>
<span class="no">RSpec</span><span class="p">.</span><span class="nf">configuration</span><span class="p">.</span><span class="nf">after</span><span class="p">(</span><span class="ss">:suite</span><span class="p">)</span> <span class="k">do</span>
<span class="c1"># this number is greatly reduced and unstable when calling Ractor above</span>
<span class="nb">p</span> <span class="no">Coverage</span><span class="p">.</span><span class="nf">result</span><span class="p">.</span><span class="nf">values</span><span class="p">.</span><span class="nf">sum</span> <span class="p">{</span> <span class="o">|</span><span class="n">arr</span><span class="o">|</span> <span class="n">arr</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="o">&</span><span class="ss">:to_i</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
</code></pre>
<p>I had this problem in <a href="https://github.com/jaynetics/character_set/" class="external">this library</a>. The problem affects simplecov users as well, as described <a href="https://github.com/simplecov-ruby/simplecov/issues/1058" class="external">here</a>.</p> Ruby master - Bug #20155 (Assigned): Using value of rb_fiber_scheduler_current() crashes Rubyhttps://bugs.ruby-lang.org/issues/201552024-01-05T22:14:24Zpaddor (Patrik Wenger)paddor@gmail.com
<p>While trying to manually block/unblock fibers from an extension using the Fiber Scheduler,<br>
I noticed that using the return value of <code>rb_fiber_scheduler_current()</code> crashes Ruby.</p>
<p>I've created a minimal extension gem called "fiber_blocker". Its test suite shows the behavior. See <a href="https://github.com/paddor/fiber_blocker" class="external">https://github.com/paddor/fiber_blocker</a>, especially the lines containing <code>FIXME</code>.</p>
<p>Passing <code>Fiber.scheduler</code> to the extension functions works. But letting it get the current scheduler itself does not seem to work.</p>
<p>Is <code>rb_fiber_scheduler_current()</code>(within a non-blocking Fiber) not the equivalent to <code>Fiber.scheduler</code>?<br>
Even just printing the its return value with <code>#p</code> will crash Ruby.</p>
<p>Ruby either crashes like this:</p>
<pre><code># Running:
T1 BEGIN
T2 BEGIN
T1 END
..T1 BEGIN
ext: blocking fiber
passed scheduler = #<Scheduler:0x00007fc5f22d39e8 @readable={}, @writable={}, @waiting={}, @closed=false, @lock=#<Thread::Mutex:0x00007fc5f22ec8d0>, @blocking={}, @ready=[], @urgent=[#<IO:fd 5>, #<IO:fd 6>]>
T2 BEGIN
ext: unblocking fiber
T1 END
.E
Finished in 1.007014s, 3.9721 runs/s, 2.9791 assertions/s.
1) Error:
TestFiberBlocker#test_fiber_blocker_current_fiber:
fatal: machine stack overflow in critical region
No backtrace
</code></pre>
<p>Or with a segfault:</p>
<pre><code># Running:
FiberBlocker.test works.
.T1 BEGIN
T2 BEGIN
T1 END
.T1 BEGIN
ext: blocking fiber
/home/user/dev/oss/async_ruby_test/rbnng/fiber_blocker/test/test_fiber_blocker.rb:40: [BUG] Segmentation fault at 0x00000000390d8f98
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux]
-- Control frame information -----------------------------------------------
c:0003 p:---- s:0012 e:000011 CFUNC :block_fiber
c:0002 p:0014 s:0006 e:000005 BLOCK /home/user/dev/oss/async_ruby_test/rbnng/fiber_blocker/test/test_fiber_blocker.rb:40 [FINISH]
c:0001 p:---- s:0003 e:000002 DUMMY [FINISH]
-- Ruby level backtrace information ----------------------------------------
/home/user/dev/oss/async_ruby_test/rbnng/fiber_blocker/test/test_fiber_blocker.rb:40:in `block in test_fiber_blocking_in_ext'
/home/user/dev/oss/async_ruby_test/rbnng/fiber_blocker/test/test_fiber_blocker.rb:40:in `block_fiber'
-- Threading information ---------------------------------------------------
Total ractor count: 1
Ruby thread count for this ractor: 4
-- Machine register context ------------------------------------------------
RIP: 0x00007f1554f17ad8 RBP: 0x00000000390d8f90 RSP: 0x00007f153a79e280
RAX: 0x00007f1554addba8 RBX: 0x00007f153a79eab0 RCX: 0x0000000000000000
RDX: 0x00007f1554ade600 RDI: 0x00007f15551e8788 RSI: 0x0000000000000ae1
R8: 0x000000000000002b R9: 0x00007f153a79f038 R10: 0x00007f1554c0b9b0
R11: 0x00007f153a79e490 R12: 0x0000000000000ae1 R13: 0x0000000000000000
R14: 0x0000000000000000 R15: 0x000055ab732d7df0 EFL: 0x0000000000010206
-- C level backtrace information -------------------------------------------
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_print_backtrace+0x14) [0x7f1554f24961] /home/user/src/ruby-3.3.0/vm_dump.c:820
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_vm_bugreport) /home/user/src/ruby-3.3.0/vm_dump.c:1151
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_bug_for_fatal_signal+0x104) [0x7f1554d1c214] /home/user/src/ruby-3.3.0/error.c:1065
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(sigsegv+0x4f) [0x7f1554e700df] /home/user/src/ruby-3.3.0/signal.c:926
/lib/x86_64-linux-gnu/libc.so.6(0x7f1554842520) [0x7f1554842520]
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(RBASIC_CLASS+0x0) [0x7f1554f17ad8] ./include/ruby/internal/globals.h:178
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(gccct_method_search) /home/user/src/ruby-3.3.0/vm_eval.c:475
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_funcallv_scope) /home/user/src/ruby-3.3.0/vm_eval.c:1063
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_funcallv) /home/user/src/ruby-3.3.0/vm_eval.c:1084
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_inspect+0x19) [0x7f1554dc1569] /home/user/src/ruby-3.3.0/object.c:697
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(ruby__sfvextra+0x11a) [0x7f1554e7223a] /home/user/src/ruby-3.3.0/sprintf.c:1119
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(BSD_vfprintf+0xa69) [0x7f1554e73059] /home/user/src/ruby-3.3.0/vsnprintf.c:830
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(RBASIC_SET_CLASS_RAW+0x0) [0x7f1554e75b56] /home/user/src/ruby-3.3.0/sprintf.c:1168
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(ruby_vsprintf0) /home/user/src/ruby-3.3.0/sprintf.c:1169
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_enc_vsprintf+0x5d) [0x7f1554e75ecd] /home/user/src/ruby-3.3.0/sprintf.c:1195
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_sprintf+0x9d) [0x7f1554e7607d] /home/user/src/ruby-3.3.0/sprintf.c:1225
/home/user/dev/oss/async_ruby_test/rbnng/fiber_blocker/lib/fiber_blocker/fiber_blocker.so(block_fiber+0x4a) [0x7f1554ad430a] ../../../../ext/fiber_blocker/fiber_blocker.c:29
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(vm_cfp_consistent_p+0x0) [0x7f1554ef64b4] /home/user/src/ruby-3.3.0/vm_insnhelper.c:3490
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(vm_call_cfunc_with_frame_) /home/user/src/ruby-3.3.0/vm_insnhelper.c:3492
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(vm_call_cfunc_with_frame) /home/user/src/ruby-3.3.0/vm_insnhelper.c:3518
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(vm_call_cfunc_other) /home/user/src/ruby-3.3.0/vm_insnhelper.c:3544
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(vm_sendish+0x9e) [0x7f1554f06f87] /home/user/src/ruby-3.3.0/vm_insnhelper.c:5581
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(vm_exec_core) /home/user/src/ruby-3.3.0/insns.def:834
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_vm_exec+0x19a) [0x7f1554f0d1fa] /home/user/src/ruby-3.3.0/vm.c:2486
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_vm_invoke_proc+0x5f) [0x7f1554f12e0f] /home/user/src/ruby-3.3.0/vm.c:1728
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_fiber_start+0x1ba) [0x7f1554cf098a] /home/user/src/ruby-3.3.0/cont.c:2536
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(fiber_entry+0x20) [0x7f1554cf0d00] /home/user/src/ruby-3.3.0/cont.c:847
/home/user/.rubies/ruby-3.3.0/lib/libruby.so.3.3(rb_threadptr_root_fiber_setup) (null):0
</code></pre>
<p>This happens with the Async scheduler as well as with Ruby’s test scheduler. My minimal extension uses Ruby’s.</p>
<p>I hope I'm not missing something obvious. My C isn't very good.</p> Ruby master - Bug #20146 (Assigned): Code using Ractor with env `RUBY_MAX_CPU=1` ends with unreac...https://bugs.ruby-lang.org/issues/201462024-01-04T02:17:54Zshia (Sangyong Sim)
<a name="Reproducible-code"></a>
<h2 >Reproducible code<a href="#Reproducible-code" class="wiki-anchor">¶</a></h2>
<pre><code class="rb syntaxhl" data-language="rb"><span class="c1"># sample-code.rb</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="mi">1</span> <span class="p">}</span>
</code></pre>
<pre><code class="bash syntaxhl" data-language="bash"><span class="nv">RUBY_MAX_CPU</span><span class="o">=</span>1 ruby sample-code.rb <span class="c"># This will not end with exit code 0</span>
<span class="nv">RUBY_MAX_CPU</span><span class="o">=</span>2 ruby sample-code.rb <span class="c"># This ends with exit code 0 as expected</span>
</code></pre>
<a name="Expected"></a>
<h2 >Expected<a href="#Expected" class="wiki-anchor">¶</a></h2>
<p>process with RUBY_MAX_CPU=1 exits successfully as same as RUBY_MAX_CPU more than 1.</p> Ruby master - Bug #20112 (Assigned): Ractors not working properly in ruby 3.3.0https://bugs.ruby-lang.org/issues/201122024-01-03T15:51:14Zariasdiniz (Aria Diniz)
<p>I recently installed Ruby 3.3.0, and noticed that some of my scripts that use Ractors started to struggle with performance. After doing some benchmarks, I noticed that, while Ractors seem to be working well on Ruby 3.2.2, they're not working properly on 3.3.0.</p>
<p>I'm using Ubuntu 22.04.3 LTS</p>
<p>Here is the benchmark code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># frozen_string_literal: true</span>
<span class="nb">require</span> <span class="s1">'benchmark'</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="ss">:warmup</span> <span class="p">}</span> <span class="k">if</span> <span class="k">defined?</span><span class="p">(</span><span class="no">Ractor</span><span class="p">)</span>
<span class="no">Benchmark</span><span class="p">.</span><span class="nf">bmbm</span> <span class="k">do</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span>
<span class="n">x</span><span class="p">.</span><span class="nf">report</span><span class="p">(</span><span class="s2">"Thread: "</span><span class="p">)</span> <span class="k">do</span>
<span class="n">threads</span> <span class="o">=</span> <span class="p">[]</span>
<span class="mi">8</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
<span class="n">threads</span> <span class="o"><<</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="mi">20000000</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span> <span class="o">|</span><span class="n">j</span><span class="o">|</span>
<span class="p">((</span><span class="n">i</span> <span class="o">*</span> <span class="mi">20000000</span><span class="p">)</span> <span class="o">+</span> <span class="n">j</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">threads</span><span class="p">.</span><span class="nf">each</span><span class="p">(</span><span class="o">&</span><span class="ss">:join</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">x</span><span class="p">.</span><span class="nf">report</span><span class="p">(</span><span class="s2">"Ractor: "</span><span class="p">)</span> <span class="k">do</span>
<span class="n">ractors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="mi">0</span><span class="o">..</span><span class="mi">8</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
<span class="n">ractors</span> <span class="o"><<</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">k</span><span class="o">|</span>
<span class="mi">20000000</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span> <span class="o">|</span><span class="n">j</span><span class="o">|</span>
<span class="p">((</span><span class="n">k</span> <span class="o">*</span> <span class="mi">20000000</span><span class="p">)</span> <span class="o">+</span> <span class="n">j</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">ractors</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:take</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Here is the results for Ruby 3.2.2:</p>
<p>Rehearsal --------------------------------------------<br>
Thread: 7.666909 0.001091 7.668000 ( 7.675266)<br>
Ractor: 19.318528 0.012017 19.330545 ( 2.505888)<br>
---------------------------------- total: 26.998545sec</p>
<pre><code> user system total real
</code></pre>
<p>Thread: 7.918141 0.004011 7.922152 ( 7.928772)<br>
Ractor: 19.366414 0.003954 19.370368 ( 2.517993)</p>
<p>Here is the results for Ruby 3.3.0:</p>
<p>Rehearsal --------------------------------------------<br>
Thread: 8.634152 0.010895 8.645047 ( 8.645104)<br>
Ractor: 100.172179 0.035985 100.208164 ( 15.213245)<br>
--------------------------------- total: 108.853211sec</p>
<pre><code> user system total real
</code></pre>
<p>Thread: 9.451236 0.004002 9.455238 ( 9.460132)<br>
Ractor: 118.463294 0.119942 118.583236 ( 18.462157)</p> Ruby master - Bug #20045 (Assigned): `TestDir#test_home` fails on i686https://bugs.ruby-lang.org/issues/200452023-12-07T09:28:07Zvo.x (Vit Ondruch)v.ondruch@tiscali.cz
<p>This is followup to <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: `TestFileExhaustive#test_expand_path_for_existent_username` and `TestDir#test_home` fails on i686 (Closed)" href="https://bugs.ruby-lang.org/issues/19147">#19147</a>. Testing on Fedora 38 and Fedora Rawhide, we are facing this test failure:</p>
<pre><code>$ tar xf build/SOURCES/ruby-3.2.2.tar.xz
$ cd ruby-3.2.2/
$ ./configure && make
... snip ...
---
Configuration summary for ruby version 3.2.2
* Installation prefix: /usr/local
* exec prefix: ${prefix}
* arch: i686-linux
* site arch: ${arch}
* RUBY_BASE_NAME: ruby
* ruby lib prefix: ${libdir}/${RUBY_BASE_NAME}
* site libraries path: ${rubylibprefix}/${sitearch}
* vendor path: ${rubylibprefix}/vendor_ruby
* target OS: linux
* compiler: gcc
* with thread: pthread
* with coroutine: x86
* enable shared libs: no
* dynamic library ext: so
* CFLAGS: ${optflags} ${debugflags} ${warnflags}
* LDFLAGS: -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic
* DLDFLAGS: -Wl,--compress-debug-sections=zlib
* optflags: -O3 -fno-fast-math
* debugflags: -ggdb3
* warnflags: -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wold-style-definition \
-Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat \
-Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wundef
* strip command: strip -S -x
* install doc: rdoc
* MJIT support: yes
* YJIT support: no
* man page type: doc
---
... snip ...
$ LANG=C make test-all 'TESTS=-v -n /TestDir#test_home/'
config.status: creating ruby-runner.h
making mjit_build_dir.so
generating i686-linux-fake.rb
i686-linux-fake.rb updated
Run options:
--seed=10517
"--ruby=./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems"
--excludes-dir=./test/excludes
--name=!/memory_leak/
-v
-n
/TestDir#test_home/
# Running tests:
[1/0] TestDir#test_home = 0.00 s
1) Error:
TestDir#test_home:
RuntimeError: can't set length of shared string
/builddir/ruby-3.2.2/test/ruby/test_dir.rb:557:in `expand_path'
/builddir/ruby-3.2.2/test/ruby/test_dir.rb:557:in `block in test_home'
Finished tests in 4.164691s, 0.2401 tests/s, 1.6808 assertions/s.
1 tests, 7 assertions, 0 failures, 1 errors, 0 skips
ruby -v: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [i686-linux]
make: *** [uncommon.mk:855: yes-test-all] Error 1
</code></pre>
<p>Please note that having the <code>C</code> locale is essential. The test passes just fine with e.g. <code>C.UTF-8</code> locale.</p>
<p>We were able to reduce the test case to the following:</p>
<pre><code>$ whoami
mockbuild
$ echo 'File.expand_path("~mockbuild")' > test.rb
$ LANG=C RUBYLIB=/builddir/ruby-3.2.2/.ext/i686-linux LD_LIBRARY_PATH=. ./ruby --disable-gems test.rb
test.rb:1:in `expand_path': can't set length of shared string (RuntimeError)
from test.rb:1:in `<main>'
</code></pre>
<p>As I said earlier, the <code>LANG=C</code> is essential as well as the <code>RUBYLIB=/builddir/ruby-3.2.2/.ext/i386-linux</code>. Adding the path to <code>RUBYLIB</code> enables Ruby to load the following libraries:</p>
<pre><code>/builddir/ruby-3.2.2/.ext/i686-linux/enc/encdb.so
/builddir/ruby-3.2.2/.ext/i686-linux/enc/trans/transdb.so
</code></pre>
<p>And that makes the difference. Also, the <code>File.expand_path("~mockbuild")</code> must be in some file, replacing this by <code>-e 'File.expand_path("~mockbuild")'</code> does not reproduce the issue.</p>
<p>We also believe that this was introduced by <a href="https://github.com/ruby/ruby/pull/6699" class="external">https://github.com/ruby/ruby/pull/6699</a>, specifically by <a class="changeset" title="Transition shape when object's capacity changes This commit adds a `capacity` field to shapes, a..." href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/5246f4027ec574e77809845e1b1f7822cc2a5cef">git|5246f4027ec574e77809845e1b1f7822cc2a5cef</a> and fixed in master by <a class="changeset" title="Enable 5 size pools on 32 bit systems This commit will allow 32 bit systems to take advantage of..." href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/b4571097df4a6bd848f1195026d82a92f3a7f9d8">git|b4571097df4a6bd848f1195026d82a92f3a7f9d8</a>.</p>
<p>Unfortunately, we were not able to discover what is the mechanism behind this, why this depends on locale, why the test must be in file, why the string is shared etc. But I hope we have provided enough details for someone else more knowledgeable.</p>
<p>Some background for this issue is also available here:</p>
<p><a href="https://src.fedoraproject.org/rpms/ruby/pull-request/164" class="external">https://src.fedoraproject.org/rpms/ruby/pull-request/164</a></p> Ruby master - Bug #19996 (Assigned): `RUBY_MN_THREADS=1` triggers Action Cable unit test failureshttps://bugs.ruby-lang.org/issues/199962023-11-10T04:16:56Zyahonda (Yasuo Honda)yasuo.honda@gmail.com
<a name="Steps-to-reproduce"></a>
<h3 >Steps to reproduce<a href="#Steps-to-reproduce" class="wiki-anchor">¶</a></h3>
<ol>
<li>Install <code>ruby 3.3.0dev</code>
</li>
<li>Set <code>RUBY_MN_THREADS=1</code> environment variable</li>
<li>Follow these steps</li>
</ol>
<pre><code>git clone https://github.com/rails/rails
cd rails
rm Gemfile.lock
bundle install
cd actioncable
bin/test test/channel/base_test.rb test/subscription_adapter/redis_test.rb test/channel/test_case_test.rb test/subscription_adapter/redis_test.rb test/client_test.rb --seed 14800
</code></pre>
<a name="Expected-behavior"></a>
<h3 >Expected behavior<a href="#Expected-behavior" class="wiki-anchor">¶</a></h3>
<p>It should pass as not setting <code>RUBY_MN_THREADS</code>.</p>
<pre><code>$ unset RUBY_MN_THREADS
$ bin/test test/channel/base_test.rb test/subscription_adapter/redis_test.rb test/channel/test_case_test.rb test/subscription_adapter/redis_test.rb test/client_test.rb --seed 14800
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/minitest-5.20.0/lib/minitest.rb:3: warning: mutex_m which will no longer be part of the default gems since Ruby 3.4.0. Add mutex_m to your Gemfile or gemspec.
Run options: --seed 14800
# Running:
.........................................................................
Finished in 12.031310s, 6.0675 runs/s, 46.7115 assertions/s.
73 runs, 562 assertions, 0 failures, 0 errors, 0 skips
$
</code></pre>
<a name="Actual-behavior"></a>
<h3 >Actual behavior<a href="#Actual-behavior" class="wiki-anchor">¶</a></h3>
<p>It usually fails as follows.</p>
<pre><code>$ bin/test test/channel/base_test.rb test/subscription_adapter/redis_test.rb test/channel/test_case_test.rb test/subscription_adapter/redis_test.rb test/client_test.rb --seed 14800
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/minitest-5.20.0/lib/minitest.rb:3: warning: mutex_m which will no longer be part of the default gems since Ruby 3.4.0. Add mutex_m to your Gemfile or gemspec.
Run options: --seed 14800
# Running:
..................................................F
Failure:
RedisAdapterTest::AlternateConfiguration#test_channel_prefix [/home/yahonda/src/github.com/rails/rails/actioncable/test/subscription_adapter/common.rb:35]:
Expected #<Concurrent::Event:0x00007f0b2698d4f0 @__Lock__=#<Thread::Mutex:0x00007f0b26f8cab8>, @__Condition__=#<Thread::ConditionVariable:0x00007f0b26f8ca90>, @set=false, @iteration=0> to be set?.
bin/test test/subscription_adapter/channel_prefix.rb:6
.F
Failure:
RedisAdapterTest::AlternateConfiguration#test_multiple_broadcast [/home/yahonda/src/github.com/rails/rails/actioncable/test/subscription_adapter/common.rb:35]:
Expected #<Concurrent::Event:0x00007f0b2698a4d0 @__Lock__=#<Thread::Mutex:0x00007f0b26fac688>, @__Condition__=#<Thread::ConditionVariable:0x00007f0b26fac4f8>, @set=false, @iteration=0> to be set?.
bin/test test/subscription_adapter/common.rb:74
E
Error:
ClientTest#test_interacting_clients:
ThreadError: queue empty
<internal:thread_sync>:18:in `pop'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:168:in `read_message'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:241:in `block (2 levels) in test_interacting_clients'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:218:in `block (2 levels) in concurrently'
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/promises.rb:1583:in `evaluate_to'
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/promises.rb:1766:in `block in on_resolvable'
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:352:in `run_task'
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:343:in `block (3 levels) in create_worker'
<internal:kernel>:187:in `loop'
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:334:in `block (2 levels) in create_worker'
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:333:in `catch'
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:333:in `block in create_worker'
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/promises.rb:1258:in `raise'
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/promises.rb:1258:in `wait_until_resolved!'
/home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/promises.rb:988:in `value!'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:218:in `map'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:218:in `concurrently'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:240:in `block in test_interacting_clients'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:90:in `with_puma_server'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:234:in `test_interacting_clients'
bin/test test/client_test.rb:233
E
Error:
ClientTest#test_disappearing_client:
ThreadError: queue empty
<internal:thread_sync>:18:in `pop'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:168:in `read_message'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:275:in `block in test_disappearing_client'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:90:in `with_puma_server'
/home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:273:in `test_disappearing_client'
bin/test test/client_test.rb:272
..................
Finished in 1323.812615s, 0.0551 runs/s, 0.3830 assertions/s.
73 runs, 507 assertions, 2 failures, 2 errors, 0 skips
$
</code></pre> Ruby master - Bug #19794 (Assigned): Ruby 3.2.2 fails to build on macOS Sonoma betashttps://bugs.ruby-lang.org/issues/197942023-08-02T05:08:15Zjhaungs (Jim Haungs)
<p>With Big Sur, Apple deprecated putting dylibs in /usr/local/lib. In Sonoma (beta 4), this directory has disappeared completely. However, ruby's configure script depends on its existence. So, virtually every ruby installer (RVM, rbenv, asdf, ruby-build, and even building from source tarball) fails.</p>
<p>When building ruby 3.2.2 from source, the configure step outputs the irritatingly useless "something wrong with LDFLAGS" error message and fails to build.</p>
<p>The solution was to <code>cd /usr/local; sudo mkdir lib</code> to create the missing lib directory under /usr/local.</p>
<p>It would be nice to remove this dependency from the configure script.</p> Ruby master - Bug #19410 (Assigned): If move from ractor fails with error, some objects are left ...https://bugs.ruby-lang.org/issues/194102023-02-03T20:02:50Zluke-gru (Luke Gruber)luke.gru@gmail.com
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">r</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">receive</span>
<span class="k">end</span>
<span class="n">a</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="n">obj</span> <span class="o">=</span> <span class="p">[</span><span class="n">a</span><span class="p">,</span> <span class="nb">proc</span> <span class="p">{</span> <span class="p">}]</span>
<span class="k">begin</span>
<span class="n">r</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="ss">move: </span><span class="kp">true</span><span class="p">)</span>
<span class="k">rescue</span> <span class="o">=></span> <span class="n">e</span>
<span class="nb">puts</span> <span class="s2">"couldn't move"</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="n">a</span> <span class="c1"># a is moved, this errors out. But it's not really moved because the other ractor can't access it. It's in limbo :)</span>
<span class="n">r</span> <span class="o"><<</span> <span class="ss">:end</span>
<span class="n">r</span><span class="p">.</span><span class="nf">take</span>
</code></pre>
<p>This might be tricky to fix, as it requires some sort of commit function for moving objects after every object is checked for ability to move.</p> Ruby master - Bug #19408 (Assigned): Object no longer frozen after moved from a ractorhttps://bugs.ruby-lang.org/issues/194082023-02-03T18:55:10Zluke-gru (Luke Gruber)luke.gru@gmail.com
<p>I think frozen objects should still be frozen after a move.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">r</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">receive</span>
<span class="nb">p</span> <span class="n">obj</span><span class="p">.</span><span class="nf">frozen?</span> <span class="c1"># should be true but is false</span>
<span class="nb">p</span> <span class="n">obj</span>
<span class="k">end</span>
<span class="n">obj</span> <span class="o">=</span> <span class="p">[</span><span class="no">Object</span><span class="p">.</span><span class="nf">new</span><span class="p">].</span><span class="nf">freeze</span>
<span class="n">r</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="ss">move: </span><span class="kp">true</span><span class="p">)</span>
<span class="n">r</span><span class="p">.</span><span class="nf">take</span>
</code></pre> Ruby master - Bug #19407 (Assigned): 2 threads taking from current ractor will hang foreverhttps://bugs.ruby-lang.org/issues/194072023-02-03T18:43:11Zluke-gru (Luke Gruber)luke.gru@gmail.com
<p>In the current implementation of Ractors, it's possible to <code>take</code> from the current ractor. This could be useful<br>
when co-ordinating threads:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">t</span> <span class="o">=</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">obj</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">take</span>
<span class="nb">p</span> <span class="n">obj</span> <span class="c1"># do some work with obj</span>
<span class="k">end</span>
<span class="n">t0</span> <span class="o">=</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">obj</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">take</span>
<span class="nb">p</span> <span class="n">obj</span> <span class="c1"># do some work with obj</span>
<span class="k">end</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">yield</span> <span class="ss">:go</span>
</code></pre>
<p>However it hangs forever:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">t</span> <span class="o">=</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">obj</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">take</span>
<span class="nb">p</span> <span class="n">obj</span>
<span class="k">end</span>
<span class="n">t0</span> <span class="o">=</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">obj</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">take</span>
<span class="nb">p</span> <span class="n">obj</span>
<span class="k">end</span>
<span class="nb">sleep</span> <span class="mf">0.5</span>
</code></pre>
<p>Should "self-take" be disabled, or was it designed to allow it but this is just a bug?</p> Ruby master - Bug #19383 (Assigned): Time.now.zone encoding for German display language in Window...https://bugs.ruby-lang.org/issues/193832023-01-26T20:52:24Zstringsn88keys (Thomas Powell)
<p>OS:<br>
Verified on Windows 10 and Windows Server 2022 and Ruby 2.7.7 through 3.1.3</p>
<p>Display language:<br>
Verified on German, but may impact other languages in which Time.now.zone returns characters that aren't [A-Za-z].</p>
<p>Time zone:<br>
CET (UTC +01:00) Amsterdam, Berlin, ...</p>
<p>Time.now.zone # => "Mitteleuro\xE3ische Zeit"<br>
Time.now.zone.encoding # => #<a href="Encoding:IBM437" class="external">Encoding:IBM437</a><br>
puts Time.now.zone # => "Mitteleurop∑ische Zeit" (should be "Mitteleuropäische Zeit")<br>
Time.now.zone.encode(Encoding::UTF_8) # => "Mitteleurop∑ische Zeit"</p>
<p>Doing a force_encoding on all encodings in Encoding.list reveals that ISO-8859-(1..16) and Windows-125(0,2,4,7) work to coerce the ä out of the time zone string:<br>
Time.now.zone.force_encoding(Encoding::WINDOWS_1252) # => "Mitteleuro\xE3ische Zeit"<br>
... but ...<br>
Time.now.zone.force_encoding(Encoding::WINDOWS_1252).encode(Encoding::UTF_8) #=> "Mitteleuropäische Zeit"</p>
<p>Related issue: This improper encoding/rendering caused Ohai's JSON output to be unparseable. Workaround was forcing to Windows-1252.<br>
<a href="https://github.com/chef/ohai/pull/1781" class="external">https://github.com/chef/ohai/pull/1781</a></p> Ruby master - Bug #19378 (Assigned): Windows: Use less syscalls for faster require of big gemshttps://bugs.ruby-lang.org/issues/193782023-01-26T07:02:23Zaidog (Andi Idogawa)andi@idogawa.com
<p>Hello 🙂</p>
<a name="Problem"></a>
<h2 >Problem<a href="#Problem" class="wiki-anchor">¶</a></h2>
<p>require is slow on windows for big gems. (example: require 'gtk3'=> 3 seconds+). This is a problem for people who want to make cross platform GUI apps with ruby.</p>
<a name="Possible-Reason"></a>
<h2 >Possible Reason<a href="#Possible-Reason" class="wiki-anchor">¶</a></h2>
<p>As touched on in <a href="https://bugs.ruby-lang.org/issues/15797" class="external">#15797</a> it seems like require uses realpath, which is emulated on windows. It checks every parent directory. The same syscalls run many times.</p>
<a name="Testfile"></a>
<h2 >Testfile<a href="#Testfile" class="wiki-anchor">¶</a></h2>
<p>C:\tmp\speedtest\testrequire.rb:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="n">__dir__</span> <span class="o">+</span> <span class="s2">"/helloworld1.rb"</span>
<span class="nb">require</span> <span class="n">__dir__</span> <span class="o">+</span> <span class="s2">"/helloworld2.rb"</span>
</code></pre>
<pre><code class="shell syntaxhl" data-language="shell">ruby <span class="nt">--disable-gems</span> C:<span class="se">\t</span>mp<span class="se">\s</span>peedtest<span class="se">\t</span>estrequire.rb
</code></pre>
<a name="Syscalls-per-FileDirectory"></a>
<h3 >Syscalls per File/Directory:<a href="#Syscalls-per-FileDirectory" class="wiki-anchor">¶</a></h3>
<ol>
<li>CreateFile</li>
<li>QueryInformationVolume</li>
<li>QueryIdInformation</li>
<li>QueryAllInformationFile</li>
<li>QueryNameInformationFile</li>
<li>QueryNameInformationFile</li>
<li>QueryNormalizedNameInformationFile</li>
<li>CloseFile</li>
</ol>
<a name="FilesDirectories-checked"></a>
<h3 >Files/Directories checked<a href="#FilesDirectories-checked" class="wiki-anchor">¶</a></h3>
<ol>
<li>C:\tmp</li>
<li>C:\tmp\speedtest</li>
<li>C:\tmp\speedtest\helloworld1.rb</li>
<li>C:\tmp</li>
<li>C:\tmp\speedtest</li>
<li>C:\tmp\speedtest\helloworld2.rb</li>
</ol>
<p>For two required files Ruby had to do 8*6 = <strong>48</strong> syscalls.<br>
The syscalls orginate from rb_w32_reparse_symlink_p / lstat</p>
<p>Rubygems live in subfolders with 9+ parts: "C:\Ruby32-x64\lib\ruby\gems\3.2.0\gems\glib2-4.0.8\lib\glib2\variant.rb"<br>
Each file takes 8 * 9 = <strong>72</strong>+ calls. For variant.rb it is <strong>80</strong> calls.<br>
The result for the syscalls don't change in such a short time, so it should be possible to cache it.</p>
<p>With require_relative it's twice as many calls.</p>
<a name="Other-testcases"></a>
<h2 >Other testcases<a href="#Other-testcases" class="wiki-anchor">¶</a></h2>
<p>Same result:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">File</span><span class="p">.</span><span class="nf">realpath</span> <span class="n">__dir__</span> <span class="o">+</span> <span class="s2">"/helloworld1.rb"</span>
<span class="no">File</span><span class="p">.</span><span class="nf">realpath</span> <span class="n">__dir__</span> <span class="o">+</span> <span class="s2">"/helloworld2.rb"</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">File</span><span class="p">.</span><span class="nf">stat</span> <span class="n">__dir__</span> <span class="o">+</span> <span class="s2">"/helloworld1.rb"</span>
<span class="no">File</span><span class="p">.</span><span class="nf">stat</span> <span class="n">__dir__</span> <span class="o">+</span> <span class="s2">"/helloworld2.rb"</span>
</code></pre>
<p>It does not happen in $LOAD_PATH.resolve_feature_path(<strong>dir</strong> + "/helloworld1.rb")</p>
<a name="Request"></a>
<h2 >Request<a href="#Request" class="wiki-anchor">¶</a></h2>
<p>Would it be possible to cache the stat calls when using require?<br>
I tried to implement a cache inside the ruby source code, but failed.<br>
If not, is there now a way to combine ruby files into one?</p>
<p>I previously talked about require here: <a href="https://bugs.ruby-lang.org/issues/19325#note-11" class="external">YJIT: Windows support lacking.</a></p>
<a name="How-to-reproduce"></a>
<h2 >How to reproduce<a href="#How-to-reproduce" class="wiki-anchor">¶</a></h2>
<p>Ruby versions: At least 3.0+, most likely older ones too.<br>
Tested using Ruby Installer 3.1 and 3.2.<br>
<a href="https://learn.microsoft.com/en-us/sysinternals/downloads/procmon" class="external">Procmon Software by Sysinternals</a></p> Ruby master - Bug #19374 (Assigned): Issue with Ractor.make_shareable with curried procshttps://bugs.ruby-lang.org/issues/193742023-01-24T12:40:33Zluke-gru (Luke Gruber)luke.gru@gmail.com
<p>This works, but shouldn't:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Worker</span>
<span class="k">def</span> <span class="nf">start</span><span class="p">(</span><span class="o">&</span><span class="n">blk</span><span class="p">)</span>
<span class="n">blk</span> <span class="o">=</span> <span class="n">blk</span><span class="p">.</span><span class="nf">curry</span> <span class="c1"># bug in ruby allows sharing of non-shareable proc</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">make_shareable</span><span class="p">(</span><span class="n">blk</span><span class="p">)</span>
<span class="vi">@ractor</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">blk</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">b</span><span class="o">|</span>
<span class="n">main</span> <span class="o">=</span> <span class="n">b</span><span class="p">.</span><span class="nf">call</span>
<span class="nb">p</span> <span class="s2">"from ractor: </span><span class="si">#{</span><span class="n">main</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">work</span>
<span class="vi">@ractor</span><span class="p">.</span><span class="nf">take</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">worker</span> <span class="o">=</span> <span class="no">Worker</span><span class="p">.</span><span class="nf">new</span>
<span class="n">a</span> <span class="o">=</span> <span class="nb">self</span> <span class="c1"># unshareable main object</span>
<span class="nb">p</span> <span class="s2">"from main: </span><span class="si">#{</span><span class="n">a</span><span class="si">}</span><span class="s2">"</span>
<span class="n">worker</span><span class="p">.</span><span class="nf">start</span> <span class="p">{</span> <span class="n">a</span> <span class="p">}</span>
<span class="n">worker</span><span class="p">.</span><span class="nf">work</span>
</code></pre>
<p>The curried proc has a reference to the original proc and it's not checked for shareability.</p> Ruby master - Bug #19372 (Assigned): Proc objects are not traversed for shareable check during Ra...https://bugs.ruby-lang.org/issues/193722023-01-23T19:23:33Zluke-gru (Luke Gruber)luke.gru@gmail.com
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Proc</span>
<span class="nb">attr_accessor</span> <span class="ss">:obj1</span>
<span class="k">def</span> <span class="nf">initialize</span>
<span class="vi">@obj1</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="o">=</span> <span class="kp">true</span><span class="p">.</span><span class="nf">instance_eval</span> <span class="p">{</span> <span class="no">Proc</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s2">"hi"</span> <span class="p">}</span> <span class="p">}</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">make_shareable</span><span class="p">(</span><span class="nb">p</span><span class="p">)</span>
<span class="nb">p</span> <span class="s2">"Obj1 frozen?"</span><span class="p">,</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">shareable?</span><span class="p">(</span><span class="nb">p</span><span class="p">.</span><span class="nf">obj1</span><span class="p">)</span>
<span class="no">P</span> <span class="o">=</span> <span class="nb">p</span>
<span class="n">r</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">pp</span> <span class="o">=</span> <span class="no">P</span>
<span class="nb">p</span> <span class="n">pp</span><span class="p">.</span><span class="nf">obj1</span> <span class="c1"># gives error in debug builds (rb_ractor_confirm_belonging rb_bug() call)</span>
<span class="k">end</span>
</code></pre> Ruby master - Bug #19369 (Assigned): Small corner-case issue that breaks Ractor isolation: change...https://bugs.ruby-lang.org/issues/193692023-01-23T01:28:22Zluke-gru (Luke Gruber)luke.gru@gmail.com
<p>I was looking into how objects are traversed for deep cloning and I came up with a way to break it. I don't think it'll ever happen in real life so it's not really an issue, just<br>
an interesting case. Run with warnings disabled.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">obj</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="nb">p</span> <span class="s2">"unshareable obj:"</span><span class="p">,</span> <span class="n">obj</span>
<span class="no">UNSHAREABLE</span> <span class="o">=</span> <span class="n">obj</span>
<span class="no">GO</span> <span class="o">=</span> <span class="kp">false</span>
<span class="no">SET</span> <span class="o">=</span> <span class="kp">false</span>
<span class="k">class</span> <span class="nc">Object</span>
<span class="nb">attr_accessor</span> <span class="ss">:unshareable</span>
<span class="k">def</span> <span class="nf">initialize_clone</span><span class="p">(</span><span class="n">orig</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"Clone called for </span><span class="si">#{</span><span class="n">orig</span><span class="p">.</span><span class="nf">inspect</span><span class="si">}</span><span class="s2">, self = </span><span class="si">#{</span><span class="nb">self</span><span class="p">.</span><span class="nf">inspect</span><span class="si">}</span><span class="s2">"</span>
<span class="n">_self</span> <span class="o">=</span> <span class="nb">self</span>
<span class="k">if</span> <span class="n">orig</span> <span class="o">==</span> <span class="no">UNSHAREABLE</span>
<span class="n">t</span> <span class="o">=</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="nb">puts</span> <span class="s2">"In thread"</span>
<span class="no">Thread</span><span class="p">.</span><span class="nf">pass</span> <span class="k">until</span> <span class="no">GO</span>
<span class="nb">puts</span> <span class="s2">"Setting unshareable!"</span>
<span class="c1"># this must be done in separate thread to bypass object traversal deep-cloning</span>
<span class="n">_self</span><span class="p">.</span><span class="nf">unshareable</span> <span class="o">=</span> <span class="no">UNSHAREABLE</span>
<span class="no">Object</span><span class="p">.</span><span class="nf">const_set</span><span class="p">(</span><span class="ss">:SET</span><span class="p">,</span> <span class="kp">true</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">super</span><span class="p">(</span><span class="n">orig</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">r</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">o</span><span class="o">|</span>
<span class="nb">puts</span> <span class="s2">"from r</span><span class="si">#{</span><span class="no">Ractor</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">object_id</span><span class="si">}</span><span class="s2"> obj </span><span class="si">#{</span><span class="n">o</span><span class="p">.</span><span class="nf">inspect</span><span class="si">}</span><span class="s2">"</span>
<span class="no">GO</span> <span class="o">=</span> <span class="kp">true</span>
<span class="kp">loop</span> <span class="k">until</span> <span class="no">SET</span>
<span class="nb">p</span> <span class="s2">"from ractor, got unshareable:"</span><span class="p">,</span> <span class="n">o</span><span class="p">.</span><span class="nf">unshareable</span>
<span class="k">end</span>
<span class="n">r</span><span class="p">.</span><span class="nf">take</span>
</code></pre> Ruby master - Bug #19368 (Assigned): Small issue with isolated procs and evalhttps://bugs.ruby-lang.org/issues/193682023-01-22T17:40:38Zluke-gru (Luke Gruber)luke.gru@gmail.com
<pre><code>a = Object.new # non-shareable
prok = Ractor.current.instance_eval do
Proc.new do
eval('a')
end
end
prok.call # this should work, we're in the main ractor and the proc is not isolated
Ractor.make_shareable(prok) # this doesn't currently work, but I think it should. It gives Ractor::IsolationError. See below for reasoning on why I think it should work.
# A flag seems to be set on the proc after it's run and accesses outers...
</code></pre>
<p>Because this work fine:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span> <span class="c1"># non-shareable</span>
<span class="n">prok</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">instance_eval</span> <span class="k">do</span>
<span class="no">Proc</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="nb">eval</span><span class="p">(</span><span class="s1">'a'</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">make_shareable</span><span class="p">(</span><span class="n">prok</span><span class="p">)</span> <span class="c1"># this works, and it's okay because we get a different error when actually running the shareable proc inside a ractor that accesses outers through eval.</span>
</code></pre> Ruby master - Bug #19367 (Assigned): Issue with ractor local storage APIhttps://bugs.ruby-lang.org/issues/193672023-01-22T14:46:45Zluke-gru (Luke Gruber)luke.gru@gmail.com
<p>In a non-main ractor, you can do Ractor.main[:key] = 'val', but it only affects storage for Ractor.current, not Ractor.main (which is good!).<br>
I think it should throw a RuntimeError if trying to get/set ractor-local storage for non-current ractor.</p>
<p>Patch coming.</p> Ruby master - Bug #19364 (Assigned): Issue with tracepoint enable/disable across ractorshttps://bugs.ruby-lang.org/issues/193642023-01-21T22:54:58Zluke-gru (Luke Gruber)luke.gru@gmail.com
<p>This sometimes segfaults:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">test_enable_disable_in_multiple_ractors_with_target</span>
<span class="n">rs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="mi">100</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
<span class="c1"># setup new iseqs</span>
<span class="no">Kernel</span><span class="p">.</span><span class="nf">define_method</span> <span class="ss">:"my_method_to_change_for_tracing_</span><span class="si">#{</span><span class="n">i</span><span class="si">}</span><span class="ss">"</span> <span class="k">do</span>
<span class="kp">true</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="mi">100</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
<span class="n">rs</span> <span class="o"><<</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">j</span><span class="o">|</span>
<span class="n">meth</span> <span class="o">=</span> <span class="ss">:"my_method_to_change_for_tracing_</span><span class="si">#{</span><span class="n">j</span><span class="si">}</span><span class="ss">"</span>
<span class="n">tp</span> <span class="o">=</span> <span class="no">TracePoint</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:line</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span> <span class="c1"># local to ractor</span>
<span class="mi">100</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span>
<span class="n">tp</span><span class="p">.</span><span class="nf">enable</span><span class="p">(</span><span class="ss">target: </span><span class="nb">method</span><span class="p">(</span><span class="n">meth</span><span class="p">))</span> <span class="c1"># change iseq internals of given method, should be done with lock</span>
<span class="n">tp</span><span class="p">.</span><span class="nf">disable</span> <span class="c1"># disable hooks should hold lock too, changes method definition internals</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">rs</span><span class="p">.</span><span class="nf">each</span><span class="p">(</span><span class="o">&</span><span class="ss">:take</span><span class="p">)</span> <span class="c1"># shouldn't raise</span>
<span class="k">end</span>
<span class="n">test_enable_disable_in_multiple_ractors_with_target</span><span class="p">()</span>
</code></pre>
<p>Changing iseq internals is done without the VM lock. This is true in Tracepoint#enable and Tracepoint#disable methods.<br>
I have a patch coming.</p> Ruby master - Bug #19338 (Assigned): Ruby hangs when ouputting warnings inside ractor with VM loc...https://bugs.ruby-lang.org/issues/193382023-01-14T18:15:37Zluke-gru (Luke Gruber)luke.gru@gmail.com
<p>This code causes Ruby to hang:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">rs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="mi">2</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span>
<span class="n">rs</span> <span class="o"><<</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="no">MYCONSTANT</span> <span class="o">=</span> <span class="mi">2</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">rs</span><span class="p">.</span><span class="nf">each</span><span class="p">(</span><span class="o">&</span><span class="ss">:take</span><span class="p">)</span>
</code></pre>
<p>There is a problem when the warning is being outputted with multiple ractors. A thread is calling RB_VM_LOCK() while holding the VM lock in ractor.c (ractor_check_blocking())</p>
<p>If the code is changed to RB_VM_LOCK_ENTER() and RB_VM_LOCK_LEAVE() then it fixes it, but I don't know if there's a better way.</p>
<p>Thanks!</p> Ruby master - Bug #18940 (Assigned): Ruby Ractor fails with IOError when handling higher concurrencyhttps://bugs.ruby-lang.org/issues/189402022-07-26T18:33:12Zbrodock (Gabriel Mazetto)brodock@gmail.com
<p>Reproduction server:</p>
<pre><code>require 'socket'
# Set based on CPU count
CONCURRENCY = 8
server = TCPServer.new(8080)
workers = CONCURRENCY.times.map do
Ractor.new do
loop do
# receive TCPSocket
session = Ractor.recv
request = session.gets
puts request
session.print "HTTP/1.1 200\r\n"
session.print "Content-Type: text/html\r\n"
session.print "\r\n"
session.print "Hello world! Current time is #{Time.now}"
session.close
end
end
end
loop do
conn, _ = server.accept
# pass TCPSocket to one of the workers
workers.sample.send(conn, move: true)
end
</code></pre>
<p>run apache benchmark against code above:</p>
<pre><code>ab -n 20000 -c 20 http://localhost:8080/
</code></pre>
<p>or run using hey (<a href="https://github.com/rakyll/hey" class="external">https://github.com/rakyll/hey</a>):</p>
<pre><code>hey -n 20000 -c 20 http://localhost:8080/
</code></pre>
<p>you should see something like this on the benchmark tool side:</p>
<pre><code>Summary:
Total: 32.9538 secs
Slowest: 2.6317 secs
Fastest: 0.0002 secs
Average: 0.0331 secs
Requests/sec: 606.9098
Response time histogram:
0.000 [1] |
0.263 [16968] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.527 [1740] |■■■■
0.790 [0] |
1.053 [0] |
1.316 [0] |
1.579 [0] |
1.842 [0] |
2.105 [20] |
2.369 [0] |
2.632 [6] |
Latency distribution:
10% in 0.0008 secs
25% in 0.0010 secs
50% in 0.0012 secs
75% in 0.0016 secs
90% in 0.0075 secs
95% in 0.3101 secs
99% in 0.3175 secs
Details (average, fastest, slowest):
DNS+dialup: 0.0322 secs, 0.0002 secs, 2.6317 secs
DNS-lookup: 0.0006 secs, 0.0000 secs, 0.0127 secs
req write: 0.0001 secs, 0.0000 secs, 0.0095 secs
resp wait: 0.0007 secs, 0.0000 secs, 0.0140 secs
resp read: 0.0001 secs, 0.0000 secs, 0.0088 secs
Status code distribution:
[200] 18735 responses
Error distribution:
[1231] Get "http://localhost:8080/": dial tcp [::1]:8080: connect: connection refused
[16] Get "http://localhost:8080/": dial tcp [::1]:8080: connect: connection reset by peer
[1] Get "http://localhost:8080/": net/http: HTTP/1.x transport connection broken: unexpected EOF
[1] Get "http://localhost:8080/": read tcp 127.0.0.1:57078->127.0.0.1:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57054->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57058->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57059->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57062->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57067->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57068->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57069->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57070->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57071->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57072->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57075->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57076->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57087->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57088->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57089->[::1]:8080: read: connection reset by peer
[1] Get "http://localhost:8080/": read tcp [::1]:57090->[::1]:8080: read: connection reset by peer
</code></pre>
<p>and this on the ruby process:</p>
<pre><code>...
GET / HTTP/1.1
GET / HTTP/1.1
#<Thread:0x0000000100fbf6e8 run> terminated with exception (report_on_exception is true):
ractor.rb:21:in `write': GET / HTTP/1.1
uninitialized stream (IOError)
from ractor.rb:21:in `print'
from ractor.rb:21:in `block (3 levels) in <main>'
from ractor.rb:11:in `loop'
from ractor.rb:11:in `block (2 levels) in <main>'
GET / HTTP/1.1
GET / HTTP/1.1
</code></pre> Ruby master - Bug #18677 (Assigned): BigDecimal#power (**) returns FloatDomainError when passing ...https://bugs.ruby-lang.org/issues/186772022-04-04T09:27:59Zdorianmariefr (Dorian Marié)
<p>Example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">></span> <span class="no">BigDecimal</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="o">**</span> <span class="no">BigDecimal</span><span class="p">(</span><span class="s2">"Infinity"</span><span class="p">)</span>
<span class="no">FloatDomainError</span><span class="p">:</span> <span class="no">Computation</span> <span class="n">results</span> <span class="k">in</span> <span class="s1">'Infinity'</span>
</code></pre>
<p>Maybe:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s2">"bigdecimal/util"</span>
<span class="k">class</span> <span class="nc">BigDecimal</span> <span class="o"><</span> <span class="no">Numeric</span>
<span class="k">def</span> <span class="nf">**</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">if</span> <span class="n">other</span><span class="p">.</span><span class="nf">infinite?</span> <span class="o">==</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nb">self</span> <span class="o">></span> <span class="mi">1</span>
<span class="no">BigDecimal</span><span class="o">::</span><span class="no">INFINITY</span>
<span class="k">elsif</span> <span class="nb">self</span> <span class="o">==</span> <span class="mi">1</span>
<span class="nb">self</span>
<span class="k">elsif</span> <span class="nb">self</span> <span class="o">>=</span> <span class="mi">0</span>
<span class="no">BigDecimal</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="k">else</span>
<span class="n">power</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">else</span>
<span class="n">power</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">puts_and_eval</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="nb">puts</span> <span class="n">string</span>
<span class="nb">p</span> <span class="nb">eval</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">puts_and_eval</span> <span class="s2">"10 ** BigDecimal::INFINITY"</span>
<span class="n">puts_and_eval</span> <span class="s2">"1 ** BigDecimal::INFINITY"</span>
<span class="n">puts_and_eval</span> <span class="s2">"0.1 ** BigDecimal::INFINITY"</span>
<span class="n">puts_and_eval</span> <span class="s2">"0 ** BigDecimal::INFINITY"</span>
<span class="n">puts_and_eval</span> <span class="s2">"-1 ** BigDecimal::INFINITY"</span>
</code></pre>
<p>Seems like ruby is doing very different things from math though</p> Ruby master - Bug #18338 (Open): Encoding.default_external = Encoding::UTF_16BE may add a wrongly...https://bugs.ruby-lang.org/issues/183382021-11-15T07:26:56Zmame (Yusuke Endoh)mame@ruby-lang.org
<pre><code># coding: US-ASCII
Encoding.default_external = Encoding::UTF_16BE
"abc".encode(Encoding.default_external)
p $LOADED_FEATURES.last.encoding #=> #<Encoding:UTF-16BE>
p $LOADED_FEATURES.last
#=> "\u2F68\u6F6D\u652F\u6D61\u6D65\u2F77\u6F72\u6B2F\u7275\u6279\u2F6C\u6F63\u616C\u2F6C\u6962\u2F72\u7562\u792F\u332E\u312E\u302F\u7838\u365F\u3634\u2D6C\u696E\u7578\u2F65\u6E63\u2F74\u7261\u6E73\u2F75\u7466\u5F31\u365F\u3332\u2E73\x6F"
</code></pre>
<p>This weird string seems <code>"/home/mame/work/ruby/local/lib/ruby/3.1.0/x86_64-linux/enc/trans/utf_16_32.s\u0000o".force_encoding("UTF-16BE")</code>.</p>
<p>Note that the code may raise a "code converter not found" error depending on the length of install path (or build path?). Maybe it works if it is even due to UTF-16.</p>
<pre><code># works
mame$ /Users/mame/ruby2/exe/ruby --disable-gems test.rb
#<Encoding:UTF-16BE>
"\u2F55\u7365\u7273\u2F6D\u616D\u652F\u7275\u6279\u322F\u2E65\u7874\u2F78\u3836\u5F36\u342D\u6461\u7277\u696E\u3139\u2F65\u6E63\u2F74\u7261\u6E73\u2F73\u696E\u676C\u655F\u6279\u7465\u2E62\u756E\u646C\x65"
</code></pre>
<pre><code># raises an exception
mame$ /Users/mame/ruby22/exe/ruby --disable-gems test.rb
0ec: 0x0
test.rb:4:in `encode': code converter not found (US-ASCII to UTF-16BE) (Encoding::ConverterNotFoundError)
from test.rb:4:in `<main>'
test.rb:4:in `encode': No such file or directory @ rb_check_realpath_internal - ⽕獥牳⽭慭支牵批㈲⼮數琯砸㙟㘴ⵤ慲睩渱㤯敮振瑲慮猯獩湧汥形祴攮扵湤汥 (Errno::ENOENT)
from test.rb:4:in `<main>'
</code></pre> Ruby master - Bug #18337 (Assigned): Ruby allows zero-width characters in identifiershttps://bugs.ruby-lang.org/issues/183372021-11-15T00:14:21Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<p>Ruby allows zero-width characters in identifiers, which can be shown with the following small test:</p>
<p>irb(main):001:0> script = "ab = 20; a\u200Bb = 30; puts ab;"<br>
=> "ab = 20; ab = 30; puts ab;"<br>
irb(main):002:0> eval(script)<br>
20<br>
=> nil</p>
<p>The first line creates the script. It contains a zero-width space (ZWSP), but that's not visible in most contexts (see next line). Looking at the script, one expects 30 as an output, but the output is 20 because there are two variables involved, one with a ZWSP and one without. I propose we fix this by disallowing such characters in identifiers. I'll give more details in a followup.</p> Ruby master - Bug #18255 (Open): ioctl zeroes the last buffer bytehttps://bugs.ruby-lang.org/issues/182552021-10-18T21:47:28Zvihai (Daniele Orlandi)daniele@orlandi.com
<p>Hello,</p>
<p>I'm running ruby 2.7.4p191 on an armv7 linux and experimenting with GPIO_GET_LINEHANDLE_IOCTL ioctl.</p>
<p>The ioctl sanity check is triggered as if the buffer was too small however the size of the buffer passed to ioctl is correct.</p>
<pre><code>io.rb:116:in `ioctl': return value overflowed string (ArgumentError)
</code></pre>
<p>If I append at least one byte to the buffer the ioctl does not raise an exception.</p>
<p>It seems that the last byte of the buffer is zeroed:</p>
<pre><code>puts "SIZE=#{req.bytesize}"
req = req + "XXXXXXXXXX".b
puts req.unpack("H*")
fd.ioctl(GPIO_GET_LINEHANDLE_IOCTL, req)
puts req.unpack("H*")
</code></pre>
<pre><code>SIZE=364
[...]0000000000000058585858585858585858
[...]0000000600000058585858585858585800
</code></pre>
<p>I checked with a C program and the ioctl does not actually touch the buffer beyond the expected 364 bytes.<br>
The ioctl number does encode 364 as size:</p>
<pre><code>#include <stdio.h>
#include <linux/gpio.h>
void main()
{
printf("SIZE=%d", _IOC_SIZE(GPIO_GET_LINEHANDLE_IOCTL));
}
</code></pre>
<pre><code>SIZE=364
</code></pre> Ruby master - Bug #18152 (Open): Fix theoretical bug with signals + qsorthttps://bugs.ruby-lang.org/issues/181522021-09-07T00:02:40Zeggert (Paul Eggert)eggert@cs.ucla.edu
<p>Ruby assumes that qsort is async-signal-safe, but POSIX does not guarantee this and it's not true of some qsort implementations, notably glibc. This is not a practical problem with glibc, since glibc qsort is async-signal-safe with small sorts and in practice Ruby's use of qsort is invariably small enough. However, it's better to be absolutely async-signal-safe, if only to pacify static checkers and the like.</p>
<p>I am attaching two alternative patches for the problem. Either will suffice. The first is simple and easier to audit, but does not scale well (though that is not important here). The second patch should scale, but is harder to audit.</p>
<p>It would be difficult to write test cases illustrating the bug that these patches fix, as they'd be timing dependent.</p> Ruby master - Bug #18131 (Open): addr2line.c: Some inlined functions mistakenly shownhttps://bugs.ruby-lang.org/issues/181312021-08-24T19:59:25Zxtkoba (Tee KOBAYASHI)
<p>What is observed in ppc64le CI (pathnames edited for readability):</p>
<pre><code>-- C level backtrace information -------------------------------------------
/home/xxx/ruby/ruby(rb_vm_bugreport+0x198) [0x6430d199028] vm_dump.c:759
/home/xxx/ruby/ruby(ibf_load_small_value+0x78) [0x6430cf011c8] error.c:815
/home/xxx/ruby/ruby(ibf_load_iseq_each) compile.c:11650
/home/xxx/ruby/ruby(vm_respond_to) compile.c:12594
/home/xxx/ruby/ruby(rb_ec_obj_respond_to) vm_method.c:2576
/home/xxx/ruby/ruby(rb_obj_respond_to) vm_method.c:2569
/home/xxx/ruby/ruby(rb_bug_for_fatal_signal) vm_method.c:2584
/home/xxx/ruby/ruby(sigsegv+0x64) [0x6430d0bb954] signal.c:961
linux-vdso64.so.1(__kernel_sigtramp_rt64+0x0) [0x795f1d6304c8]
/home/xxx/ruby/ruby(rb_ary_push+0x2c) [0x6430d1b31cc] array.c:1313
(...)
</code></pre>
<p>Here, 6 functions are shown for address <code>0x6430cf011c8</code>, of which only <code>rb_bug_for_fatal_signal</code> is valid.</p>
<p>I have not yet come up with how to fix this, but I suspect this is partially due to <code>ranges_include</code> in <code>addr2line.c</code> not handling <code>DW_AT_entry_pc</code> at all.</p> Ruby master - Bug #18119 (Assigned): Ractor crashes when instantiating classeshttps://bugs.ruby-lang.org/issues/181192021-08-19T13:23:40Zpeterzhu2118 (Peter Zhu)peter@peterzhu.ca
<p>The following script crashes with a segfault (tested on Ubuntu 20.04 and macOS 11.5.2):</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">workers</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="o">...</span><span class="mi">8</span><span class="p">).</span><span class="nf">map</span> <span class="k">do</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="kp">loop</span> <span class="k">do</span>
<span class="mi">100</span><span class="p">.</span><span class="nf">times</span><span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="no">Class</span><span class="p">.</span><span class="nf">new</span> <span class="p">}</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">yield</span> <span class="kp">nil</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="mi">100</span><span class="p">.</span><span class="nf">times</span> <span class="p">{</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">select</span><span class="p">(</span><span class="o">*</span><span class="n">workers</span><span class="p">)</span> <span class="p">}</span>
</code></pre>
<p>Crash error:</p>
<pre><code><internal:ractor>:267: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
test.rb:4: [BUG] Segmentation fault at 0x0000000000000040
ruby 3.1.0dev (2021-08-19T08:44:48Z master 6963f8f743) [x86_64-linux]
-- Control frame information -----------------------------------------------
c:0010 p:---- s:0033 e:000032 CFUNC :new
c:0009 p:0011 s:0029 e:000028 BLOCK test.rb:4 [FINISH]
c:0008 p:---- s:0026 e:000025 IFUNC
c:0007 p:---- s:0023 e:000022 CFUNC :times
c:0006 p:---- s:0020 e:000019 CFUNC :each
c:0005 p:---- s:0017 e:000016 CFUNC :map
c:0004 p:0007 s:0013 e:000012 BLOCK test.rb:4 [FINISH]
c:0003 p:---- s:0010 e:000009 CFUNC :loop
c:0002 p:0004 s:0006 e:000005 BLOCK test.rb:3 [FINISH]
c:0001 p:---- s:0003 e:000002 (none) [FINISH]
-- Ruby level backtrace information ----------------------------------------
test.rb:3:in `block (2 levels) in <main>'
test.rb:3:in `loop'
test.rb:4:in `block (3 levels) in <main>'
test.rb:4:in `map'
test.rb:4:in `each'
test.rb:4:in `times'
test.rb:4:in `block (4 levels) in <main>'
test.rb:4:in `new'
-- Machine register context ------------------------------------------------
RIP: 0x0000562c1f9cd2cb RBP: 0x00007f6c3736d378 RSP: 0x00007f6c368285f0
RAX: 0x00007f6c1c00e208 RBX: 0x00007f6c3736d378 RCX: 0x0000562c20ed8330
RDX: 0x0000000000000000 RDI: 0x00007f6c100095c0 RSI: 0x0000000000000000
R8: 0x0000000000000007 R9: 0x0000562c20ed8120 R10: 0x0000000000000022
R11: 0x0000562c21180760 R12: 0x0000000000000000 R13: 0x00007f6c3736c000
R14: 0x0000000000000000 R15: 0x00007f6c3736d378 EFL: 0x0000000000010202
-- C level backtrace information -------------------------------------------
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_print_backtrace+0x11) [0x562c1f995e38] ../vm_dump.c:759
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_vm_bugreport) ../vm_dump.c:1041
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_bug_for_fatal_signal+0xec) [0x562c1f78a0bc] ../error.c:815
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(sigsegv+0x4d) [0x562c1f8ebcbd] ../signal.c:961
/lib/x86_64-linux-gnu/libpthread.so.0(__restore_rt+0x0) [0x7f6c3b2c63c0]
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_class_remove_from_super_subclasses+0x2b) [0x562c1f9cd2cb] ../class.c:99
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(obj_free+0x37a) [0x562c1f7ae95a] ../gc.c:3123
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(gc_plane_sweep+0x21) [0x562c1f7aef3d] ../gc.c:5322
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(gc_page_sweep) ../gc.c:5464
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(gc_sweep_step) ../gc.c:5630
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(gc_heap_prepare_minimum_pages+0x0) [0x562c1f7afd94] ../gc.c:5834
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(gc_sweep) ../gc.c:5837
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(gc_marks+0x1c0) [0x562c1f7b3df8] ../gc.c:8144
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(gc_start) ../gc.c:9013
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(heap_prepare+0x2f) [0x562c1f7b8b6f] ../gc.c:2131
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(heap_next_freepage) ../gc.c:2422
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(ractor_cache_slots) ../gc.c:2454
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(newobj_slowpath) ../gc.c:2495
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(newobj_slowpath_wb_protected) ../gc.c:2519
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(newobj_of0+0x5) [0x562c1f7b8ebd] ../gc.c:2562
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(newobj_of) ../gc.c:2572
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_wb_protected_newobj_of) ../gc.c:2596
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(class_alloc+0x5) [0x562c1f9cd49e] ../class.c:185
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_class_boot) ../class.c:230
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(class_call_alloc_func+0x5) [0x562c1f84e5d3] ../object.c:2075
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_class_alloc) ../object.c:2047
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_class_new_instance_pass_kw) ../object.c:2120
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_cfp_consistent_p+0x0) [0x562c1f96d6bc] ../vm_insnhelper.c:2989
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_call_cfunc_with_frame) ../vm_insnhelper.c:2991
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_sendish+0x303) [0x562c1f978393] ../vm_insnhelper.c:4562
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_exec_core+0xcd) [0x562c1f98316d] ../insns.def:775
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_vm_exec+0x197) [0x562c1f978fc7] ../vm.c:2164
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(collect_i+0x12) [0x562c1fa27bf2] ../enum.c:608
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_vm_pop_frame+0x0) [0x562c1f976ba8] ../vm_insnhelper.c:3795
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_yield_with_cfunc) ../vm_insnhelper.c:3796
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(invoke_block_from_c_bh+0x10) [0x562c1f97d0d3] ../vm.c:1359
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_yield) ../vm.c:1399
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_yield_0) ../vm_eval.c:1350
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_yield_1) ../vm_eval.c:1356
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(int_dotimes+0x5c) [0x562c1f83a49c] ../numeric.c:5014
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_cfp_consistent_p+0x0) [0x562c1f97dd4f] ../vm_eval.c:135
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_call0_cfunc_with_frame) ../vm_eval.c:137
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_call0_cfunc) ../vm_eval.c:149
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_call0_body) ../vm_eval.c:182
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_call0+0x1ea) [0x562c1f9812fa] ../vm_eval.c:72
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(iterate_method+0x3b) [0x562c1f981e9b] ../vm_eval.c:847
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_iterate0+0x101) [0x562c1f973001] ../vm_eval.c:1534
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_block_call_kw+0x76) [0x562c1f9731f6] ../vm_eval.c:1566
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(enumerator_block_call+0x59) [0x562c1fa358e9] ../enumerator.c:553
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_cfp_consistent_p+0x0) [0x562c1f97dd4f] ../vm_eval.c:135
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_call0_cfunc_with_frame) ../vm_eval.c:137
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_call0_cfunc) ../vm_eval.c:149
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_call0_body) ../vm_eval.c:182
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_call0+0x1ea) [0x562c1f9812fa] ../vm_eval.c:72
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(iterate_method+0x3b) [0x562c1f981e9b] ../vm_eval.c:847
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_iterate0+0x101) [0x562c1f973001] ../vm_eval.c:1534
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_lambda_call+0x75) [0x562c1f973295] ../vm_eval.c:1633
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(enum_collect+0x5b) [0x562c1fa29acb] ../enum.c:647
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_cfp_consistent_p+0x0) [0x562c1f96d6bc] ../vm_insnhelper.c:2989
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_call_cfunc_with_frame) ../vm_insnhelper.c:2991
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_sendish+0x303) [0x562c1f978393] ../vm_insnhelper.c:4562
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_exec_core+0x130) [0x562c1f9831d0] ../insns.def:756
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_vm_exec+0x197) [0x562c1f978fc7] ../vm.c:2164
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(invoke_block_from_c_bh+0x130) [0x562c1f97c85a] ../vm.c:1264
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_yield) ../vm.c:1399
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_yield_0) ../vm_eval.c:1350
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(loop_i) ../vm_eval.c:1449
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_vrescue2+0x114) [0x562c1f794694] ../eval.c:1023
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_rescue2+0x8e) [0x562c1f79490e] ../eval.c:1000
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_cfp_consistent_p+0x0) [0x562c1f96d6bc] ../vm_insnhelper.c:2989
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_call_cfunc_with_frame) ../vm_insnhelper.c:2991
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_sendish+0x303) [0x562c1f978393] ../vm_insnhelper.c:4562
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(vm_exec_core+0x130) [0x562c1f9831d0] ../insns.def:756
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_vm_exec+0x197) [0x562c1f978fc7] ../vm.c:2164
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(thread_do_start_proc+0x294) [0x562c1f930f24] ../thread.c:716
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(thread_do_start+0xc) [0x562c1f9336fc] ../thread.c:760
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(thread_start_func_2) ../thread.c:835
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(rb_native_cond_initialize+0x0) [0x562c1f933a09] ../thread_pthread.c:1051
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(register_cached_thread_and_wait) ../thread_pthread.c:1103
/home/spin/src/github.com/Shopify/ruby-master/install/bin/ruby(thread_start_func_1) ../thread_pthread.c:1058
/lib/x86_64-linux-gnu/libpthread.so.0(0x9609) [0x7f6c3b2ba609]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x43) [0x7f6c3b044293]
</code></pre> Ruby master - Bug #18013 (Open): Unexpected results when mxiing negated character classes and cas...https://bugs.ruby-lang.org/issues/180132021-06-29T08:55:22Zjirkamarsik (Jirka Marsik)
<pre><code>irb(main):001:0> /[^a-c]/i.match("A")
=> nil
irb(main):002:0> /[[^a-c]]/i.match("A")
=> #<MatchData "A">
</code></pre>
<p>The two regular expressions above match different strings, because the character classes denote different sets of characters. In order for <code>/[^a-c]/i</code> to produce correct results, Oniguruma provided a fix that can still be easily seen in the code as it is hidden behind an always-on preprocessor flag (<code>CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS</code>, <a href="https://github.com/ruby/ruby/blob/9eae8cdefba61e9e51feb30a4b98525593169666/regparse.c#L5528" class="external">https://github.com/ruby/ruby/blob/9eae8cdefba61e9e51feb30a4b98525593169666/regparse.c#L5528</a>). The idea of the fix is to first case-fold a character class and only then apply the negation (essentially moving the case-fold operator <em>inside</em> the negation).</p>
<p>In the case of our first regular expression, <code>[a-c]</code> is case-folded into <code>[a-cA-C]</code> and that is then inverted into <code>[^a-cA-C]</code>, which is the expected result. However, this case-folding logic is currently only being applied to the top-most character class and so if we use a nested negated character class, the order of the operations will be switched.</p>
<p>With our second regular expression, <code>[a-c]</code> will first be negated to yield <code>[^a-c]</code>, which will then be case-folded into <code>.</code>, the set of all characters (since <code>[^a-c]</code> contains <code>A-C</code>, which case-fold into <code>a-c</code>).</p>
<p>A way to fix this would be to apply case-folding for nested character classes as well, so that the nested character classes behave the same as the top-most character class. Then, we would get the same semantics for both expressions.</p> Ruby master - Bug #18012 (Open): Case-insensitive character classes can only match multiple code ...https://bugs.ruby-lang.org/issues/180122021-06-29T08:35:05Zjirkamarsik (Jirka Marsik)
<p>Some Unicode characters case-fold to strings of multiple code points, e.g. the ligature <code>\ufb00</code> can match the string <code>ff</code>.</p>
<pre><code>irb(main):001:0> /\A[\ufb00]\z/i.match("\ufb00")
=> #<MatchData "ff">
irb(main):002:0> /\A[\ufb00]\z/i.match("ff")
=> #<MatchData "ff">
</code></pre>
<p>As expected, when we negate this character class, we can no longer match neither the ligature character <code>\ufb00</code> nor the string <code>ff</code>.</p>
<pre><code>irb(main):003:0> /\A[^\ufb00]\z/i.match("\ufb00")
=> nil
irb(main):004:0> /\A[^\ufb00]\z/i.match("ff")
=> nil
</code></pre>
<p>Then, when we add a second negation, the <code>\ufb00</code> ligature reappears in the character set but the string <code>ff</code> is no longer accepted.</p>
<pre><code>irb(main):005:0> /\A[^[^\ufb00]]\z/i.match("\ufb00")
=> #<MatchData "ff">
irb(main):006:0> /\A[^[^\ufb00]]\z/i.match("ff")
=> nil
</code></pre>
<p>This reveals that the multi-code-point matches in character classes are blocked by negation. However, this is implemented only by checking whether the topmost character class is negated. If we wrap the character class in another set of brackets, the semantics change.</p>
<pre><code>irb(main):007:0> /\A[[^[^\ufb00]]]\z/i.match("\ufb00")
=> #<MatchData "ff">
irb(main):008:0> /\A[[^[^\ufb00]]]\z/i.match("ff")
=> #<MatchData "ff">
</code></pre>
<p>The cause behind this discrepancy (the fact that <code>[^[^\ufb00]]</code> and <code>[[^[^\ufb00]]]</code> match different strings) is the extra <code>IS_NCCLASS_NOT</code> check in <code>i_apply_case_fold</code> (<a href="https://github.com/ruby/ruby/blob/9eae8cdefba61e9e51feb30a4b98525593169666/regparse.c#L5568" class="external">https://github.com/ruby/ruby/blob/9eae8cdefba61e9e51feb30a4b98525593169666/regparse.c#L5568</a>).</p> Ruby master - Bug #18010 (Open): Character class with single character gets case-folded with foll...https://bugs.ruby-lang.org/issues/180102021-06-28T09:30:01Zjirkamarsik (Jirka Marsik)
<pre><code>irb(main):001:0> /ff/i.match("\ufb00")
=> #<MatchData "ff">
irb(main):002:0> /[f]f/i.match("\ufb00")
=> #<MatchData "ff">
irb(main):003:0> /f[f]/i.match("\ufb00")
=> nil
irb(main):004:0> /[f][f]/i.match("\ufb00")
=> nil
irb(main):005:0> /(?:f)f/i.match("\ufb00")
=> nil
irb(main):006:0> /f(?:f)/i.match("\ufb00")
=> nil
irb(main):007:0> /(?:f)(?:f)/i.match("\ufb00")
=> nil
</code></pre>
<p>In the above, singleton character classes (<code>[...]</code>) and even parentheses (<code>(?:...)</code>) break up string literals, forcing each separate substring to be matched against separately. However, in the one case when a singleton character class precedes a string, it is joined with it as an optimization. However, this optimization ends up changing the semantics of the Regexp.</p> Ruby master - Bug #18002 (Open): s390x: Tests failing without LC_ALL envhttps://bugs.ruby-lang.org/issues/180022021-06-21T10:45:16Zjaruga (Jun Aruga)
<p>The following failures happened in RubyCI on our s390x Ubuntu focal server.<br>
On the server, RubyCI (ruby/chkbuild) is executed with LC_ALL not set, by cron.<br>
I found the unset <code>LC_ALL</code> causes the failures on the s390x server. This does not happen on x86_64 Fedora 33 on my local machine.</p>
<p>I was able to reproduce the failures on the master branch <code>dbd1887d04f5ff7c2a1f0a27d7339133a</code> on the server.</p>
<a name="Reproducer"></a>
<h2 >Reproducer<a href="#Reproducer" class="wiki-anchor">¶</a></h2>
<pre><code>$ uname -m
s390x
$ autoconf
$ ./configure \
--prefix=${HOME}/local/ruby-master-9d96837 \
--enable-shared
$ make
</code></pre>
<h3>Without <code>LC_ALL</code>
</h3>
<p>Then run the tests without <code>LC_ALL</code>.</p>
<pre><code>$ unset LC_ALL
$ echo $LC_ALL
<= empty
</code></pre>
<pre><code>$ make test-all TESTS="-v test/ruby/test_file.rb -n TestFile#test_realpath_encoding"
Run options:-
--seed=85060
"--ruby=./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems"
--excludes-dir=./test/excludes
--name=!/memory_leak/
-v
-n
TestFile#test_realpath_encoding
# Running tests:
[1/0] TestFile#test_realpath_encoding = 0.00 s
1) Failure:
TestFile#test_realpath_encoding [/home/jaruga/git/ruby/ruby2/test/ruby/test_file.rb:284]:
<"/tmp/rubytest-realpath20210621-3365652-za1wql/A\u0391\u0410\u0531\u10A0\u05D0\u2C00\u3042"> expected but was
<"/tmp/rubytest-realpath20210621-3365652-za1wql/A\u00CE\u0091\u00D0\u0090\u00D4\u00B1\u00E1\u0082\u00A0\u00D7\u0090\u00E2\u00B0\u0080\u00E3\u0081\u0082">.
Finished tests in 0.007217s, 138.5674 tests/s, 692.8372 assertions/s.
1 tests, 5 assertions, 1 failures, 0 errors, 0 skips
ruby -v: ruby 3.1.0dev (2021-06-18T10:13:36Z master 9d96837dbd) [s390x-linux]
make: *** [uncommon.mk:803: yes-test-all] Error 1
</code></pre>
<pre><code>$ make test-all TESTS="-v test/irb/test_context.rb -n TestIRB::TestContext#test_eval_input_with_invalid_byte_sequence_exception"
Run options:-
--seed=74635
"--ruby=./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems"
--excludes-dir=./test/excludes
--name=!/memory_leak/
-v
-n
TestIRB::TestContext#test_eval_input_with_invalid_byte_sequence_exception
# Running tests:
[1/0] TestIRB::TestContext#test_eval_input_with_invalid_byte_sequence_exception = 0.00 s
1) Failure:
TestIRB::TestContext#test_eval_input_with_invalid_byte_sequence_exception [/home/jaruga/git/ruby/ruby2/test/irb/test_context.rb:505]:
Expected /\(irb\):1:in `fuga': A\\xF3B \(RuntimeError\)\n/
to match
"(irb):1:in `fuga': A�B (RuntimeError)\n"+
"\tfrom (irb):1:in `hoge'\n"+
"\tfrom (irb):1:in `<main>'\n"
after 1 patterns with 0 characters.
Finished tests in 0.007640s, 130.8819 tests/s, 785.2916 assertions/s.
1 tests, 6 assertions, 1 failures, 0 errors, 0 skips
ruby -v: ruby 3.1.0dev (2021-06-18T10:13:36Z master 9d96837dbd) [s390x-linux]
make: *** [uncommon.mk:803: yes-test-all] Error 1
</code></pre>
<h3>With <code>export LC_ALL=C</code>
</h3>
<p>On the <code>export LC_ALL=C</code> (<code>LC_ALL=C</code> without <code>export</code> is not enough to pass the tests)</p>
<pre><code>$ export LC_ALL=C
$ echo $LC_ALL
C
</code></pre>
<pre><code>$ make test-all TESTS="-v test/ruby/test_file.rb -n TestFile#test_realpath_encoding"
Run options:
--seed=89696
"--ruby=./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems"
--excludes-dir=./test/excludes
--name=!/memory_leak/
-v
-n
TestFile#test_realpath_encoding
# Running tests:
[1/0] TestFile#test_realpath_encoding = 0.00 s
Finished tests in 0.004715s, 212.0691 tests/s, 1060.3455 assertions/s.
1 tests, 5 assertions, 0 failures, 0 errors, 0 skips
ruby -v: ruby 3.1.0dev (2021-06-18T10:13:36Z master 9d96837dbd) [s390x-linux]
</code></pre>
<pre><code>$ make test-all TESTS="-v test/irb/test_context.rb -n TestIRB::TestContext#test_eval_input_with_invalid_byte_sequence_exception"
Run options:
--seed=67965
"--ruby=./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems"
--excludes-dir=./test/excludes
--name=!/memory_leak/
-v
-n
TestIRB::TestContext#test_eval_input_with_invalid_byte_sequence_exception
# Running tests:
[1/0] TestIRB::TestContext#test_eval_input_with_invalid_byte_sequence_exception = 0.00 s
Finished tests in 0.007877s, 126.9448 tests/s, 761.6689 assertions/s.
1 tests, 6 assertions, 0 failures, 0 errors, 0 skips
ruby -v: ruby 3.1.0dev (2021-06-18T10:13:36Z master 9d96837dbd) [s390x-linux]
</code></pre>
<a name="Possible-Solution"></a>
<h2 >Possible Solution<a href="#Possible-Solution" class="wiki-anchor">¶</a></h2>
<p>Fix the tests not depending on the external LC_ALL condition.</p> Ruby master - Bug #17999 (Open): TestMethod#test_zsuper intermittent timeout error on raspbian10-...https://bugs.ruby-lang.org/issues/179992021-06-18T01:33:18Zxtkoba (Tee KOBAYASHI)
<p>In <a href="http://rubyci.s3.amazonaws.com/raspbian10-aarch64/ruby-master/log/20210617T223805Z.log.html.gz" class="external">http://rubyci.s3.amazonaws.com/raspbian10-aarch64/ruby-master/log/20210617T223805Z.log.html.gz</a> the following error message is observed:</p>
<pre><code> 1) Error:
TestMethod#test_zsuper:
Timeout::Error: execution of assert_separately expired timeout (30.0 sec)
pid 16029 killed by SIGTERM (signal 15)
|
/home/chkbuild/build/20210617T223805Z/ruby/test/ruby/test_inlinecache.rb:37:in `test_zsuper'
</code></pre>
<p>This seems to appear intermittently.</p>
<p>As for test timeout on aarch64-linux we have other open issues: <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: TestThreadQueue#test_thr_kill is flaky on AArch64 (Closed)" href="https://bugs.ruby-lang.org/issues/16493">#16493</a>, <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: TestThread#test_signal_at_join fails on aarch64 (Closed)" href="https://bugs.ruby-lang.org/issues/16920">#16920</a>, <a class="issue tracker-1 status-1 priority-4 priority-default" title="Bug: make notes and make test fail with Ruby3.0.1p64 RaspberryPI 4B Ubuntu 20.10 ARM64 (Open)" href="https://bugs.ruby-lang.org/issues/17792">#17792</a>. I'm not sure if they are relevant to one another in any way.</p> Ruby master - Bug #17998 (Assigned): ractor: process hanging (with ractors initialized, but not b...https://bugs.ruby-lang.org/issues/179982021-06-17T13:45:50Zchucke (Tiago Cardoso)
<p>I couldn't figure out how to reproduce this in a more contained way, so I'll share what I'm doing <a href="https://github.com/HoneyryderChuck/minitest/tree/issue-872" class="external">in this minitest branch</a>.</p>
<p>I'm trying to make minitest's parallel mode use ractors. If you look at the last commit of the branch, I'm:</p>
<ul>
<li>replacing the parallel executor with a ractor-based one;</li>
<li>I'm defining the ractor executor, where I have a ractor pipe that a pool will consume work from</li>
<li>I'm turning off parallel subset of tests (to reproduce the bug that I'll be describing).</li>
</ul>
<p>When I run <code>rake test</code> in my Mac (BigSur 11.4), the process hangs. I can see that the ractor threads are executing and running, but the test process doesn't respond to the INFO signal interrupt (which should tell me where the process is hanging). This seems like a bug in the VM, as no work is being sent to the parallel executor, i.e. all ractors should be sleeping (I've <code>puts</code>'d also the executor shutdown process, and it never reaches it).</p>
<p>If I replace the ractor-based executor back with the thread based executor, everything works as expected.</p> Ruby master - Bug #17990 (Open): Inconsistent behavior of Regexp quantifiers over characters with...https://bugs.ruby-lang.org/issues/179902021-06-15T11:59:27Zjirkamarsik (Jirka Marsik)
<p>With case insensitive Regexps, the string <code>"ff"</code> is considered equal to the string <code>"\ufb00"</code> with a single ligature character.</p>
<pre><code>irb(main):001:0> /ff/i.match("\ufb00")
=> #<MatchData "ff">
</code></pre>
<p>This behavior also persists when the string <code>"ff"</code> doesn't appear literally in the Regexp source but is expressed using a fixed-length quantifier, as in the following:</p>
<pre><code>irb(main):002:0> /f{2}/i.match("\ufb00")
=> #<MatchData "ff">
irb(main):003:0> /f{2,2}/i.match("\ufb00")
=> #<MatchData "ff">
</code></pre>
<p>However, this doesn't hold in general. When using other quantifiers, the ligature character <code>"\ufb00"</code> is not recognized a sequence of two <code>"f"</code> characters.</p>
<pre><code>irb(main):004:0> /f*/i.match("\ufb00")
=> #<MatchData "">
irb(main):005:0> /f+/i.match("\ufb00")
=> nil
irb(main):006:0> /f{1,}/i.match("\ufb00")
=> nil
irb(main):007:0> /f{1,2}/i.match("\ufb00")
=> nil
irb(main):008:0> /f{,2}/i.match("\ufb00")
=> #<MatchData "">
irb(main):009:0> /ff?/i.match("\ufb00")
=> nil
</code></pre>
<p>This leads to inconsistent behavior where a Regexp like <code>/f{1,2}/i</code> matches <em>fewer</em> strings than the more strict Regexp <code>/f{2,2}/i</code>.</p>
<p>I suspect that this is caused by the pattern analyzer directly expanding <code>/f{2}/i</code> and <code>/f{2,2}/i</code> into <code>/ff/i</code>. However, this optimization then changes the semantics of the Regexp, as it is otherwise impossible to match a single ligature character via multiple repetitions of a quantified expression.</p>
<p>While experimenting with this case, I have also discovered a related issue (caused by the problematic expansions of <code>/f{n}/i</code> and the issue reported here: <a href="https://bugs.ruby-lang.org/issues/17989" class="external">https://bugs.ruby-lang.org/issues/17989</a>).</p>
<p>These match:</p>
<pre><code>/f{100}/i.match("f" * 100)
/f{100}/i.match("\ufb00" * 50)
/f{100}/i.match("\ufb00" * 49 + "ff")
/f{100}/i.match("ff" + "\ufb00" * 49)
</code></pre>
<p>However, this doesn't match:</p>
<pre><code>/f{100}/i.match("f" + "\ufb00" * 49 + "f")
</code></pre> Ruby master - Bug #17989 (Open): Case insensitive Regexps do not handle characters with overlappi...https://bugs.ruby-lang.org/issues/179892021-06-15T11:43:14Zjirkamarsik (Jirka Marsik)
<p>When a Regexp uses the case-insensitive flag, strings are compared by first case folding them and then comparing the case foldings for equality. When a literal string is encountered in a Regexp source, the pattern analyzer tries to enumerate all possible strings that would case fold to the same string as the string in the pattern. In this way, case folding can be avoided when the Regexp is used to match. However, the algorithm used to enumerate all the possible strings which case fold to the same string is not complete. It assumes that the case foldings of different characters do not overlap (i.e. the multi-character case folding of some character cannot be a prefix or suffix of the multi-character case folding of some other character). However, this is not the case for several Unicode characters.</p>
<p>In the code below, many of the equalities <code>A == B</code>, tested via <code>/A/i.match("B")</code>, do not hold. Those that do hold hold only because the number of case-equivalent strings detected by the analyzer crosses a threshold at which point the analyzer abandons this optimization.</p>
<pre><code>/\ufb00/i.match("ff") # LATIN SMALL LIGATURE FF
/\ufb01/i.match("fi") # LATIN SMALL LIGATURE FI
/\ufb02/i.match("fl") # LATIN SMALL LIGATURE FL
/\ufb03/i.match("ffi") # LATIN SMALL LIGATURE FFI
/\ufb04/i.match("ffl") # LATIN SMALL LIGATURE FFL
# (ff)i == (ffi)
/\ufb00i/i.match("\ufb03")
# (ffi) == (ff)i
/\ufb03/i.match("\ufb00i")
# f(fi) == (ffi)
/f\ufb01/i.match("\ufb03")
# (ffi) == f(fi)
/\ufb03/i.match("f\ufb01")
# (ff)l == (ffl)
/\ufb00l/i.match("\ufb04")
# (ffl) == (ff)l
/\ufb04/i.match("\ufb00l")
# f(fl) == (ffl)
/f\ufb02/i.match("\ufb04")
# (ffl) == f(fl)
/\ufb04/i.match("f\ufb02")
/\u1f50/i.match("\u03c5\u0313") # GREEK SMALL LETTER UPSILON WITH PSILI
/\u1f52/i.match("\u03c5\u0313\u0300") # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
/\u1f54/i.match("\u03c5\u0313\u0301") # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
/\u1f56/i.match("\u03c5\u0313\u0342") # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
# (upsilon psili) varia == (upsilon psili varia)
/\u1f50\u0300/i.match("\u1f52")
# (upsilon psili varia) == (upsilon psili) varia
/\u1f52/i.match("\u1f50\u0300")
# (upsilon psili) oxia == (upsilon psili oxia)
/\u1f50\u0301/i.match("\u1f54")
# (upsilon psili oxia) == (upsilon psili) oxia
/\u1f54/i.match("\u1f50\u0301")
# (upsilon psili) perispomeni == (upsilon psili perispomeni)
/\u1f50\u0342/i.match("\u1f56")
# (upsilon psili perispomeni) == (upsilon psili) perispomeni
/\u1f56/i.match("\u1f50\u0342")
/\u1fb6/i.match("\u03b1\u0342") # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
/\u1fb7/i.match("\u03b1\u0342\u03b9") # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
# (alpha perispomeni) ypogegrammeni == (alpha perispomeni ypogegrammeni)
/\u1fb6\u03b9/i.match("\u1fb7")
# (alpha perispomeni ypogegrammeni) == (alpha perispomeni) ypogegrammeni
/\u1fb7/i.match("\u1fb6\u03b9")
/\u1fc6/i.match("\u03b7\u0342") # GREEK SMALL LETTER ETA WITH PERISPOMENI
/\u1fc7/i.match("\u03b7\u0342\u03b9") # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
# (eta perispomeni) ypogegrammeni == (eta perispomeni ypogegrammeni)
/\u1fc6\u03b9/i.match("\u1fc7")
# (eta perispomeni ypogegrammeni) == (eta perispomeni) ypogegrammeni
/\u1fc7/i.match("\u1fc6\u03b9")
/\u1ff6/i.match("\u03c9\u0342") # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
/\u1ff7/i.match("\u03c9\u0342\u03b9") # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
# (omega perispomeni) ypogegrammeni == (omega perispomeni ypogegrammeni)
/\u1ff6\u03b9/i.match("\u1ff7")
# (omega perispomeni ypogegrammeni) == (omega perispomeni) ypogegrammeni
/\u1ff7/i.match("\u1ff6\u03b9")
</code></pre> Ruby master - Bug #17931 (Open): Compile fails setup option nodynamichttps://bugs.ruby-lang.org/issues/179312021-05-31T11:21:13ZTerabin (Allyson Souza Bacon)
<p>I can compile the ruby normally without deselecting the #option nodinamyc and some other extension, but when deselecting I get the following error</p>
<pre><code class="shell syntaxhl" data-language="shell">rbconfig.rb updated
generating enc.mk
making srcs under enc
generating transdb.h
transdb.h updated
compiling C:/ruby-3.0.1/dln.c
dln.c
compiling C:/ruby-3.0.1/localeinit.c
localeinit.c
creating verconf.h
verconf.h updated
compiling C:/ruby-3.0.1/loadpath.c
loadpath.c
builtin_binary.inc updated
compiling C:/ruby-3.0.1/builtin.c
builtin.c
linking static-library x64-vcruntime140-ruby300-static.lib
generating x64-vcruntime140-ruby300.def
linking import-library x64-vcruntime140-ruby300.lib
Criando biblioteca x64-vcruntime140-ruby300.lib e objeto x64-vcruntime140-ruby300.exp
generating makefiles ext/configure-ext.mk
ext/configure-ext.mk updated
configuring fiddle
libffi_version: 3.2.1
generating makefile exts.mk
exts.mk updated
The system cannot find the path specified.
NMAKE : fatal error U1077: <span class="s1">'cd'</span> : código de retorno <span class="s1">'0x1'</span>
Stop.
NMAKE : fatal error U1077: <span class="s1">'"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\nmake.EXE"'</span> : código de retorno <span class="s1">'0x2'</span>
Stop.
C:<span class="se">\r</span>build2>
</code></pre>
<p>I tested at visual studio 2017 and 2019.</p>
<p><strong>How to reproduce</strong></p>
<pre><code class="shell syntaxhl" data-language="shell"><span class="nb">set </span><span class="nv">PATH</span><span class="o">=</span>C:<span class="se">\P</span>rogram Files <span class="o">(</span>x86<span class="o">)</span><span class="se">\M</span>icrosoft Visual Studio<span class="se">\2</span>019<span class="se">\C</span>ommunity<span class="se">\V</span>C<span class="se">\T</span>ools<span class="se">\M</span>SVC<span class="se">\1</span>4.28.29910<span class="se">\b</span><span class="k">in</span><span class="se">\H</span>ostx64<span class="se">\x</span>64<span class="p">;</span>%PATH%
<span class="nb">cd </span>C:<span class="se">\r</span>build_x64
<span class="nb">cd </span>C:<span class="se">\r</span>build2
C:<span class="se">\r</span>uby-3.0.1<span class="se">\w</span>in32<span class="se">\c</span>onfigure.bat <span class="nt">--disable-dln</span> <span class="nt">--with-static-link-ext</span> <span class="nt">--enable-shared</span><span class="o">=</span>no
</code></pre> Ruby master - Bug #17882 (Assigned): bootstraptest/test_ractor.rb:224 segfaults on Cygwinhttps://bugs.ruby-lang.org/issues/178822021-05-22T16:03:35Zxtkoba (Tee KOBAYASHI)
<p>The attached test code is excerpted from <code>bootstraptest/test_ractor.rb:224</code>. This code causes a segmentation fault every time when run on <code>x86_64-cygwin</code>. There are at least 3 types of dying messages, as shown below.</p>
<p>I have no idea whether this is relevant to <a class="issue tracker-1 status-1 priority-4 priority-default" title="Bug: bootstraptest/test_ractor.rb:224 a random failing test with "The outgoing-port is already closed ... (Open)" href="https://bugs.ruby-lang.org/issues/17878">#17878</a>, which is an issue with the very same test code.</p>
<p>Type 1 (null pointer dereference):</p>
<pre><code>Thread 6 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 5368]
VM_CF_BLOCK_HANDLER (cfp=0x0) at ../vm.c:115
115 const VALUE *ep = VM_CF_LEP(cfp);
(gdb) bt
#0 VM_CF_BLOCK_HANDLER (cfp=0x0) at ../vm.c:115
#1 0x00007ff6acedb495 in rb_vm_frame_block_handler (cfp=<optimized out>) at ../vm.c:128
#2 0x00007ff6acdd954e in pass_passed_block_handler (ec=0x80012bba0) at ../eval_intern.h:17
#3 rb_obj_call_init_kw (obj=obj@entry=123145240968920, argc=argc@entry=1, argv=argv@entry=0xffd0ca08, kw_splat=kw_splat@entry=0) at ../eval.c:1724
#4 0x00007ff6ace3efc2 in rb_class_new_instance (argc=argc@entry=1, argv=argv@entry=0xffd0ca08, klass=klass@entry=123145300575160) at ../object.c:2192
#5 0x00007ff6acdd1c30 in rb_exc_new_str (etype=etype@entry=123145300575160, str=<optimized out>) at ../error.c:1123
#6 0x00007ff6acdd29ad in rb_vraise (exc=123145300575160, fmt=<optimized out>, ap=<optimized out>) at ../error.c:2922
#7 0x00007ff6acdd29e5 in rb_raise (exc=0, fmt=0x0) at ../error.c:2930
#8 0x00007ff6acdf90e8 in rb_io_check_initialized (fptr=0x0) at ../io.c:767
#9 rb_io_check_initialized (fptr=<optimized out>) at ../io.c:764
#10 0x00007ff6acdf90fb in rb_io_check_closed (fptr=0x0) at ../io.c:774
#11 0x00007ff6ace011ec in prep_stdio (f=0x18023acb8 <reent_data+1336>, fmode=fmode@entry=1, klass=123145300573360, klass@entry=140697440105184, path=path@entry=0x7ff6acf158e0 <prelude_table+2944> "<STDIN>") at ../io.c:8239
#12 0x00007ff6ace0122f in rb_io_prep_stdin () at ../io.c:8255
#13 0x00007ff6acebc980 in thread_start_func_2 (th=0x0, th@entry=0x80011cbf0, stack_start=stack_start@entry=0xffd0ccf8) at ../thread.c:801
#14 0x00007ff6acebd032 in thread_start_func_1 (th_ptr=<optimized out>) at ../thread_pthread.c:1035
#15 0x000000018016d45f in pthread::thread_init_wrapper(void*) () from target:/usr/bin/cygwin1.dll
#16 0x00000001800ddbba in pthread_wrapper () from target:/usr/bin/cygwin1.dll
#17 0x0000000000000000 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
</code></pre>
<p>Type 2 (<code>rb_gc_mark()</code>: <code><address></code> is <code>T_ZOMBIE</code>):</p>
<pre><code>Thread 7 hit Breakpoint 1, rb_bug (fmt=0x7ff6acf1396a <stat_data_type+8138> "rb_gc_mark(): %p is T_ZOMBIE") at ../error.c:782
782 {
(gdb) bt
#0 rb_bug (fmt=0x7ff6acf1396a <stat_data_type+8138> "rb_gc_mark(): %p is T_ZOMBIE") at ../error.c:782
#1 0x00007ff6acdeae8f in gc_mark_children (objspace=objspace@entry=0x800053970, obj=obj@entry=123145240171400) at ../gc.c:6934
#2 0x00007ff6acdeafb0 in gc_mark_stacked_objects (objspace=0x800053970, incremental=incremental@entry=0, count=count@entry=0) at ../gc.c:6961
#3 0x00007ff6acded415 in gc_mark_stacked_objects_all (objspace=0x800053970) at ../gc.c:7001
#4 gc_marks_rest (objspace=objspace@entry=0x800053970) at ../gc.c:7972
#5 0x00007ff6acdec08c in gc_marks (full_mark=<optimized out>, objspace=0x800053970) at ../gc.c:8028
#6 gc_start (objspace=objspace@entry=0x800053970, reason=<optimized out>, reason@entry=256) at ../gc.c:8862
#7 0x00007ff6acdee522 in heap_prepare (heap=0x800053998, objspace=0x800053970) at ../gc.c:2153
#8 heap_next_freepage (heap=0x800053998, objspace=0x800053970) at ../gc.c:2444
#9 ractor_cache_slots (objspace=objspace@entry=0x800053970, cr=cr@entry=0x800135d60) at ../gc.c:2476
#10 0x00007ff6acdee61a in newobj_slowpath (alloc_size=<optimized out>, wb_protected=0, cr=0x800135d60, objspace=0x800053970, flags=11, klass=123145300573360) at ../gc.c:2517
#11 newobj_slowpath_wb_unprotected (klass=123145300573360, flags=11, objspace=0x800053970, cr=0x800135d60, alloc_size=<optimized out>) at ../gc.c:2547
#12 0x00007ff6acdee815 in newobj_of0 (klass=klass@entry=123145300573360, flags=flags@entry=11, wb_protected=wb_protected@entry=0, cr=<optimized out>, alloc_size=<optimized out>) at ../gc.c:2585
#13 0x00007ff6acdee86d in newobj_of (klass=klass@entry=123145300573360, flags=flags@entry=11, v1=v1@entry=0, v2=v2@entry=0, v3=v3@entry=0, wb_protected=wb_protected@entry=0, alloc_size=40) at ../gc.c:2594
#14 0x00007ff6acdeec23 in rb_wb_unprotected_newobj_of (klass=klass@entry=123145300573360, flags=flags@entry=11, size=40, size@entry=0) at ../gc.c:2610
#15 0x00007ff6acdf666c in io_alloc (klass=klass@entry=123145300573360) at ../io.c:1038
#16 0x00007ff6acdfbca9 in prep_io (fd=2, fmode=fmode@entry=65546, klass=klass@entry=123145300573360, path=path@entry=0x7ff6acf158f1 <prelude_table+2961> "<STDERR>") at ../io.c:8206
#17 0x00007ff6ace011d4 in prep_stdio (f=0x18023ae28 <reent_data+1704>, fmode=fmode@entry=10, klass=123145300573360, klass@entry=34361007456, path=path@entry=0x7ff6acf158f1 <prelude_table+2961> "<STDERR>") at ../io.c:8237
#18 0x00007ff6ace01295 in rb_io_prep_stderr () at ../io.c:8267
#19 0x00007ff6acebc9a6 in thread_start_func_2 (th=0x0, th@entry=0x800134550, stack_start=stack_start@entry=0xffa0ccf8) at ../thread.c:803
#20 0x00007ff6acebd032 in thread_start_func_1 (th_ptr=<optimized out>) at ../thread_pthread.c:1035
#21 0x000000018016d45f in pthread::thread_init_wrapper(void*) () from target:/usr/bin/cygwin1.dll
#22 0x00000001800ddbba in pthread_wrapper () from target:/usr/bin/cygwin1.dll
#23 0x0000000000000000 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
</code></pre>
<p>Type 3 (try to mark <code>T_NONE</code> object):</p>
<pre><code><OBJ_INFO:gc_mark_ptr@../gc.c:6580> 0x00006fffffe7fb70 [0 M ] T_NONE
------------------------------------------------------------------------
Thread 7 hit Breakpoint 1, rb_bug (fmt=fmt@entry=0x7ff6acf138a0 <stat_data_type+7936> "try to mark T_NONE object") at ../error.c:782
782 {
(gdb) bt
#0 rb_bug (fmt=fmt@entry=0x7ff6acf138a0 <stat_data_type+7936> "try to mark T_NONE object") at ../error.c:782
#1 0x00007ff6acdea5c9 in gc_mark_ptr (objspace=0x800053970, obj=123145300736880) at ../gc.c:6581
#2 0x00007ff6ace672ea in ractor_mark (ptr=0x800117240) at ../ractor.c:197
#3 0x00007ff6acdeafb0 in gc_mark_stacked_objects (objspace=objspace@entry=0x800053970, incremental=incremental@entry=1, count=count@entry=2147483647) at ../gc.c:6961
#4 0x00007ff6acded3f9 in gc_mark_stacked_objects_incremental (count=2147483647, objspace=0x800053970) at ../gc.c:6995
#5 gc_marks_rest (objspace=objspace@entry=0x800053970) at ../gc.c:7968
#6 0x00007ff6acdee4f1 in gc_marks_continue (heap=0x800053998, objspace=0x800053970) at ../gc.c:8012
#7 heap_prepare (heap=0x800053998, objspace=0x800053970) at ../gc.c:2148
#8 heap_next_freepage (heap=0x800053998, objspace=0x800053970) at ../gc.c:2444
#9 ractor_cache_slots (objspace=objspace@entry=0x800053970, cr=cr@entry=0x800129350) at ../gc.c:2476
#10 0x00007ff6acdee61a in newobj_slowpath (alloc_size=<optimized out>, wb_protected=0, cr=0x800129350, objspace=0x800053970, flags=11, klass=123145300573360) at ../gc.c:2517
#11 newobj_slowpath_wb_unprotected (klass=123145300573360, flags=11, objspace=0x800053970, cr=0x800129350, alloc_size=<optimized out>) at ../gc.c:2547
#12 0x00007ff6acdee815 in newobj_of0 (klass=klass@entry=123145300573360, flags=flags@entry=11, wb_protected=wb_protected@entry=0, cr=<optimized out>, alloc_size=<optimized out>) at ../gc.c:2585
#13 0x00007ff6acdee86d in newobj_of (klass=klass@entry=123145300573360, flags=flags@entry=11, v1=v1@entry=0, v2=v2@entry=0, v3=v3@entry=0, wb_protected=wb_protected@entry=0, alloc_size=40) at ../gc.c:2594
#14 0x00007ff6acdeec23 in rb_wb_unprotected_newobj_of (klass=klass@entry=123145300573360, flags=flags@entry=11, size=40, size@entry=0) at ../gc.c:2610
#15 0x00007ff6acdf666c in io_alloc (klass=klass@entry=123145300573360) at ../io.c:1038
#16 0x00007ff6acdfbca9 in prep_io (fd=0, fmode=fmode@entry=65537, klass=klass@entry=123145300573360, path=path@entry=0x7ff6acf158e0 <prelude_table+2944> "<STDIN>") at ../io.c:8206
#17 0x00007ff6ace011d4 in prep_stdio (f=0x18023acb8 <reent_data+1336>, fmode=fmode@entry=1, klass=123145300573360, klass@entry=140697440105184, path=path@entry=0x7ff6acf158e0 <prelude_table+2944> "<STDIN>") at ../io.c:8237
#18 0x00007ff6ace0122f in rb_io_prep_stdin () at ../io.c:8255
#19 0x00007ff6acebc980 in thread_start_func_2 (th=0x0, th@entry=0x80010dcb0, stack_start=stack_start@entry=0xffa0ccf8) at ../thread.c:801
#20 0x00007ff6acebd032 in thread_start_func_1 (th_ptr=<optimized out>) at ../thread_pthread.c:1035
#21 0x000000018016d45f in pthread::thread_init_wrapper(void*) () from target:/usr/bin/cygwin1.dll
#22 0x00000001800ddbba in pthread_wrapper () from target:/usr/bin/cygwin1.dll
#23 0x0000000000000000 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
</code></pre> Ruby master - Bug #17878 (Open): bootstraptest/test_ractor.rb:224 a random failing test with "The...https://bugs.ruby-lang.org/issues/178782021-05-21T14:25:41Zjaruga (Jun Aruga)
<p>I was running Travis several times I am trying to revive based on the master commit: <code>50a534a1526e2b9f4ea41e44b802bd73f9cebbeb</code>.<br>
Then I got the following failure on Travis arm64 Ubuntu focal environment. The failure happened for the first time in around 5 times.</p>
<p>Here is the Travis log.<br>
<a href="https://travis-ci.com/github/junaruga/ruby/jobs/506885939#L2227" class="external">https://travis-ci.com/github/junaruga/ruby/jobs/506885939#L2227</a></p>
<pre><code>$ $SETARCH make -s test -o showflags TESTOPTS="${TESTOPTS=-j33 -q --tty=no}"
...
test_ractor.rb ....................Fstderr output is not empty
<internal:ractor>:345:in `select': The outgoing-port is already closed (Ractor::ClosedError)
from bootstraptest.tmp.rb:12:in `block in test'
from bootstraptest.tmp.rb:11:in `times'
from bootstraptest.tmp.rb:11:in `test'
from bootstraptest.tmp.rb:26:in `block in <main>'
from bootstraptest.tmp.rb:25:in `times'
from bootstraptest.tmp.rb:25:in `each'
from bootstraptest.tmp.rb:25:in `map'
from bootstraptest.tmp.rb:25:in `<main>'
</code></pre>
<pre><code>Fiber count: 10000 (skipping)
#1213 test_ractor.rb:224:in `<top (required)>':
def test n
rs = (1..n).map do |i|
Ractor.new(i) do |i|
"r#{i}"
end
end
as = []
all_rs = rs.dup
n.times{
r, obj = Ractor.select(*rs)
as << [r, obj]
rs.delete(r)
}
if as.map{|r, o| r.object_id}.sort == all_rs.map{|r| r.object_id}.sort &&
as.map{|r, o| o}.sort == (1..n).map{|i| "r#{i}"}.sort
'ok'
else
'ng'
end
end
30.times.map{|i|
test i
}
#=> "" (expected "[\"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\", \"ok\"]")
FAIL 1/1488 tests failed
make: *** [uncommon.mk:768: yes-btest-ruby] Error 1
The command "$SETARCH make -s test -o showflags TESTOPTS="${TESTOPTS=$JOBS -q --tty=no}"" exited with 2.
</code></pre> Ruby master - Bug #17792 (Open): make notes and make test fail with Ruby3.0.1p64 RaspberryPI 4B U...https://bugs.ruby-lang.org/issues/177922021-04-10T04:41:08Zhanlyusarang (Hanlyu Sarang)
<p>I am building Ruby 3.01 from sources on a RaspberryPI 4B running Ubuntu 20.10 ARM64.</p>
<p>This is my first day using this PI4B + Ubuntu 20.10 ARM64, and this is the first time I have attempted to build Ruby on it.<br>
I received a few notes during compilation and one failure during testing.</p>
<p>Note that on the previous day, I built the same Ruby sources on the same machine running RaspberryPI OS (32-bit Debian), no problems. FYI, you can use either a 32-bit or a 64-bit OS on the RasberryPI 4B.</p>
<p>Anyway, here are the details of what I experienced on the PI4B using Ubuntu 20.10 ARM64:</p>
<p>During the make, I get a few notes:</p>
<p>compiling parse.c<br>
parse.y: In function ‘node_assign’:<br>
parse.y:11265:1: note: parameter passing for argument of type ‘struct lex_context’ changed in GCC 9.1<br>
11265 | node_assign(struct parser_params *p, NODE *lhs, NODE *rhs, struct lex_context ctxt, const YYLTYPE *loc)<br>
| ^~~~~~~~~~~<br>
parse.y: In function ‘new_const_op_assign’:<br>
parse.y:12283:1: note: parameter passing for argument of type ‘struct lex_context’ changed in GCC 9.1<br>
12283 | new_const_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct lex_context ctxt, const YYLTYPE *loc)<br>
| ^~~~~~~~~~~~~~~~~~~<br>
parse.y: In function ‘new_op_assign’:<br>
parse.y:12196:1: note: parameter passing for argument of type ‘struct lex_context’ changed in GCC 9.1<br>
12196 | new_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct lex_context ctxt, const YYLTYPE *loc)<br>
| ^~~~~~~~~~~~~<br>
compiling proc.c</p>
<p>The build is successful, but when I run make test, I get one failure</p>
<p>/home/pi/builds/ruby-3.0.1# make test<br>
BASERUBY = /usr/bin/ruby --disable=gems<br>
CC = gcc<br>
LD = ld<br>
LDSHARED = gcc -shared<br>
CFLAGS = -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -std=gnu99<br>
XCFLAGS = -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fno-strict-overflow -fvisibility=hidden -fexcess-precision=standard -DRUBY_EXPORT -fPIE -I. -I.ext/include/aarch64-linux -I./include -I. -I./enc/unicode/12.1.0<br>
CPPFLAGS =<br>
DLDFLAGS = -Wl,--compress-debug-sections=zlib -fstack-protector-strong -pie<br>
SOLIBS = -lz -lpthread -lrt -lrt -lgmp -ldl -lcrypt -lm<br>
LANG = en_US.UTF-8<br>
LC_ALL =<br>
LC_CTYPE =<br>
MFLAGS =<br>
gcc (Ubuntu 10.2.0-13ubuntu1) 10.2.0<br>
Copyright (C) 2020 Free Software Foundation, Inc.<br>
This is free software; see the source for copying conditions. There is NO<br>
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p>
<p>./revision.h unchanged<br>
<a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Query part lost when using Net::HTTP.post_form function (Closed)" href="https://bugs.ruby-lang.org/issues/655">#655</a> test_io.rb:87:in `block in <top (required)>':<br>
at_exit { p :foo }</p>
<pre><code> megacontent = "abc" * 12345678
#File.open("megasrc", "w") {|f| f << megacontent }
t0 = Thread.main
Thread.new { sleep 0.001 until t0.stop?; Process.kill(:INT, $$) }
r1, w1 = IO.pipe
r2, w2 = IO.pipe
t1 = Thread.new { w1 << megacontent; w1.close }
t2 = Thread.new { r2.read; r2.close }
IO.copy_stream(r1, w2) rescue nil
w2.close
r1.close
t1.join
t2.join
</code></pre>
<p>#=> killed by SIGKILL (signal 9) (timeout) megacontent-copy_stream<br>
test_io.rb FAIL 1/9<br>
Fiber count: 10000 (skipping)<br>
FAIL 1/1486 tests failed<br>
make: *** [uncommon.mk:766: yes-btest-ruby] Error 1</p>
<p>I went ahead and did the make install, which succeeded.<br>
I now have an installation of Ruby which I will be working with over the next few months to see if it works OK.</p>
<p>If you need more info, please let me know.</p> Ruby master - Bug #17774 (Open): Quantified empty group causes regex to failhttps://bugs.ruby-lang.org/issues/177742021-04-04T08:08:53ZDavidebyzero (David Ellsworth)
<p>The regex <code>^((x*)(?=\2$))*x$</code> matches powers of 2 in unary, expressed as strings of <code>x</code> characters whose length is the number.</p>
<p>Adding an empty group <code>()</code> in the middle of it should have no effect on its operation, and indeed it does not. <code>^((x*)()(?=\2$))*x$</code> still matches powers of 2 just fine.<br>
Quantifying that empty group, <code>(){4}</code>, should still have no effect. And indeed, <code>^((x*)(){4}(?=\2$))*x$</code> still matches powers of 2. But quantify that to <code>(){5}</code>, and suddenly it fails.</p>
<p>The following command line should print <code>1</code>, but instead prints nothing:</p>
<pre><code>ruby -e 'print 1 if "x"*32 =~ /^((x*)(){5}(?=\2$))*x$/'
</code></pre>
<p>However this one does print <code>1</code>:</p>
<pre><code>ruby -e 'print 1 if "x"*32 =~ /^((x*)(){4}(?=\2$))*x$/'
</code></pre>
<p>Bug found to occur on <a href="https://tio.run/" class="external">Try It Online</a>: <code>ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux]</code><br>
Bug confirmed to happen on my own machine: <code>ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-msys]</code></p>
<p>Solving the challenge <a href="https://codegolf.stackexchange.com/questions/211840/is-that-number-a-two-bit-number%ef%b8%8f/222792#222792" class="external">Is that number a Two Bit Number™️?</a> on Code Golf Stack Exchange is what led me to discover this bug.</p> Ruby master - Bug #17678 (Assigned): Ractors do not restart after forkhttps://bugs.ruby-lang.org/issues/176782021-03-08T16:19:45Zivoanjo (Ivo Anjo)ivo.anjo@datadoghq.com
<p>Hello there! I'm working at Datadog on the <code>ddtrace</code> gem -- <a href="https://github.com/DataDog/dd-trace-rb" class="external">https://github.com/DataDog/dd-trace-rb</a> and we're experimenting with using Ractors in our library but run into a few issues.</p>
<a name="Background"></a>
<h3 >Background<a href="#Background" class="wiki-anchor">¶</a></h3>
<p>When running a Ractor as a background process, the Ractor stops & does not restart when the application forks.</p>
<a name="How-to-reproduce-Ruby-version-amp-script"></a>
<h3 >How to reproduce (Ruby version & script)<a href="#How-to-reproduce-Ruby-version-amp-script" class="wiki-anchor">¶</a></h3>
<p><code>ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]</code></p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">r2</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="kp">loop</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s2">"[</span><span class="si">#{</span><span class="no">Process</span><span class="p">.</span><span class="nf">pid</span><span class="si">}</span><span class="s2">] Ractor"</span><span class="p">;</span> <span class="nb">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
<span class="nb">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"[</span><span class="si">#{</span><span class="no">Process</span><span class="p">.</span><span class="nf">pid</span><span class="si">}</span><span class="s2">] Forking..."</span>
<span class="nb">fork</span> <span class="k">do</span>
<span class="nb">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"[</span><span class="si">#{</span><span class="no">Process</span><span class="p">.</span><span class="nf">pid</span><span class="si">}</span><span class="s2">] End fork."</span>
<span class="k">end</span>
<span class="kp">loop</span> <span class="k">do</span>
<span class="nb">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
<a name="Expectation-and-result"></a>
<h3 >Expectation and result<a href="#Expectation-and-result" class="wiki-anchor">¶</a></h3>
<p>The application prints “Ractor” each second in the main process, but not in the fork.</p>
<p>Expected the Ractor (defined as <code>r2</code>) to run in the fork.</p>
<pre><code>[29] Ractor
[29] Ractor
[29] Forking...
[29] Ractor
[29] Ractor
[29] Ractor
[29] Ractor
[29] Ractor
[32] End fork.
[29] Ractor
[29] Ractor
[29] Ractor
</code></pre>
<a name="Additional-notes"></a>
<h3 >Additional notes<a href="#Additional-notes" class="wiki-anchor">¶</a></h3>
<p>Threads do not restart across forks either, so it might not be unreasonable to expect consistent behavior. However, it’s possible to detect a dead Thread and recreate it after a fork (e.g. with <code>#alive?</code>, <code>#status</code>), but there’s no such mechanism for Ractors.</p>
<a name="Suggested-solutions"></a>
<h3 >Suggested solutions<a href="#Suggested-solutions" class="wiki-anchor">¶</a></h3>
<ol>
<li>Auto-restart Ractors after fork</li>
<li>Add additional methods to Ractors that allow users to check & manage the status of the Ractor, similar to Thread.</li>
</ol> Ruby master - Bug #17677 (Assigned): Ractor crashes fork when blockinghttps://bugs.ruby-lang.org/issues/176772021-03-08T16:19:22Zdelner (David Elner)
<a name="Background"></a>
<h2 >Background<a href="#Background" class="wiki-anchor">¶</a></h2>
<p>If you create a Ractor which blocks (e.g. <code>receive</code>), then fork the process, the fork will segfault upon completion.</p>
<a name="How-to-reproduce"></a>
<h2 >How to reproduce<a href="#How-to-reproduce" class="wiki-anchor">¶</a></h2>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">r2</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">receive</span>
<span class="k">end</span>
<span class="nb">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"Forking..."</span>
<span class="nb">fork</span> <span class="k">do</span>
<span class="nb">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"End fork."</span>
<span class="k">end</span>
<span class="kp">loop</span> <span class="k">do</span>
<span class="nb">puts</span> <span class="s2">"Main thread."</span>
<span class="nb">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
<a name="Expectation-and-result"></a>
<h2 >Expectation and result<a href="#Expectation-and-result" class="wiki-anchor">¶</a></h2>
<p>Application prints “Main thread” from main process every second, while fork prints “End fork.” then produces a segfault. Main process continues to run.</p>
<p>Expected fork to not raise a segfault.</p>
<pre><code><internal:ractor>:267: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
Forking...
Main thread.
Main thread.
End fork.
app/sandbox.rb:80: [BUG]: Device or resource busy (EBUSY)
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]
-- Control frame information -----------------------------------------------
c:0003 p:---- s:0011 e:000010 CFUNC :fork
c:0002 p:0048 s:0007 E:001b48 EVAL app/sandbox.rb:80 [FINISH]
c:0001 p:0000 s:0003 E:002590 (none) [FINISH]
-- Ruby level backtrace information ----------------------------------------
app/sandbox.rb:80:in `<main>'
app/sandbox.rb:80:in `fork'
-- C level backtrace information -------------------------------------------
/usr/local/lib/libruby.so.3.0(rb_print_backtrace+0x11) [0x7f9848528cfb] vm_dump.c:758
/usr/local/lib/libruby.so.3.0(rb_vm_bugreport) vm_dump.c:998
/usr/local/lib/libruby.so.3.0(bug_report_end+0x0) [0x7f9848354808] error.c:763
/usr/local/lib/libruby.so.3.0(rb_bug_without_die) error.c:763
/usr/local/lib/libruby.so.3.0(die+0x0) [0x7f98482c6902] error.c:771
/usr/local/lib/libruby.so.3.0(rb_bug) error.c:773
/usr/local/lib/libruby.so.3.0(rb_bug_errno+0x3c) [0x7f9848354a1c] error.c:802
/usr/local/lib/libruby.so.3.0(rb_native_mutex_destroy+0x20) [0x7f98484ce380] thread_pthread.c:444
/usr/local/lib/libruby.so.3.0(rb_native_cond_initialize) (null):0
/usr/local/lib/libruby.so.3.0(ractor_free+0xd) [0x7f984844487d] ractor.c:229
/usr/local/lib/libruby.so.3.0(run_final+0xb) [0x7f9848371c66] gc.c:3670
/usr/local/lib/libruby.so.3.0(finalize_list) gc.c:3689
/usr/local/lib/libruby.so.3.0(rb_objspace_call_finalizer+0x33d) [0x7f984837cc5d] gc.c:3852
/usr/local/lib/libruby.so.3.0(rb_ec_cleanup+0x311) [0x7f984835f0b1] eval.c:184
/usr/local/lib/libruby.so.3.0(ruby_stop+0x9) [0x7f984835f339] eval.c:329
/usr/local/lib/libruby.so.3.0(rb_f_fork+0x1f) [0x7f98484402f8] process.c:4348
/usr/local/lib/libruby.so.3.0(rb_f_fork) process.c:4338
/usr/local/lib/libruby.so.3.0(vm_call_cfunc_with_frame+0x11b) [0x7f984850672b] vm_insnhelper.c:2898
/usr/local/lib/libruby.so.3.0(vm_call_method_each_type+0xf9) [0x7f98485192c9] vm_insnhelper.c:3388
/usr/local/lib/libruby.so.3.0(vm_call_method+0xb4) [0x7f9848519b24] vm_insnhelper.c:3506
/usr/local/lib/libruby.so.3.0(vm_sendish+0xb3) [0x7f984850a3d3] vm_insnhelper.c:4499
/usr/local/lib/libruby.so.3.0(vm_exec_core+0x140) [0x7f98485123e0] insns.def:770
/usr/local/lib/libruby.so.3.0(rb_vm_exec+0x176) [0x7f9848517b26] vm.c:2163
/usr/local/lib/libruby.so.3.0(rb_ec_exec_node+0xd9) [0x7f9848359719] eval.c:317
/usr/local/lib/libruby.so.3.0(ruby_run_node+0x55) [0x7f984835f395] eval.c:375
/usr/local/bin/ruby(main+0x5b) [0x565147e5410b] ./main.c:50
...
Main thread.
Main thread.
Main thread.
</code></pre>
<a name="Additional-notes"></a>
<h2 >Additional notes<a href="#Additional-notes" class="wiki-anchor">¶</a></h2>
<p>This does not happen if a blocking operation does not occur in the Ractor. E.g.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">r2</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="kp">loop</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s2">"[</span><span class="si">#{</span><span class="no">Process</span><span class="p">.</span><span class="nf">pid</span><span class="si">}</span><span class="s2">] Ractor"</span><span class="p">;</span> <span class="nb">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
</code></pre>
<p>Segfault can also be prevented by invoking <code>close_incoming</code> prior to forking, although this raises another error internally.</p>
<p>It also does not crash on MacOS 10.15.7: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19].</p>
<a name="Suggested-solutions"></a>
<h2 >Suggested solutions<a href="#Suggested-solutions" class="wiki-anchor">¶</a></h2>
<p>(None)</p> Ruby master - Bug #17578 (Assigned): mkmf experimental C++ Supporthttps://bugs.ruby-lang.org/issues/175782021-01-25T06:26:31Zcfis (Charlie Savage)
<p>I've been working on the Rice gem (<a href="https://github.com/jasonroelofs/rice" class="external">https://github.com/jasonroelofs/rice</a>) that wraps C++ code for use in Ruby.</p>
<p>I noticed that some c++ support was added to mkmf for Ruby 2.7. However, if I try to use it find a header it fails to work. For example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">find_header</span><span class="p">(</span><span class="s1">'rice.hpp'</span><span class="p">)</span>
</code></pre>
<p>The reason is the conftest uses gcc -E instead of g++ -E. To fix that requires overlading the cpp_command to support C++.</p>
<p>This the fix I have put in that works:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">MakeMakefile</span><span class="p">[</span><span class="s1">'C++'</span><span class="p">].</span><span class="nf">module_eval</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">cpp_command</span><span class="p">(</span><span class="n">outfile</span><span class="p">,</span> <span class="n">opt</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span>
<span class="n">conf</span> <span class="o">=</span> <span class="n">cc_config</span><span class="p">(</span><span class="n">opt</span><span class="p">)</span>
<span class="k">if</span> <span class="vg">$universal</span> <span class="ow">and</span> <span class="p">(</span><span class="n">arch_flag</span> <span class="o">=</span> <span class="n">conf</span><span class="p">[</span><span class="s1">'ARCH_FLAG'</span><span class="p">])</span> <span class="ow">and</span> <span class="o">!</span><span class="n">arch_flag</span><span class="p">.</span><span class="nf">empty?</span>
<span class="n">conf</span><span class="p">[</span><span class="s1">'ARCH_FLAG'</span><span class="p">]</span> <span class="o">=</span> <span class="n">arch_flag</span><span class="p">.</span><span class="nf">gsub</span><span class="p">(</span><span class="sr">/(?:\G|\s)-arch\s+\S+/</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
<span class="k">end</span>
<span class="no">RbConfig</span><span class="o">::</span><span class="n">expand</span><span class="p">(</span><span class="s2">"$(CXX) -E </span><span class="si">#$INCFLAGS</span><span class="s2"> </span><span class="si">#$CPPFLAGS</span><span class="s2"> </span><span class="si">#$CFLAGS</span><span class="s2"> </span><span class="si">#{</span><span class="n">opt</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="no">CONFTEST_CXX</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">outfile</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
<span class="n">conf</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>The two changes over the default method are:</p>
<p>$(CC) -> $(CXX) -E<br>
#{CONFTEST_c} -> #{CONFTEST_cxx}</p>
<p>Could this change be merged in? I can provide a patch file if you would like.</p>
<p>Last, it wasn't obvious to me how to activate the C++ support in mkfm. I ended up doing this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="kp">include</span> <span class="no">MakeMakefile</span><span class="p">[</span><span class="s1">'C++'</span><span class="p">]</span>
</code></pre>
<p>Is that correct?</p> Ruby master - Bug #17516 (Assigned): forking in a ractor causes Ruby to crashhttps://bugs.ruby-lang.org/issues/175162021-01-06T10:56:50Zpkmuldoon (Phil Muldoon)
<p>I just want to point out, there's absolutely no reason to do this, but</p>
<p>r = Ractor.new do<br>
Process.fork()<br>
end</p>
<p>Will cause:</p>
<p><a href="internal:ractor" class="external">internal:ractor</a>:267: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.<br>
[BUG] rb_thread_terminate_all: called by child thread (0x0000700004ddca40, 0x00007f981b567ee0)<br>
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin20]</p>
<p>-- Crash Report log information --------------------------------------------<br>
See Crash Report log file under the one of following:<br>
* ~/Library/Logs/DiagnosticReports<br>
* /Library/Logs/DiagnosticReports<br>
for more details.<br>
Don't forget to include the above Crash Report log file in bug reports.</p>
<p>-- Control frame information -----------------------------------------------<br>
c:0001 p:---- s:0003 e:000002 (none) [FINISH]</p>
<p>-- C level backtrace information -------------------------------------------<br>
=> #<Ractor:#3 (pry):5 terminated><br>
[4] pry(main)> /Users/phillipmuldoon/.rubies/ruby-3.0.0/bin/ruby(rb_vm_bugreport+0x6cf) [0x103084d1f]<br>
/Users/phillipmuldoon/.rubies/ruby-3.0.0/bin/ruby(rb_bug_without_die+0x206) [0x102e9e2b6]<br>
/Users/phillipmuldoon/.rubies/ruby-3.0.0/bin/ruby(rb_bug+0x71) [0x103091e6b]<br>
/Users/phillipmuldoon/.rubies/ruby-3.0.0/bin/ruby(rb_thread_terminate_all+0x329) [0x10301e5b9]<br>
/Users/phillipmuldoon/.rubies/ruby-3.0.0/bin/ruby(rb_ractor_terminate_all+0xa3) [0x102f8acc3]<br>
/Users/phillipmuldoon/.rubies/ruby-3.0.0/bin/ruby(rb_ec_cleanup+0x229) [0x102ea9299]<br>
/Users/phillipmuldoon/.rubies/ruby-3.0.0/bin/ruby(ruby_stop+0x9) [0x102ea9509]<br>
/Users/phillipmuldoon/.rubies/ruby-3.0.0/bin/ruby(thread_start_func_2+0x8ce) [0x103027fce]<br>
/Users/phillipmuldoon/.rubies/ruby-3.0.0/bin/ruby(thread_start_func_1+0x10d) [0x10302753d]<br>
/usr/lib/system/libsystem_pthread.dylib(_pthread_start+0xe0) [0x7fff20382950]</p> Ruby master - Bug #17506 (Open): Ractor isolation broken by ThreadGrouphttps://bugs.ruby-lang.org/issues/175062021-01-03T20:05:43Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>Ractors currently share the ThreadGroup.</p>
<p>This doesn't seem very useful as there is no possible communication between the Threads of different Ractors.</p>
<p>It is also an isolation error:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">ThreadGroup</span><span class="p">.</span><span class="nf">attr_accessor</span> <span class="ss">:foo</span>
<span class="n">var</span> <span class="o">=</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">group</span><span class="p">.</span><span class="nf">foo</span> <span class="o">=</span> <span class="p">[</span><span class="ss">:example</span><span class="p">]</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">group</span><span class="p">.</span><span class="nf">foo</span> <span class="o"><<</span> <span class="p">[</span><span class="ss">:oops</span><span class="p">]</span> <span class="p">}.</span><span class="nf">take</span>
<span class="n">var</span> <span class="c1"># => [:example, [:oops]]</span>
</code></pre>
<p>Should <code>Ractor.new</code> create a new <code>ThreadGroup</code>? Should <code>ThreadGroup</code> not have (non-shareable) instance variables? Or should <code>Ractor.new { Thread.current.group }.take</code> be <code>nil</code>? See also <a href="https://bugs.ruby-lang.org/issues/17505" class="external">https://bugs.ruby-lang.org/issues/17505</a> about <code>nil</code>.</p>
<p>Note that <code>Ractor</code> respects the <code>ThreadGroup</code>'s state:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Thread</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">group</span><span class="p">.</span><span class="nf">enclose</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">group</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="no">Thread</span><span class="p">.</span><span class="nf">current</span><span class="p">)</span> <span class="p">}.</span><span class="nf">take</span> <span class="c1"># => can't move to the enclosed thread group</span>
<span class="no">Thread</span><span class="p">.</span><span class="nf">current</span><span class="p">.</span><span class="nf">group</span><span class="p">.</span><span class="nf">freeze</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="p">{}</span> <span class="c1"># => ThreadError (can't start a new thread (frozen ThreadGroup))</span>
</code></pre>
<p>I am not sure what is the best behavior as I don't have enough experience with how ThreadGroups are used, especially enclosed ThreadGroups.</p> Ruby master - Bug #17359 (Open): Ractor copy mode is not Ractor-safehttps://bugs.ruby-lang.org/issues/173592020-12-01T08:29:37Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>It should not be possible to mutate an object across Ractors, but the copy mode allows it currently:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Foo</span>
<span class="nb">attr_accessor</span> <span class="ss">:x</span>
<span class="k">def</span> <span class="nf">initialize_copy</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
<span class="vg">$last</span> <span class="o">=</span> <span class="nb">self</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">o</span> <span class="o">=</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span>
<span class="n">o</span><span class="p">.</span><span class="nf">x</span> <span class="o">=</span> <span class="mi">42</span>
<span class="n">r</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">o</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">copy</span><span class="o">|</span>
<span class="nb">puts</span> <span class="n">copy</span><span class="p">.</span><span class="nf">x</span> <span class="c1"># => 42</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">yield</span> <span class="ss">:sync</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">yield</span> <span class="ss">:sync</span>
<span class="nb">puts</span> <span class="n">copy</span><span class="p">.</span><span class="nf">x</span> <span class="c1"># => 666</span>
<span class="k">end</span>
<span class="n">r</span><span class="p">.</span><span class="nf">take</span> <span class="c1"># => :sync</span>
<span class="vg">$last</span><span class="p">.</span><span class="nf">x</span> <span class="o">=</span> <span class="mi">666</span>
<span class="n">r</span><span class="p">.</span><span class="nf">take</span> <span class="c1"># => :sync</span>
<span class="n">r</span><span class="p">.</span><span class="nf">take</span>
</code></pre>
<p>Maybe the <code>copy</code> object should be marked as moved?</p> Ruby master - Bug #17142 (Open): Ruby fails to build in AIX https://bugs.ruby-lang.org/issues/171422020-09-02T14:05:19ZAyappan (Ayappan Perumal)
<p>Ruby fails to build in AIX in 64bit mode.</p>
<p>This commit <a href="https://github.com/ruby/ruby/commit/f47c38245ff6976c5d1fc27a79f239bba00fc333" class="external">https://github.com/ruby/ruby/commit/f47c38245ff6976c5d1fc27a79f239bba00fc333</a> essentially broke the 64bit build.</p>
<p>The asm code is not applicable for AIX it seems. Probably we need to add a !defined(_AIX) check on this.</p> Ruby master - Bug #16997 (Open): IO#gets converts some \r\n to \n with universal_newline: falsehttps://bugs.ruby-lang.org/issues/169972020-06-27T21:26:48Zscivola20 (sciv ola)
<p>Reproduction code:</p>
<pre><code>IO.binwrite "t.csv", ("a" * 100 + "\r\n") * 100
File.open("t.csv", encoding: "BOM|UTF-8", universal_newline: false) do |input|
p input.gets(nil, 32 * 1024) # => "a...a\n...\na...a\r\n...\r\n"
end
</code></pre>
<p>It causes MalformedCSVError at opening CSV file with `encoding: "BOM|UTF-8":<br>
<a href="https://github.com/ruby/csv/issues/147" class="external">https://github.com/ruby/csv/issues/147</a></p> Ruby master - Bug #16905 (Open): Ruby required to build Ruby on Haiku?https://bugs.ruby-lang.org/issues/169052020-05-20T17:55:21Zextrowerk (Zoltán Mizsei)
<p>Building Ruby on Haiku results in the following error:</p>
<pre><code>executable host ruby is required. use --with-baseruby option.
</code></pre>
<p>Build environment:</p>
<pre><code>~> uname -a
Haiku shredder 1 hrev54197 May 14 2020 06:44:52 x86_64 x86_64 Haiku
</code></pre>
<p>Current recipe and patch set:<br>
<a href="https://github.com/extrowerk/haikuports/tree/ruby_2.7.1/dev-lang/ruby" class="external">https://github.com/extrowerk/haikuports/tree/ruby_2.7.1/dev-lang/ruby</a></p> Ruby master - Bug #16819 (Assigned): Line reporting off by one when reporting line of a hash?https://bugs.ruby-lang.org/issues/168192020-04-27T18:18:58Zenebo (Thomas Enebo)tom.enebo@gmail.com
<p>If I run this program:</p>
<pre><code>TracePoint.new(:line) { |t| p t.lineno}.enable
def foo(a, b) # 2
a + b # 3
end # 4
# 5
foo 1, 2 # 6
# 7
A = { # 8
a: 1, # 9
b: 2 # 10
} # 11
</code></pre>
<p>I see:</p>
<pre><code>system ~/work/jruby no_sourceposition * 2388% mri26 ../snippets/ast1.rb
2
6
3
9
</code></pre>
<p>I believe this 9 should be an 8 (it is what we currently emit for JRuby). I tried to figure out why this is the case and I patched RubyVM::AbstractSyntaxTree with the ability to note newline flag:</p>
<pre><code>diff --git a/ast.c b/ast.c
index f0e8dd2eaf..df58006a96 100644
--- a/ast.c
+++ b/ast.c
@@ -7,6 +7,8 @@
#include "vm_core.h"
#include "iseq.h"
+#define RBOOL(v) ((v) ? Qtrue : Qfalse)
+
static VALUE rb_mAST;
static VALUE rb_cNode;
@@ -731,6 +733,16 @@ rb_ast_node_inspect(VALUE self)
return str;
}
+static VALUE
+rb_ast_node_newline(VALUE self)
+{
+ struct ASTNodeData *data;
+ TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
+
+ return RBOOL(data->node->flags & NODE_FL_NEWLINE);
+}
+
+
void
Init_ast(void)
{
@@ -756,5 +768,6 @@ Init_ast(void)
rb_define_method(rb_cNode, "last_lineno", rb_ast_node_last_lineno, 0);
rb_define_method(rb_cNode, "last_column", rb_ast_node_last_column, 0);
rb_define_method(rb_cNode, "children", rb_ast_node_children, 0);
+ rb_define_method(rb_cNode, "newline?", rb_ast_node_newline, 0);
rb_define_method(rb_cNode, "inspect", rb_ast_node_inspect, 0);
}
</code></pre>
<p>I also made a simple script:</p>
<pre><code>source = File.read ARGV.shift
root = RubyVM::AbstractSyntaxTree.parse source
def print_node(node, indent = "")
if node.respond_to? :first_lineno
eol = node.newline? ? " <-- newline" : ""
$stdout.write "#{indent}(#{node.type}@#{node.first_lineno-1}-#{node.last_lineno-1})"
case node.type
when :LIT, :STR
puts " = #{node.children[0].inspect}#{eol}"
when :ARRAY
puts eol
node.children[0..-2].each do |child|
print_node(child, indent + " ")
end
when :FCALL
puts " = #{node.children[0]}#{eol}"
node.children[1..-1].each do |child|
print_node(child, indent + " ")
end
else
puts eol
node.children.each do |child|
print_node(child, indent + " ")
end
end
elsif node.nil?
puts "#{indent}nil"
else
puts "#{indent}#{node.inspect}"
end
end
print_node root
puts RubyVM::InstructionSequence.compile(source).disasm
</code></pre>
<p>If I run this I see MRI has line 8 marked as the newline (which JRuby also matches) but if we look at the disasm it would appear compile.c decided to put the line in a different location:</p>
<pre><code>../ruby/ruby --disable-gems ../snippets/ast_mri.rb ../snippets/ast1.rb
(SCOPE@0-10)
[]
nil
(BLOCK@0-10)
(CALL@0-0) <-- newline
(ITER@0-0)
(CALL@0-0)
(CONST@0-0)
:TracePoint
:new
(ARRAY@0-0)
(LIT@0-0) = :line
(SCOPE@0-0)
[:t]
(ARGS@0-0)
1
nil
nil
nil
0
nil
nil
nil
nil
nil
(FCALL@0-0) = p <-- newline
(ARRAY@0-0)
(CALL@0-0)
(DVAR@0-0)
:t
:lineno
nil
:enable
nil
(DEFN@1-3) <-- newline
:foo
(SCOPE@1-3)
[:a, :b]
(ARGS@1-1)
2
nil
nil
nil
0
nil
nil
nil
nil
nil
(OPCALL@2-2) <-- newline
(LVAR@2-2)
:a
:+
(ARRAY@2-2)
(LVAR@2-2)
:b
(FCALL@5-5) = foo <-- newline
(ARRAY@5-5)
(LIT@5-5) = 1
(LIT@5-5) = 2
(CDECL@7-10) <-- newline
:A
(HASH@7-10)
(ARRAY@8-9)
(LIT@8-8) = :a
(LIT@8-8) = 1
(LIT@9-9) = :b
(LIT@9-9) = 2
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(11,18)> (catch: FALSE)
== catch table
| catch type: break st: 0000 ed: 0013 sp: 0000 cont: 0013
| == disasm: #<ISeq:block in <compiled>@<compiled>:1 (1,22)-(1,39)> (catch: FALSE)
| == catch table
| | catch type: redo st: 0001 ed: 0010 sp: 0000 cont: 0001
| | catch type: next st: 0001 ed: 0010 sp: 0000 cont: 0010
| |------------------------------------------------------------------------
| local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
| [ 1] t@0<Arg>
| 0000 nop ( 1)[Bc]
| 0001 putself [Li]
| 0002 getlocal_WC_0 t@0
| 0004 opt_send_without_block <callinfo!mid:lineno, argc:0, ARGS_SIMPLE>, <callcache>
| 0007 opt_send_without_block <callinfo!mid:p, argc:1, FCALL|ARGS_SIMPLE>, <callcache>
| 0010 nop
| 0011 leave ( 1)[Br]
|------------------------------------------------------------------------
0000 opt_getinlinecache 7, <is:0> ( 1)[Li]
0003 getconstant :TracePoint
0005 opt_setinlinecache <is:0>
0007 putobject :line
0009 send <callinfo!mid:new, argc:1>, <callcache>, block in <compiled>
0013 nop
0014 opt_send_without_block <callinfo!mid:enable, argc:0, ARGS_SIMPLE>, <callcache>( 1)
0017 pop
0018 putspecialobject 1 ( 2)[Li]
0020 putobject :foo
0022 putiseq foo
0024 opt_send_without_block <callinfo!mid:core#define_method, argc:2, ARGS_SIMPLE>, <callcache>
0027 pop
0028 putself ( 6)[Li]
0029 putobject_INT2FIX_1_
0030 putobject 2
0032 opt_send_without_block <callinfo!mid:foo, argc:2, FCALL|ARGS_SIMPLE>, <callcache>
0035 pop
0036 duphash {:a=>1, :b=>2} ( 9)[Li]
0038 dup ( 8)
0039 putspecialobject 3
0041 setconstant :A
0043 leave
== disasm: #<ISeq:foo@<compiled>:2 (2,0)-(4,3)> (catch: FALSE)
local table (size: 2, argc: 2 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 2] a@0<Arg> [ 1] b@1<Arg>
0000 getlocal_WC_0 a@0 ( 3)[LiCa]
0002 getlocal_WC_0 b@1
0004 opt_plus <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache>
0007 leave ( 4)[Re]
</code></pre> Ruby master - Bug #16776 (Assigned): Regression in coverage libraryhttps://bugs.ruby-lang.org/issues/167762020-04-10T16:39:29Zdeivid (David Rodríguez)
<p>Hi!</p>
<p>I noticed a regression in the coverage library. I tried to write a minimal program to show it, hopefully it gives some clues or where the issue might lie.</p>
<p>In ruby 2.5.8 and earlier, the following program would print <code>{:lines=>[1, 1, nil]}</code>, showing that the body of the "foo" method was run once. However, on newer rubies, it prints <code>{:lines=>[1, 0, nil]}</code>, which is incorrect because the "foo" method body has actually been run once.</p>
<p>This is the repro script:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># frozen_string_literal: true</span>
<span class="nb">require</span> <span class="s2">"coverage"</span>
<span class="no">Coverage</span><span class="p">.</span><span class="nf">start</span><span class="p">(</span><span class="ss">lines: </span><span class="kp">true</span><span class="p">)</span>
<span class="n">code</span> <span class="o">=</span> <span class="o"><<~</span><span class="no">RUBY</span><span class="sh">
def foo
"LOL"
end
</span><span class="no">RUBY</span>
<span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s2">"foo.rb"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">code</span><span class="p">)</span> <span class="p">}</span>
<span class="nb">require_relative</span> <span class="s2">"foo"</span>
<span class="no">TracePoint</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:line</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">_tp</span><span class="o">|</span>
<span class="n">foo</span>
<span class="k">end</span><span class="p">.</span><span class="nf">enable</span> <span class="k">do</span>
<span class="nb">sleep</span> <span class="mi">0</span>
<span class="k">end</span>
<span class="n">res</span> <span class="o">=</span> <span class="no">Coverage</span><span class="p">.</span><span class="nf">result</span>
<span class="nb">puts</span> <span class="n">res</span><span class="p">[</span><span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s2">"foo.rb"</span><span class="p">)]</span>
</code></pre> Ruby master - Bug #16497 (Assigned): StringIO#internal_encoding is broken (more severely in 2.7)https://bugs.ruby-lang.org/issues/164972020-01-10T11:18:31Zzverok (Victor Shepelev)zverok.offline@gmail.com
<p>To the best of my understanding from <a href="https://docs.ruby-lang.org/en/master/Encoding.html" class="external">Encoding</a> docs, the following is true:</p>
<ul>
<li>external encoding (explicitly specified or taken from <code>Encoding.default_external</code>) specifies how the IO understands input and stores it internally</li>
<li>internal encoding (explicitly specified or taken from <code>Encoding.default_internal</code>) specifies how the IO converts what it reads.</li>
</ul>
<p>Demonstration with regular files:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># prepare data</span>
<span class="no">File</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="s1">'test.txt'</span><span class="p">,</span> <span class="s1">'Україна'</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">),</span> <span class="ss">encoding: </span><span class="s1">'KOI8-U'</span><span class="p">)</span> <span class="c1">#=> 7</span>
<span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">io</span><span class="p">)</span>
<span class="n">str</span> <span class="o">=</span> <span class="n">io</span><span class="p">.</span><span class="nf">read</span>
<span class="p">[</span><span class="n">io</span><span class="p">.</span><span class="nf">external_encoding</span><span class="p">,</span> <span class="n">io</span><span class="p">.</span><span class="nf">internal_encoding</span><span class="p">,</span> <span class="n">str</span><span class="p">,</span> <span class="n">str</span><span class="p">.</span><span class="nf">encoding</span><span class="p">]</span>
<span class="k">end</span>
<span class="c1"># read it:</span>
<span class="nb">test</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s1">'test.txt'</span><span class="p">,</span> <span class="s1">'r:KOI8-U'</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># We can specify internal encoding when opening the file:</span>
<span class="nb">test</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s1">'test.txt'</span><span class="p">,</span> <span class="s1">'r:KOI8-U:UTF-8'</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, #<Encoding:UTF-8>, "Україна", #<Encoding:UTF-8>]</span>
<span class="c1"># ...or when it is already opened</span>
<span class="nb">test</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s1">'test.txt'</span><span class="p">).</span><span class="nf">tap</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">set_encoding</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">,</span> <span class="s1">'UTF-8'</span><span class="p">)</span> <span class="p">})</span>
<span class="c1"># => [#<Encoding:KOI8-U>, #<Encoding:UTF-8>, "Україна", #<Encoding:UTF-8>]</span>
<span class="c1"># ...or with Encoding.default_internal</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="s1">'UTF-8'</span>
<span class="nb">test</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s1">'test.txt'</span><span class="p">,</span> <span class="s1">'r:KOI8-U'</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, #<Encoding:UTF-8>, "Україна", #<Encoding:UTF-8>]</span>
</code></pre>
<p>But with StringIO, <strong>internal encoding can't be set</strong> in Ruby <strong>2.6</strong>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'stringio'</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">str</span> <span class="o">=</span> <span class="s1">'Україна'</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">)</span>
<span class="c1"># Simplest form:</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># Try to set via mode</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="s1">'r:KOI8-U:UTF-8'</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># Try to set via set_encoding:</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="s1">'r:KOI8-U:UTF-8'</span><span class="p">).</span><span class="nf">tap</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">set_encoding</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">,</span> <span class="s1">'UTF-8'</span><span class="p">)</span> <span class="p">})</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># Try to set via Enoding.default_internal:</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="s1">'UTF-8'</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
</code></pre>
<p>So, in 2.6, any attempt to do something with StringIO's internal encoding are <strong>just ignored</strong>.</p>
<p>In <strong>2.7</strong>, though, matters became much worse:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'stringio'</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">str</span> <span class="o">=</span> <span class="s1">'Україна'</span><span class="p">.</span><span class="nf">encode</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">)</span>
<span class="c1"># Behaves same as 2.6</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># Try to set via mode: WEIRD behavior starts</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="s1">'r:KOI8-U:UTF-8'</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:UTF-8>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:UTF-8>]</span>
<span class="c1"># Try to set via set_encoding: still just ignored</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="s1">'r:KOI8-U:UTF-8'</span><span class="p">).</span><span class="nf">tap</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">set_encoding</span><span class="p">(</span><span class="s1">'KOI8-U'</span><span class="p">,</span> <span class="s1">'UTF-8'</span><span class="p">)</span> <span class="p">})</span>
<span class="c1"># => [#<Encoding:KOI8-U>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:KOI8-U>]</span>
<span class="c1"># Try to set via Enoding.default_internal: WEIRD behavior again</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="s1">'UTF-8'</span>
<span class="nb">test</span><span class="p">(</span><span class="no">StringIO</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">str</span><span class="p">))</span>
<span class="c1"># => [#<Encoding:UTF-8>, nil, "\xF5\xCB\xD2\xC1\xA7\xCE\xC1", #<Encoding:UTF-8>]</span>
</code></pre>
<p>So, <strong>2.7</strong> not just ignores attempts to set <strong>internal</strong> encoding, but erroneously sets it to <strong>external</strong> one, so strings are not recoded, but their encoding is forced to change.</p>
<p>I believe it is severe bug (more severe than 2.6's "just ignoring").</p>
<p><a href="https://www.reddit.com/r/ruby/comments/emd6q4/is_this_a_stringio_bug_in_ruby_270/" class="external">This Reddit thread</a> shows how it breaks existing code:</p>
<ul>
<li>the author uses <code>StringIO</code> to work with <code>ASCII-8BIT</code> strings;</li>
<li>the code is performed in Rails environment (which sets <code>internal_encoding</code> to <code>UTF-8</code> by default);</li>
<li>under <strong>2.7</strong>, <code>StringIO#read</code> returns <code>ASCII-8BIT</code> content in Strings saying their encoding is <code>UTF-8</code>.</li>
</ul> Ruby master - Bug #16158 (Open): "st" Character Sequence In Regex Look-Behind Causes Illegal Patt...https://bugs.ruby-lang.org/issues/161582019-09-09T15:14:59Zmichaeltomko (Michael Tomko)
<p><em>This is my first Ruby bug submission. Please let me know if there is anything else that I can provide that would be helpful. Thanks for your time!</em></p>
<p>I've tried just about as many combinations as I can think of and I have been able to narrow down the issue to the following components being present in a regular expression.</p>
<ul>
<li>The character sequence "st" either preceded by any characters OR being a part of a top-level alternation inside of a look-behind. The issue occurs with both positive and negative look-behinds. ex: <code>(?<!Costa)</code> or <code>(?<!Bob|Sally|Stan)</code> or <code>(?<= st)</code>
</li>
<li>Case insensitivity either being set globally or inside of the regex with <code>(?i)</code> preceding the look-behind.</li>
<li>Any curly-style POSIX bracket expression included anywhere in the regex. ex: <code>\p{Space}</code> or <code>\p{L}</code>
</li>
</ul>
<p>Here are some examples of the error. I have tested this on 2.5.0 locally and [on 2.5.3 with Rubular] (<a href="https://rubular.com/r/jnr98E9JfAZJIQ" class="external">https://rubular.com/r/jnr98E9JfAZJIQ</a>).</p>
<pre><code>2.5.0 :044 > pat = /(?<!a st)\p{Space}/i
Traceback (most recent call last):
SyntaxError ((irb):44: invalid pattern in look-behind: /(?<!a st)\p{Space}/i)
2.5.0 :047 > pat = /(?i)(?<!a st)\p{Space}/
Traceback (most recent call last):
SyntaxError ((irb):47: invalid pattern in look-behind: /(?i)(?<!a st)\p{Space}/)
2.5.0 :016 > pat = /(?<!Costa)Mesa(\p{Space}|\p{Punct})+(AZ|Arizona)/i
Traceback (most recent call last):
SyntaxError ((irb):16: invalid pattern in look-behind: /(?<=Costa)Mesa(\p{Space}|\p{Punct})+(AZ|Arizona)/i)
</code></pre>
<p>My expectation would be that this regular expression would compile as written, as it does in JRuby and in MacOS regex testing apps like Patterns or Reggy.</p>
<p>It does compile as expected if the case insensitivity flag is removed or instantiated after the look-behind, if the "st" character sequence is first in the look-behind and not apart of an alternation, or if different types of operators are substituted for the POSIX bracket expressions.</p>
<pre><code>2.5.0 :007 > pat = /((?<!Cosa)Mesa|Arlington(?=([:space:]|[:punct:])+(AZ|Arizona)))/
=> /((?<!Cosa)Mesa|Arlington(?=(\p{Space}|\p{Punct})+(AZ|Arizona)))/
2.5.0 :008 > pat = /((?<!Cosa)Mesa|Arlington(?=([:space:]|[:punct:])+(AZ|Arizona)))/i
=> /((?<!Cosa)Mesa|Arlington(?=([:space:]|[:punct:])+(AZ|Arizona)))/i
2.5.0 :009 > pat = /((?<!Cosa)Mesa|Arlington(?=([:space:]|[:punct:])+(AZ|Arizona)))/i
=> /((?<!Cosa)Mesa|Arlington(?=(\s|\W)+(AZ|Arizona)))/i
2.5.0 :056 > pat = /(?<!a st)(?i)(?<!juice)\p{Space}/
=> /(?<!a st)(?i)(?<!juice)\p{Space}/
2.5.0 :058 > pat = /(?<!a st)(?i)(?<!stark)\p{Space}/
=> /(?<!a st)(?i)(?<!stark)\p{Space}/
</code></pre> Ruby master - Bug #15993 (Open): 'require' doesn't work if there are Cyrillic chars in the path t...https://bugs.ruby-lang.org/issues/159932019-07-10T19:41:05Zinversion (Yura Babak)
<p>I’m trying to build a cross-platform portable application with Ruby onboard and there is a problem on Windows.<br>
A user usually installs it to the Roaming folder which sits inside a user folder which can often have not a Latin name or contain spaces).<br>
When there is a Cyrillic character (maybe just not Latin) in the path — require of any gem doesn’t work:</p>
<pre><code>D:\users\киї\Ruby\2.6\bin>ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x64-mingw32]
D:\users\киї\Ruby\2.6\bin>ruby -e "require 'logger'"
Traceback (most recent call last):
1: from <internal:gem_prelude>:2:in `<internal:gem_prelude>'
<internal:gem_prelude>:2:in `require': No such file or directory -- D:/users/РєРёС—/Ruby/2.6/lib/ruby/2.6.0/rubygems.rb (LoadError)
D:\users\киї\Ruby\2.6\bin>ruby --disable=rubyopt -e "require 'logger'"
Traceback (most recent call last):
1: from <internal:gem_prelude>:2:in `<internal:gem_prelude>'
<internal:gem_prelude>:2:in `require': No such file or directory -- D:/users/РєРёС—/Ruby/2.6/lib/ruby/2.6.0/rubygems.rb (LoadError)
D:\users\киї\Ruby\2.6\bin>gem list
Traceback (most recent call last):
1: from <internal:gem_prelude>:2:in `<internal:gem_prelude>'
<internal:gem_prelude>:2:in `require': No such file or directory -- D:/users/РєРёС—/Ruby/2.6/lib/ruby/2.6.0/rubygems.rb (LoadError)
</code></pre>
<p>We can see such encoding transformations in the output:</p>
<pre><code>киї (utf-8) == РєРёС— (win1251)
</code></pre>
<p>I have an old Ruby installation that works fine:</p>
<pre><code>D:\users\киї\Ruby\2.0\bin>ruby -e "require 'logger'"
D:\users\киї\Ruby\2.0\bin>ruby -v
ruby 2.0.0p451 (2014-02-24) [i386-mingw32]
</code></pre>
<p>The same is for <code>ruby 2.0.0p643 (2015-02-25) [i386-mingw32]</code> .</p>
<p>I also checked that require fails in the same case for<br>
<code>ruby 2.1.9p490 (2016-03-30 revision 54437) [i386-mingw32]</code></p> Ruby master - Bug #15764 (Open): Whitespace and control characters should not be permitted in tokenshttps://bugs.ruby-lang.org/issues/157642019-04-11T20:59:47ZBatmanAoD (Kyle Strand)kyle.j.strand@gmail.com
<p>As of Ruby 2.5.1p57, it appears that all valid Unicode code-points above 128 are permitted in tokens. This includes whitespace and control characters.</p>
<p>This was demonstrated here: <a href="https://gist.github.com/qrohlf/7045823" class="external">https://gist.github.com/qrohlf/7045823</a></p>
<p>I have attached the raw download from the above gist.</p>
<p>The issue has been discussed on StackOverflow: <a href="https://stackoverflow.com/q/34455427/1858225" class="external">https://stackoverflow.com/q/34455427/1858225</a></p>
<p>I would say this is arguably a bug, but I am marking this ticket as a "feature" since the current behavior could be considered by-design.</p> Ruby master - Bug #15599 (Open): Mixing autoload and require causes deadlock and incomplete defin...https://bugs.ruby-lang.org/issues/155992019-02-12T13:40:45Zakr (Akira Tanaka)akr@fsij.org
<p>I found that mixing autoload and require causes deadlock and incomplete definition.</p>
<pre><code>% cat a.rb
class A
def a1() end
end
% cat base.rb
autoload :A, './a'
t1 = Thread.new { p A.instance_methods(false) }
t2 = Thread.new { require './a' }
t1.join
t2.join
% ruby base.rb
Traceback (most recent call last):
1: from base.rb:6:in `<main>'
base.rb:6:in `join': No live threads left. Deadlock? (fatal)
3 threads, 3 sleeps current:0x000055cc6943fde0 main thread:0x000055cc6935f4b0
* #<Thread:0x000055cc6938f190 sleep_forever>
rb_thread_t:0x000055cc6935f4b0 native:0x00007f58d256eb40 int:0
base.rb:6:in `join'
base.rb:6:in `<main>'
* #<Thread:0x000055cc6968cfc8@base.rb:3 sleep_forever>
rb_thread_t:0x000055cc69736180 native:0x00007f58ce7b3700 int:0 mutex:0x000055cc6943fde0 cond:1
depended by: tb_thread_id:0x000055cc6935f4b0
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
base.rb:3:in `block in <main>'
* #<Thread:0x000055cc6968ccd0@base.rb:4 sleep_forever>
rb_thread_t:0x000055cc6943fde0 native:0x00007f58ce5b1700 int:0
/tmp/a/a.rb:1:in `<top (required)>'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
base.rb:4:in `block in <main>'
% ruby base.rb
[:a1]
% ruby base.rb
[]
</code></pre>
<p>The last run which prints [] means incomplete definition of A which a1 method is not defined.</p> Ruby master - Bug #15598 (Open): Deadlock on mutual reference of autoloaded constantshttps://bugs.ruby-lang.org/issues/155982019-02-11T12:39:41Zakr (Akira Tanaka)akr@fsij.org
<p>Mutual reference of autoloaded constants can cause deadlock sporadically.</p>
<p>Assume A is defined in a.rb and it uses B at loading time.<br>
Also, B is defined in b.rb and it uses A at loading time.</p>
<pre><code>% cat a.rb
class A
def a1() end
p [__FILE__, __LINE__, B.instance_methods(false)]
def a2() end
end
% cat b.rb
class B
def b1() end
p [__FILE__, __LINE__, A.instance_methods(false)]
def b2() end
end
</code></pre>
<p>If they are loaded via autoload and constants are referenced sequentially,<br>
it works (no error, at least).</p>
<p>However, incomplete A (which a2 is not defined) is appear in b.rb, though.</p>
<pre><code>% cat base_seq.rb
autoload :A, "./a"
autoload :B, "./b"
A
B
% ruby base_seq.rb
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, [:b1, :b2]]
</code></pre>
<p>However, the constants are referenced in multi threads,<br>
deadlock can occur, or works like sequential version, sporadically.</p>
<pre><code>% cat base_thread_const.rb
autoload :A, "./a"
autoload :B, "./b"
t1 = Thread.new { A }
t2 = Thread.new { B }
t1.join
t2.join
% ruby base_thread_const.rb
Traceback (most recent call last):
1: from base_thread_const.rb:5:in `<main>'
base_thread_const.rb:5:in `join': No live threads left. Deadlock? (fatal)
3 threads, 3 sleeps current:0x000055f9e2fa1b00 main thread:0x000055f9e2ec14b0
* #<Thread:0x000055f9e2eef188 sleep_forever>
rb_thread_t:0x000055f9e2ec14b0 native:0x00007f259bc54b40 int:0
base_thread_const.rb:5:in `join'
base_thread_const.rb:5:in `<main>'
* #<Thread:0x000055f9e31ece30@base_thread_const.rb:3 sleep_forever>
rb_thread_t:0x000055f9e31403c0 native:0x00007f2597e99700 int:0
depended by: tb_thread_id:0x000055f9e2ec14b0
/tmp/h/a.rb:3:in `<class:A>'
/tmp/h/a.rb:1:in `<top (required)>'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
base_thread_const.rb:3:in `block in <main>'
* #<Thread:0x000055f9e31ecbb0@base_thread_const.rb:4 sleep_forever>
rb_thread_t:0x000055f9e2fa1b00 native:0x00007f258ffff700 int:0
/tmp/h/b.rb:3:in `<class:B>'
/tmp/h/b.rb:1:in `<top (required)>'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
base_thread_const.rb:4:in `block in <main>'
% ruby base_thread_const.rb
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, [:b1, :b2]]
</code></pre>
<p>Also, if "require" is used instead of constant references in the threads,<br>
deadlock can occur (sporadically) too.</p>
<p>Note that incomplete A can appear in b.rb and<br>
incomplete B can appear in a.rb.<br>
The incompleteness vary.</p>
<pre><code>% cat base_thread_require.rb
autoload :A, "./a"
autoload :B, "./b"
t1 = Thread.new { require './a' }
t2 = Thread.new { require './b' }
t1.join
t2.join
% ruby base_thread_require.rb
Traceback (most recent call last):
1: from base_thread_require.rb:5:in `<main>'
base_thread_require.rb:5:in `join': No live threads left. Deadlock? (fatal)
3 threads, 3 sleeps current:0x00005591a27f5190 main thread:0x00005591a24264b0
* #<Thread:0x00005591a24531a0 sleep_forever>
rb_thread_t:0x00005591a24264b0 native:0x00007feced36ab40 int:0
base_thread_require.rb:5:in `join'
base_thread_require.rb:5:in `<main>'
* #<Thread:0x00005591a2754cc8@base_thread_require.rb:3 sleep_forever>
rb_thread_t:0x00005591a27f5190 native:0x00007fece95af700 int:0
depended by: tb_thread_id:0x00005591a24264b0
/tmp/h/a.rb:1:in `<top (required)>'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
base_thread_require.rb:3:in `block in <main>'
* #<Thread:0x00005591a2754a98@base_thread_require.rb:4 sleep_forever>
rb_thread_t:0x00005591a2506b00 native:0x00007fece13ad700 int:0 mutex:0x00005591a27f5190 cond:1
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/tmp/h/b.rb:3:in `<class:B>'
/tmp/h/b.rb:1:in `<top (required)>'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/home/akr/ruby/o0/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:54:in `require'
base_thread_require.rb:4:in `block in <main>'
% ruby base_thread_require.rb
["/tmp/h/b.rb", 3, []]
["/tmp/h/a.rb", 3, [:b1]]
% repeat 100 (ruby base_thread_require.rb >& /tmp/z && cat /tmp/z)
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/b.rb", 3, []]
["/tmp/h/a.rb", 3, [:b1]]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, [:b1, :b2]]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, [:b1, :b2]]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, [:b1, :b2]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, [:b1, :b2]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, [:b1]]
["/tmp/h/b.rb", 3, [:a1, :a2]]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, [:b1, :b2]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
["/tmp/h/a.rb", 3, []]
["/tmp/h/b.rb", 3, [:a1]]
</code></pre>
<p>I think there are several ways to solve this issue.</p>
<ul>
<li>Prohibit mutual reference.<br>
I.e. raise an error at autoload constant reference currently loading.<br>
Since mutual reference causes incomplete definition, it is dangerous even with single thread.<br>
However, if real application uses such code, this is incompatible.</li>
<li>More coarse locking.<br>
Since the deadlock is caused because two threads lock the constants in different order:<br>
A to B and B to A.<br>
I think it is possible to fix this issue by locking whole autoloading procedure by<br>
single lock, namely "global autoload lock".<br>
Note that it should also be locked by "require" method if it load a file for autoload.</li>
</ul> Ruby master - Bug #15550 (Assigned): Windows - gem bin files - can't run from bash shellhttps://bugs.ruby-lang.org/issues/155502019-01-20T00:45:45ZMSP-Greg (Greg L)
<p>As I recall, ruby-loco is no longer touching the gem related files located in the bin folder. Previously, there were two files associated with each gem, one with a .cmd/.bat extension, one without.</p>
<p>Currently, there is just one file with a .cmd extension. I have seen this before, and just came across it again, where gems are using *nix scripts run with either the MSYS2 shell or the Git shell in their CI. Hence, there is an expectation for the plain (extensionless) file to exist.</p>
<p>Not sure if this is considered a breaking change or a bug/issue.</p>
<p>Thanks, Greg</p> Ruby master - Bug #15499 (Assigned): Breaking behavior on ruby 2.6: rb_thread_call_without_gvl do...https://bugs.ruby-lang.org/issues/154992019-01-03T01:37:49Zapolcyn (alex polcyn)
<p>This issue was noticed when trying to add ruby 2.6 support to the "grpc" ruby gem (this gem is a native C-extension), and was caught by a unit test.</p>
<p>There are several APIs on the grpc ruby gem (<a href="https://github.com/grpc/grpc/tree/master/src/ruby" class="external">https://github.com/grpc/grpc/tree/master/src/ruby</a>) that invoke "rb_thread_call_without_gvl" on the current thread, doing a blocking operation in the "without gvl" callback and cancel that blocking operation in the "unblocking function". These APIs work in ruby versions prior to ruby 2.6 (e.g. ruby 2.5), but have problems when used on ruby 2.6</p>
<p>Minimal repro:</p>
<p>My system:</p>
<pre><code>> lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 9.6 (stretch)
Release: 9.6
Codename: stretch
> ruby -v
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-linux
# I installed ruby 2.6.0 with rvm - https://rvm.io/rvm/install
> GRPC_CONFIG=dbg gem install grpc --platform ruby # build grpc gem from source with debug symbols
</code></pre>
<p>ruby script, "repro.rb" that looks like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'grpc'</span>
<span class="n">ch</span> <span class="o">=</span> <span class="no">GRPC</span><span class="o">::</span><span class="no">Core</span><span class="o">::</span><span class="no">Channel</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s1">'localhost:1234'</span><span class="p">,</span> <span class="p">{},</span> <span class="ss">:this_channel_is_insecure</span><span class="p">)</span>
<span class="n">ch</span><span class="p">.</span><span class="nf">watch_connectivity_state</span><span class="p">(</span><span class="n">ch</span><span class="p">.</span><span class="nf">connectivity_state</span><span class="p">,</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">+</span> <span class="mi">360</span><span class="p">)</span>
</code></pre>
<p>Run "ruby repro.rb" with an interactive shell, and it will hang there. At this point, ctrl^C the process, and it will not terminate.<br>
What should happen is this unblocking func should be invoked: <a href="https://github.com/grpc/grpc/blob/master/src/ruby/ext/grpc/rb_channel.c#L354" class="external">https://github.com/grpc/grpc/blob/master/src/ruby/ext/grpc/rb_channel.c#L354</a>, but as seen with logging or debuggers, that unblocking func is never ran. Thus the blocking operation never completes and the main thread is stuck.</p>
<p>When the same repro.rb is ran on e.g. ruby 2.5.3 or ruby 2.4.1, the blocking operation is unblocked and the process terminates, as expected, when sending it a SIGINT.</p>
<p>Also note that if the blocking operation is put in a background thread, e.g. with this script:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'grpc'</span>
<span class="n">th</span> <span class="o">=</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">ch</span> <span class="o">=</span> <span class="no">GRPC</span><span class="o">::</span><span class="no">Core</span><span class="o">::</span><span class="no">Channel</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s1">'localhost:1234'</span><span class="p">,</span> <span class="p">{},</span> <span class="ss">:this_channel_is_insecure</span><span class="p">)</span>
<span class="n">ch</span><span class="p">.</span><span class="nf">watch_connectivity_state</span><span class="p">(</span><span class="n">ch</span><span class="p">.</span><span class="nf">connectivity_state</span><span class="p">,</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">+</span> <span class="mi">360</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">th</span><span class="p">.</span><span class="nf">join</span>
</code></pre>
<p>then "unblocking" functions will in fact be invoked upon sending the process a SIGINT, so this looks like a problem specifically with rb_thread_call_without_gvl being used on the main thread.</p>
<p>Please let me know and I can provide more details or alternative repro cases.</p>
<p>Thanks in advance.</p> Ruby master - Bug #15423 (Open): fork leapfrog leaks memory on FreeBSD 11.2https://bugs.ruby-lang.org/issues/154232018-12-16T14:28:54Znormalperson (Eric Wong)normalperson@yhbt.net
<p>It happens on 2.4.5, too; so it's not a new problem.<br>
fork leap-frogging (without exec) is an uncommon case,<br>
so I'll let somebody else fix it.</p> Ruby master - Bug #15386 (Open): [PATCH] io.c (rb_io_check_char_readable): do not io_fflush buffe...https://bugs.ruby-lang.org/issues/153862018-12-06T11:38:00Znormalperson (Eric Wong)normalperson@yhbt.net
<pre><code>This is a rare corner-case probably nobody cares about. (because
socket has IO#sync=false by default). Not critical to fix
or change before 2.6 (I'm not sure if there's a compatibility risk).
Would much appreciate an extra set of eyes to review; but it can wait
for post-26.
[I tried taking a break from C and ruby-core to work on a different
project today; but hit this bug within an hour of doing that :<]
io.c (rb_io_check_char_readable): do not io_fflush buffered sockets
I enabled userspace buffering on sockets to reduce syscall
overhead while avoiding non-portable TCP_CORK/TCP_NOPUSH.
This deadlocked for me because I was using independent threads
for reading and writing simultaneously on the same socket.
I also experimented with making io_fflush optionally
non-blocking, but that caused stream corruption with the reader
thread doing some writes.
https://80x24.org/spew/20181206104008.29153-1-e@80x24.org/raw
Test script (hitting
news://news.public-inbox.org/inbox.comp.version-control.git
is fine)
require 'socket'
require 'uri'
require 'io/nonblock'
usage = "usage: #$0 news://news.public-inbox.org/inbox.comp.version-control.git"
uri = ARGV.shift or abort usage
uri = URI(uri)
uri.port ||= 119
group = uri.path.sub(%r{\A/+}, '') # String#delete_prefix requires Ruby 2.5+
s = Socket.tcp(uri.host, uri.port)
l = s.gets
l =~ /\A2\d\d / or abort "bad greeting: #{l}"
s.nonblock = true
s.puts "GROUP #{group}"
l = s.gets
code, _, min, max = l.chomp!.split.map!(&:to_i)
code == 211 or abort "bad GROUP response: #{l}"
rdr = Thread.new do
nres = 0
r = s.dup
while l = r.gets
l.start_with?('205 ') and break # cmd_quit
l.start_with?('224 ') or abort "bad OVER response: #{l}"
while l = r.gets
if l == ".\r\n"
nres += 1
break
end
end
end
nres
end
range = min..max
s.sync = false
range.each { |i| s.puts "XOVER #{i}" }
puts "requests=#{range.size} #{Time.now}"
s.puts "QUIT"
s.flush
puts "responses=#{rdr.value} #{Time.now}"
</code></pre> Ruby master - Bug #15367 (Open): IO.select is not resumed when io-object gets closedhttps://bugs.ruby-lang.org/issues/153672018-12-02T16:48:52Zprintercu (Max Melentiev)melentievm@gmail.com
<p>Here is sample code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">rp</span><span class="p">,</span> <span class="n">wp</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">pipe</span>
<span class="n">t2</span> <span class="o">=</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="no">IO</span><span class="p">.</span><span class="nf">select</span><span class="p">([</span><span class="n">rp</span><span class="p">])</span> <span class="p">}</span>
<span class="c1"># This also does not work:</span>
<span class="c1"># t2 = Thread.new { IO.select([rp], nil, [rp]) }</span>
<span class="nb">sleep</span> <span class="mf">0.01</span>
<span class="n">rp</span><span class="p">.</span><span class="nf">close</span>
<span class="n">t2</span>
<span class="c1"># => #<Thread:0x00000000089b6ce0@(pry):51 sleep></span>
</code></pre>
<p>It happens only on linux, tested with 2.5.1, 2.6.0-preview2. On macOS it gives error, as expected:</p>
<pre><code>#<Thread:0x00007fab3aebce58@(pry):5 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from (pry):5:in `block in <main>'
(pry):5:in `select': Bad file descriptor (Errno::EBADF)
> t2
=> #<Thread:0x00007fab3aebce58@(pry):5 dead>
</code></pre> Ruby master - Bug #15315 (Open): ec_switch can still lose interruptshttps://bugs.ruby-lang.org/issues/153152018-11-18T00:50:29Znormalperson (Eric Wong)normalperson@yhbt.net
<p>ec_switch and thread switching may still lose interrupts</p>
<p>trap interrupt is OK because of r64062</p>
<p>Not OK:</p>
<ol>
<li>
<p>postponed job interrupt from MJIT worker<br>
This is trickiest to solve because it also affects thread switching,<br>
not just EC switching</p>
</li>
<li>
<p>pending interrupt is not safe but fixing ec_switch is sufficient because<br>
rb_threadptr_interrupt only targets threads, not EC.</p>
</li>
<li>
<p>timer interrupt is not critical because another interrupt will fire in 100ms</p>
</li>
</ol>
<p>Solutions:</p>
<p>moving interrupt_flag back to rb_thread_t will solve 2 and 3</p>
<ol>
<li>will remain dangerous, we need to add extra checks at thread switching<br>
because MJIT worker may get stuck if target thread stalls or dies.</li>
</ol> Ruby master - Bug #15310 (Open): [PATCH] thread_pthread.c: close race from UBF_TIMER and non-GVL-...https://bugs.ruby-lang.org/issues/153102018-11-16T02:30:10Znormalperson (Eric Wong)normalperson@yhbt.net
<p>thread_pthread.c: close race from UBF_TIMER and non-GVL-releasing thread</p>
<p>A Ruby thread may run without releasing the GVL if there is no<br>
contention. And there may be no contention because another<br>
thread missed its wakeup and needs to rely on ubf_list for<br>
wakeups. So we need to ensure the Ruby thread can relinquish<br>
GVL and trigger ubf_list wakeups to target thread when the POSIX<br>
timer fires.</p>
<p>Thus, we trigger a timeslice on SIGVTALRM when triggered by<br>
UBF_TIMER (we do not want excessive switching overhead on every<br>
SIGVTALRM signal, either).</p>
<p>Note: I'm pretty sure this is necessary, correct and would introduce no<br>
portability problems or performance overhead if I'm wrong...<br>
I could definitely use an extra set of eyes on this, though.</p> Ruby master - Bug #15263 (Open): [PATCH] vm_trace.c (postponed_job_register): only hit main threadhttps://bugs.ruby-lang.org/issues/152632018-10-27T23:35:33Znormalperson (Eric Wong)normalperson@yhbt.net
<pre><code>vm_trace.c (postponed_job_register): only hit main thread
Since postponed_job_register may be called in a signal handler,
only the main thread is safe to touch as other threads may
become invalid. Furthermore, the problem with trap interrupt
being lost during ec_switch [Bug #14939] also applies to the
postponed job and timer interrupts, so we need to preserve all
three interrupts in ec_switch.
Note: A minor problem is a possible crash during/after
ruby_vm_destruct if postponed jobs are registered.
The correct and performant fix would be to leak memory at exit
for `vm' and `vm->main_thread'. free(3) slows down short-lived
scripts, as does unregistering signal handlers.
* vm_trace.c (postponed_job_register): only hit main thread
* cont.c (ec_switch): preserve postponed and timer interrupt flags, too
</code></pre> Ruby master - Bug #15247 (Open): Windows - TEMP folder, non 8.3 & drive, fails & errors in test-a...https://bugs.ruby-lang.org/issues/152472018-10-23T17:02:28ZMSP-Greg (Greg L)
<p>While working with Azure pipelines, two issues came up related to the TEMP folder.</p>
<p>1. The standard Windows TEMP folder is located in a user directory. The user for pipeplines is 'buildguest', which is greater than 8 characters, and hence, its short and long paths differ. When I created a new user account locally on Windows 10, both ENV['TEMP'] and ENV['TMP'] were set to the short path.</p>
<p>This is causes two failures in <code>test/rdoc/test_rdoc_rdoc.rb</code> and one failure in <code>test_dir.rb</code>, the failures are listed in the attached file temp_short-long.txt.</p>
<p>2. Azure pipelines has the normal TEMP folder on drive C:, but, unlike Appveyor, the repo is placed on drive D:. This causes one failure in <code>test/rdoc/test_rdoc_options.rb</code>, and two errors from the same file, but in the std-Lib file <code>pathname.rb</code>. See attached file temp_drive.txt.</p>
<p>I'm not really sure what I think the solution for this is, as the issue is really due to Windows setting ENV['TEMP'] and ENV['TMP'] to short paths. I do recall the same issues happened on my old multi-drive desktop system. At the time, there were more significant issues with build/test, so I reconfigured the env for that...</p> Ruby master - Bug #14838 (Open): RegexpError with double "s" in look-behind assertion in case-ins...https://bugs.ruby-lang.org/issues/148382018-06-09T16:04:07Zjkamens@quantopian.com (Jonathan Kamens)jkamens@quantopian.com
<pre><code>irb(main):003:0> %r{(?<!bss>)}ui
Traceback (most recent call last):
1: from /usr/bin/irb:11:in `<main>'
SyntaxError ((irb):3: invalid pattern in look-behind: /(?<!bss>)/i)
</code></pre>
<p>The error goes away if you remove the "u" or "i" modifier. It comes back if you leave just the "i" modifier and then apply the regexp to a unicode string, since at that point the regexp gets converted to unicode.</p>
<p>See also the same bug in JRuby: <a href="https://github.com/jruby/jruby/issues/5086" class="external">https://github.com/jruby/jruby/issues/5086</a><br>
And their fix: <a href="https://github.com/jruby/jruby/commit/a72224d8a010f162d797e79cf73c21e78c0d59a0" class="external">https://github.com/jruby/jruby/commit/a72224d8a010f162d797e79cf73c21e78c0d59a0</a></p> Ruby master - Bug #14761 (Open): TestThread#test_join_limits hangs up on Solaris 10 with gcchttps://bugs.ruby-lang.org/issues/147612018-05-15T14:21:08Zngoto (Naohisa Goto)ngotogenome@gmail.com
<p>On Solaris 10, sparc architecture, when compiling ruby (r63417) by GCC (version 4.6.2), TestThread#test_join_limits did not end.</p>
<p>The test ended successfully when compiling ruby by Oracle Developer Studio 12.5 or 12.6.</p> Ruby master - Bug #14727 (Assigned): TestQueue#test_queue_with_trap always timeout on Windows10https://bugs.ruby-lang.org/issues/147272018-05-01T02:27:47Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<p>表題の通りです。ささださんも把握しているそうなので、備忘録として。</p>
<pre><code>[19/35] TestQueue#test_queue_with_trap = 10.13 s
1) Error:
TestQueue#test_queue_with_trap:
Timeout::Error: execution of assert_in_out_err expired timeout (10 sec)
pid 11608 exit 0
|
C:/Users/usa/develop/ruby/core/mytree/test/thread/test_queue.rb:553:in `test_queue_with_trap'
</code></pre> Ruby master - Bug #14681 (Open): `syswrite': stream closed in another thread (IOError)https://bugs.ruby-lang.org/issues/146812018-04-12T03:16:08Zioquatix (Samuel Williams)samuel@oriontransfer.net
<p>Perhaps related to <a href="https://bugs.ruby-lang.org/issues/13632" class="external">https://bugs.ruby-lang.org/issues/13632</a></p>
<p>Here is a sample to reproduce the issue.</p>
<pre><code>#!/usr/bin/env ruby
require 'thread'
puts RUBY_VERSION
100.times.collect do
Thread.new do
input, output = IO.pipe
worker = Thread.new do
sleep(0.1)
output.syswrite('.')
end
input.read(1)
input.close
output.close
worker.join
end
end.each(&:join)
</code></pre>
<p>If you run this, you will get output like so:</p>
<pre><code>2.5.0
#<Thread:0x00007fb7a4956ee8@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a50bb468@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4964250@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a49386f0@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a493ab08@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a495fb88@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a50bbb98@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4948820@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4939820@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a486a458@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4860020@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4970258@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4973f48@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4948618@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a495f728@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a495f868@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4848628@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4843858@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4809400@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a5085278@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a495e0f8@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a48417d8@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a5037c80@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4948398@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4948c30@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4939b18@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4957500@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a480a9b8@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a5036d30@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a5085c50@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a495e2b0@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a495f070@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a495e6e8@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a49572d0@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a495e580@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a494a350@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4811060@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a50842b0@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a494bb10@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a493ae00@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a495e878@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a494be30@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4809c70@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a480a4e0@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a50b90f0@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:11 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
#<Thread:0x00007fb7a4965600@/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:8 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
Traceback (most recent call last):
1: from /private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `block (3 levels) in <main>'
/private/var/folders/3x/tvygzl0s65520b6t4tzqbt980000gn/T/16789369-c982-4cbc-a0b3-c836af60bf03:13:in `syswrite': stream closed in another thread (IOError)
Exited with status 1 after 0.291 seconds
</code></pre>
<p>However, you can clearly see from the order of the sample code it's not possible for such an error to occur. <code>#close</code> is only invoked after a successful <code>#read</code> which is only possible after a successful <code>#write</code>. Yet, the error implies that the write failed because it was already closed.</p> Ruby master - Bug #14640 (Open): [win32] File.realpath treats a relative path with a drive letter...https://bugs.ruby-lang.org/issues/146402018-03-28T16:18:34Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<p>When <code>t</code> exists in the current directory under the drive C:,</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">File</span><span class="p">.</span><span class="nf">realpath</span><span class="p">(</span><span class="s2">"c:t"</span><span class="p">)</span> <span class="c1">#=> No such file or directory @ realpath_rec - c:/t (Errno::ENOENT)</span>
</code></pre>
<p>whereas <code>File.expand_path</code> returns <code>Dir.pwd + "/t"</code>.</p> Ruby master - Bug #14090 (Assigned): `TestGc#test_interrupt_in_finalizer` fails very rarelyhttps://bugs.ruby-lang.org/issues/140902017-11-07T07:35:25Zmame (Yusuke Endoh)mame@ruby-lang.org
<p><code>TestGc#test_interrupt_in_finalizer</code> fails very rarely, only once every handred or thousand runs.</p>
<pre><code># Running tests:
[1/1] TestGc#test_interrupt_in_finalizer = 10.13 s
1) Error:
TestGc#test_interrupt_in_finalizer:
Timeout::Error: execution of assert_in_out_err expired
pid 24697 killed by SIGABRT (signal 6) (core dumped)
|
| [BUG] Segmentation fault at 0x000003e800006075
| ruby 2.5.0dev (2017-11-07) [x86_64-linux]
|
| -- Control frame information -----------------------------------------------
|
|
| -- Machine register context ------------------------------------------------
| RIP: 0x00007f80612bb072 RBP: 0x000055c3587e1efc RSP: 0x00007ffc4f8100b0
| RAX: 0xfffffffffffffffc RBX: 0x000055c3587e1ee4 RCX: 0x00007f80612bb072
| RDX: 0x0000000000000000 RDI: 0x000055c3587e1efc RSI: 0x0000000000000080
| R8: 0x00000000000000ca R9: 0x0000000000000000 R10: 0x0000000000000000
| R11: 0x0000000000000246 R12: 0x000055c3587e1ed0 R13: 0x00007ffc4f810110
| R14: 0x000055c3587e1f38 R15: 0x0000000000000003 EFL: 0x0000000000000246
|
| -- C level backtrace information -------------------------------------------
| /home/mame/work/ruby.tmp/ruby(rb_vm_bugreport+0x7d3) [0x55c357e7a333] vm_dump.c:703
| /home/mame/work/ruby.tmp/ruby(rb_bug_context+0xd1) [0x55c357e6de11] error.c:554
| /home/mame/work/ruby.tmp/ruby(sigsegv+0x42) [0x55c357d5e602] signal.c:928
| /lib/x86_64-linux-gnu/libpthread.so.0 [0x7f80612c0150]
| /lib/x86_64-linux-gnu/libpthread.so.0(pthread_cond_wait+0x152) [0x7f80612bb072]
| /home/mame/work/ruby.tmp/ruby(native_sleep.constprop.79+0x1de) [0x55c357d967fe] thread_pthread.c:340
| /home/mame/work/ruby.tmp/ruby(rb_thread_terminate_all+0x1e0) [0x55c357d9aba0] thread.c:507
| /home/mame/work/ruby.tmp/ruby(ruby_cleanup+0x17e) [0x55c357c6078e] eval.c:188
| /home/mame/work/ruby.tmp/ruby(ruby_run_node+0x36) [0x55c357c60aa6] eval.c:302
| /home/mame/work/ruby.tmp/ruby(main+0x5f) [0x55c357c5ca1f] encoding.c:164
|
| -- Other runtime information -----------------------------------------------
|
| * Loaded script: -e
|
| * Loaded features:
|
| 0 enumerator.so
| 1 thread.rb
| 2 rational.so
| 3 complex.so
| 4 /home/mame/work/ruby.tmp/.ext/x86_64-linux/enc/encdb.so
| 5 /home/mame/work/ruby.tmp/.ext/x86_64-linux/enc/trans/transdb.so
| 6 /home/mame/work/ruby.tmp/rbconfig.rb
| 7 /home/mame/work/ruby.tmp/lib/rubygems/compatibility.rb
| 8 /home/mame/work/ruby.tmp/lib/rubygems/defaults.rb
| 9 /home/mame/work/ruby.tmp/lib/rubygems/deprecate.rb
| 10 /home/mame/work/ruby.tmp/lib/rubygems/errors.rb
| 11 /home/mame/work/ruby.tmp/lib/rubygems/version.rb
| 12 /home/mame/work/ruby.tmp/lib/rubygems/requirement.rb
| 13 /home/mame/work/ruby.tmp/lib/rubygems/platform.rb
| 14 /home/mame/work/ruby.tmp/lib/rubygems/basic_specification.rb
| 15 /home/mame/work/ruby.tmp/lib/rubygems/stub_specification.rb
| 16 /home/mame/work/ruby.tmp/lib/rubygems/util/list.rb
| 17 /home/mame/work/ruby.tmp/.ext/x86_64-linux/stringio.so
| 18 /home/mame/work/ruby.tmp/lib/rubygems/specification.rb
| 19 /home/mame/work/ruby.tmp/lib/rubygems/exceptions.rb
| 20 /home/mame/work/ruby.tmp/lib/rubygems/core_ext/kernel_gem.rb
| 21 /home/mame/work/ruby.tmp/lib/monitor.rb
| 22 /home/mame/work/ruby.tmp/lib/rubygems/core_ext/kernel_require.rb
| 23 /home/mame/work/ruby.tmp/lib/rubygems.rb
| 24 /home/mame/work/ruby.tmp/lib/rubygems/dependency.rb
| 25 /home/mame/work/ruby.tmp/lib/rubygems/path_support.rb
|
| * Process memory map:
|
| 55c357c3a000-55c357f55000 r-xp 00000000 fd:01 21892603 /home/mame/work/ruby.tmp/ruby
| 55c358155000-55c35815a000 r--p 0031b000 fd:01 21892603 /home/mame/work/ruby.tmp/ruby
| 55c35815a000-55c35815b000 rw-p 00320000 fd:01 21892603 /home/mame/work/ruby.tmp/ruby
| 55c35815b000-55c35816c000 rw-p 00000000 00:00 0
| 55c3587e1000-55c358b0d000 rw-p 00000000 00:00 0 [heap]
| 7f8058000000-7f8058021000 rw-p 00000000 00:00 0
| 7f8058021000-7f805c000000 ---p 00000000 00:00 0
| 7f805e93f000-7f805eb1e000 r--s 00000000 fd:01 15604574 /lib/x86_64-linux-gnu/libc-2.26.so
| 7f805eb1e000-7f805fb92000 r--s 00000000 fd:01 21892603 /home/mame/work/ruby.tmp/ruby
| 7f805fb92000-7f805fba8000 r-xp 00000000 fd:01 15597591 /lib/x86_64-linux-gnu/libgcc_s.so.1
| 7f805fba8000-7f805fda7000 ---p 00016000 fd:01 15597591 /lib/x86_64-linux-gnu/libgcc_s.so.1
| 7f805fda7000-7f805fda8000 r--p 00015000 fd:01 15597591 /lib/x86_64-linux-gnu/libgcc_s.so.1
| 7f805fda8000-7f805fda9000 rw-p 00016000 fd:01 15597591 /lib/x86_64-linux-gnu/libgcc_s.so.1
| 7f805fda9000-7f805feaa000 rw-p 00000000 00:00 0
| 7f805feaa000-7f805feb3000 r-xp 00000000 fd:01 23333969 /home/mame/work/ruby.tmp/.ext/x86_64-linux/stringio.so
| 7f805feb3000-7f80600b2000 ---p 00009000 fd:01 23333969 /home/mame/work/ruby.tmp/.ext/x86_64-linux/stringio.so
| 7f80600b2000-7f80600b3000 r--p 00008000 fd:01 23333969 /home/mame/work/ruby.tmp/.ext/x86_64-linux/stringio.so
| 7f80600b3000-7f80600b4000 rw-p 00009000 fd:01 23333969 /home/mame/work/ruby.tmp/.ext/x86_64-linux/stringio.so
| 7f80600b4000-7f80600b6000 r-xp 00000000 fd:01 23333689 /home/mame/work/ruby.tmp/.ext/x86_64-linux/enc/trans/transdb.so
| 7f80600b6000-7f80602b6000 ---p 00002000 fd:01 23333689 /home/mame/work/ruby.tmp/.ext/x86_64-linux/enc/trans/transdb.so
| 7f80602b6000-7f80602b7000 r--p 00002000 fd:01 23333689 /home/mame/work/ruby.tmp/.ext/x86_64-linux/enc/trans/transdb.so
| 7f80602b7000-7f80602b8000 rw-p 00003000 fd:01 23333689 /home/mame/work/ruby.tmp/.ext/x86_64-linux/enc/trans/transdb.so
| 7f80602b8000-7f80602ba000 r-xp 00000000 fd:01 23333649 /home/mame/work/ruby.tmp/.ext/x86_64-linux/enc/encdb.so
| 7f80602ba000-7f80604b9000 ---p 00002000 fd:01 23333649 /home/mame/work/ruby.tmp/.ext/x86_64-linux/enc/encdb.so
| 7f80604b9000-7f80604ba000 r--p 00001000 fd:01 23333649 /home/mame/work/ruby.tmp/.ext/x86_64-linux/enc/encdb.so
| 7f80604ba000-7f80604bb000 rw-p 00002000 fd:01 23333649 /home/mame/work/ruby.tmp/.ext/x86_64-linux/enc/encdb.so
| 7f80604bb000-7f8060691000 r-xp 00000000 fd:01 15604574 /lib/x86_64-linux-gnu/libc-2.26.so
| 7f8060691000-7f8060891000 ---p 001d6000 fd:01 15604574 /lib/x86_64-linux-gnu/libc-2.26.so
| 7f8060891000-7f8060895000 r--p 001d6000 fd:01 15604574 /lib/x86_64-linux-gnu/libc-2.26.so
| 7f8060895000-7f8060897000 rw-p 001da000 fd:01 15604574 /lib/x86_64-linux-gnu/libc-2.26.so
| 7f8060897000-7f806089b000 rw-p 00000000 00:00 0
| 7f806089b000-7f80609f0000 r-xp 00000000 fd:01 15604578 /lib/x86_64-linux-gnu/libm-2.26.so
| 7f80609f0000-7f8060bef000 ---p 00155000 fd:01 15604578 /lib/x86_64-linux-gnu/libm-2.26.so
| 7f8060bef000-7f8060bf0000 r--p 00154000 fd:01 15604578 /lib/x86_64-linux-gnu/libm-2.26.so
| 7f8060bf0000-7f8060bf1000 rw-p 00155000 fd:01 15604578 /lib/x86_64-linux-gnu/libm-2.26.so
| 7f8060bf1000-7f8060bfa000 r-xp 00000000 fd:01 15604576 /lib/x86_64-linux-gnu/libcrypt-2.26.so
| 7f8060bfa000-7f8060df9000 ---p 00009000 fd:01 15604576 /lib/x86_64-linux-gnu/libcrypt-2.26.so
| 7f8060df9000-7f8060dfa000 r--p 00008000 fd:01 15604576 /lib/x86_64-linux-gnu/libcrypt-2.26.so
| 7f8060dfa000-7f8060dfb000 rw-p 00009000 fd:01 15604576 /lib/x86_64-linux-gnu/libcrypt-2.26.so
| 7f8060dfb000-7f8060e29000 rw-p 00000000 00:00 0
| 7f8060e29000-7f8060e2c000 r-xp 00000000 fd:01 15604577 /lib/x86_64-linux-gnu/libdl-2.26.so
| 7f8060e2c000-7f806102b000 ---p 00003000 fd:01 15604577 /lib/x86_64-linux-gnu/libdl-2.26.so
| 7f806102b000-7f806102c000 r--p 00002000 fd:01 15604577 /lib/x86_64-linux-gnu/libdl-2.26.so
| 7f806102c000-7f806102d000 rw-p 00003000 fd:01 15604577 /lib/x86_64-linux-gnu/libdl-2.26.so
| 7f806102d000-7f80610ab000 r-xp 00000000 fd:01 12068737 /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2
| 7f80610ab000-7f80612ab000 ---p 0007e000 fd:01 12068737 /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2
| 7f80612ab000-7f80612ac000 r--p 0007e000 fd:01 12068737 /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2
| 7f80612ac000-7f80612ad000 rw-p 0007f000 fd:01 12068737 /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2
| 7f80612ad000-7f80612c7000 r-xp 00000000 fd:01 15604589 /lib/x86_64-linux-gnu/libpthread-2.26.so
| 7f80612c7000-7f80614c6000 ---p 0001a000 fd:01 15604589 /lib/x86_64-linux-gnu/libpthread-2.26.so
| 7f80614c6000-7f80614c7000 r--p 00019000 fd:01 15604589 /lib/x86_64-linux-gnu/libpthread-2.26.so
| 7f80614c7000-7f80614c8000 rw-p 0001a000 fd:01 15604589 /lib/x86_64-linux-gnu/libpthread-2.26.so
| 7f80614c8000-7f80614cc000 rw-p 00000000 00:00 0
| 7f80614cc000-7f80614f3000 r-xp 00000000 fd:01 15602223 /lib/x86_64-linux-gnu/ld-2.26.so
| 7f8061592000-7f80615b6000 r--s 00000000 fd:01 15604589 /lib/x86_64-linux-gnu/libpthread-2.26.so
| 7f80615b6000-7f80616bc000 rw-p 00000000 00:00 0
| 7f80616cb000-7f80616cc000 ---p 00000000 00:00 0
| 7f80616cc000-7f80616ec000 rw-p 00000000 00:00 0
| 7f80616ec000-7f80616ed000 ---p 00000000 00:00 0
| 7f80616ed000-7f80616f3000 rw-p 00000000 00:00 0
| 7f80616f3000-7f80616f4000 r--p 00027000 fd:01 15602223 /lib/x86_64-linux-gnu/ld-2.26.so
| 7f80616f4000-7f80616f5000 rw-p 00028000 fd:01 15602223 /lib/x86_64-linux-gnu/ld-2.26.so
| 7f80616f5000-7f80616f6000 rw-p 00000000 00:00 0
| 7ffc4f013000-7ffc4f812000 rw-p 00000000 00:00 0 [stack]
| 7ffc4f904000-7ffc4f907000 r--p 00000000 00:00 0 [vvar]
| 7ffc4f907000-7ffc4f909000 r-xp 00000000 00:00 0 [vdso]
| ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
|
|
| [NOTE]
| You may have encountered a bug in the Ruby interpreter or extension libraries.
| Bug reports are welcome.
| For details: http://www.ruby-lang.org/bugreport.html
|
/home/mame/work/ruby.tmp/test/ruby/test_gc.rb:354:in `test_interrupt_in_finalizer'
Finished tests in 10.127763s, 0.0987 tests/s, 0.2962 assertions/s.
1 tests, 3 assertions, 0 failures, 1 errors, 0 skips
</code></pre>
<a name="How-to-reproduce"></a>
<h2 >How to reproduce<a href="#How-to-reproduce" class="wiki-anchor">¶</a></h2>
<ol>
<li>Apply this patch. This removes a mitigation of this issue.</li>
</ol>
<pre><code>diff --git a/thread.c b/thread.c
index bfa903c6a4..dfaf75d1ce 100644
--- a/thread.c
+++ b/thread.c
@@ -507,7 +507,7 @@ rb_thread_terminate_all(void)
* me when the last sub-thread exit.
*/
sleeping = 1;
- native_sleep(th, &tv);
+ native_sleep(th, 0);
RUBY_VM_CHECK_INTS_BLOCKING(ec);
sleeping = 0;
}
</code></pre>
<ol start="2">
<li>Run <code>make test-all</code> many times. The following command would be useful.</li>
</ol>
<pre><code>make && while make test-all TESTOPTS="test/ruby/test_gc.rb -n test_interrupt_in_finalizer"; do date; done
</code></pre>
<p>FYI: With execution counter</p>
<pre><code>make && i=0 && while make test-all TESTOPTS="test/ruby/test_gc.rb -n test_interrupt_in_finalizer"; do echo; date; echo "trial:$i"; i=`expr $i + 1`; done
</code></pre>
<a name="Details"></a>
<h2 >Details<a href="#Details" class="wiki-anchor">¶</a></h2>
<p><code>TestGc#test_interrupt_in_finalizer</code> checks if SIGINT can interrupt the GC finalizers. This test itself runs on a child process, and the process should end with SIGINT. If the process does not end in ten seconds, the parent sends SIGSEGV to the child, terminates the test, and reports it as a failure. ("C level backtrace information" has "sigsegv", but don't worry, this SEGV would be the one the parent sent. I guess this bug is not so significant, parhaps.)</p>
<p>When a main thread of Ruby process ends, it terminates all child threads and waits for them. However, for unknown reason (maybe depending upon the timing of SIGINT?), it sometimes fails synchronization: all child threads end, and the main thread meaninglessly waits forever.</p>
<p>Based on Ko1's proposal, I committed a tiny change to mitigate this issue at r60694: instead of waiting forever, the main thread wakes up every one second to monitor all child threads. This is not an essential solution for this issue, but just hides. To debug this issue, we need remove the mitigation by the patch described above.</p> Ruby master - Bug #13999 (Assigned): Cygwin 環境で ripper_state_lex.rb がコアダンプするhttps://bugs.ruby-lang.org/issues/139992017-10-11T05:19:02Zhigaki (masaru higaki)mas.higa@gmail.com
<p>いくつかの gem をインストールした際にコアダンプしました。</p>
<p>--no-ri を付けるとコアダンプしないことから ri の何かが関係していそうです。</p>
<p>$ gem install bitclust-core # コアダンプ<br>
$ gem install --no-ri bitclust-core # コアダンプしない</p>
<p>標準出力、エラー出力を添付します。</p> Ruby master - Bug #13671 (Assigned): Regexp with lookbehind and case-insensitivity raises RegexpE...https://bugs.ruby-lang.org/issues/136712017-06-22T23:28:58Zdschweisguth (Dave Schweisguth)dave@schweisguth.org
<p>Here is a test program:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">description</span><span class="p">)</span>
<span class="k">begin</span>
<span class="k">yield</span>
<span class="nb">puts</span> <span class="s2">"</span><span class="si">#{</span><span class="n">description</span><span class="si">}</span><span class="s2"> is OK"</span>
<span class="k">rescue</span> <span class="no">RegexpError</span>
<span class="nb">puts</span> <span class="s2">"</span><span class="si">#{</span><span class="n">description</span><span class="si">}</span><span class="s2"> raises RegexpError"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">test</span><span class="p">(</span><span class="s2">"ass, case-insensitive, special"</span><span class="p">)</span> <span class="p">{</span> <span class="sr">/(?<!ass)/i</span> <span class="o">=~</span> <span class="s1">'✨'</span> <span class="p">}</span>
<span class="nb">test</span><span class="p">(</span><span class="s2">"bss, case-insensitive, special"</span><span class="p">)</span> <span class="p">{</span> <span class="sr">/(?<!bss)/i</span> <span class="o">=~</span> <span class="s1">'✨'</span> <span class="p">}</span>
<span class="nb">test</span><span class="p">(</span><span class="s2">"as, case-insensitive, special"</span><span class="p">)</span> <span class="p">{</span> <span class="sr">/(?<!as)/i</span> <span class="o">=~</span> <span class="s1">'✨'</span> <span class="p">}</span>
<span class="nb">test</span><span class="p">(</span><span class="s2">"ss, case-insensitive, special"</span><span class="p">)</span> <span class="p">{</span> <span class="sr">/(?<!ss)/i</span> <span class="o">=~</span> <span class="s1">'✨'</span> <span class="p">}</span>
<span class="nb">test</span><span class="p">(</span><span class="s2">"ass, case-sensitive, special"</span><span class="p">)</span> <span class="p">{</span> <span class="sr">/(?<!ass)/</span> <span class="o">=~</span> <span class="s1">'✨'</span> <span class="p">}</span>
<span class="nb">test</span><span class="p">(</span><span class="s2">"ass, case-insensitive, regular"</span><span class="p">)</span> <span class="p">{</span> <span class="sr">/(?<!ass)/i</span> <span class="o">=~</span> <span class="s1">'x'</span> <span class="p">}</span>
</code></pre>
<p>Running the test program with Ruby 2.4.1 (macOS) gives</p>
<pre><code>ass, case-insensitive, special raises RegexpError
bss, case-insensitive, special raises RegexpError
as, case-insensitive, special is OK
ss, case-insensitive, special is OK
ass, case-sensitive, special is OK
ass, case-insensitive, regular is OK
</code></pre>
<p>The RegexpError is "invalid pattern in look-behind: /(?<!ass)/i (RegexpError)"</p>
<p>Side note: in the real code in which I found this error I was able to work around the error by using (?i) after the lookbehind instead of //i.</p>
<p>Running the test program with Ruby 2.3.4 does not report any RegexpErrors.</p>
<p>I think this is a regression, although I might be wrong and it might be saving me from an incorrect result with certain strings.</p> Ruby master - Bug #13164 (Open): A second `SystemStackError` exception results in `Segmentation ...https://bugs.ruby-lang.org/issues/131642017-01-27T13:41:42Zmyst (Boaz Segev)
<p>This issue is was exposed by leveraging the fact that <code>Object#hash</code> is implemented recursively for core Ruby datatypes (i.e., Hash and Array). See the discussion here: <a href="https://github.com/boazsegev/combine_pdf/pull/91#issuecomment-275552131" class="external">https://github.com/boazsegev/combine_pdf/pull/91#issuecomment-275552131</a>.</p>
<p>TO reproduce the issue, explode the stack <strong>twice</strong>.</p>
<p>Expected results:</p>
<p>SystemStackError will be raised both times.</p>
<p>Actual results:</p>
<p>SystemStackError is raised once. The second time will cause a core dump.</p>
<p>Code to cause core dump:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">compute_nest_depth</span>
<span class="n">h</span> <span class="o">=</span> <span class="p">{</span><span class="ss">nest: </span><span class="p">{}}</span>
<span class="n">nest</span> <span class="o">=</span> <span class="n">h</span><span class="p">[</span><span class="ss">:nest</span><span class="p">]</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="kp">true</span>
<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="nb">puts</span> <span class="s2">"nested </span><span class="si">#{</span><span class="n">i</span><span class="si">}</span><span class="s2">"</span> <span class="k">if</span> <span class="p">((</span><span class="n">i</span> <span class="o">&</span> <span class="mi">511</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">next_nest</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">nest: </span><span class="p">{}</span> <span class="p">}</span>
<span class="n">nest</span><span class="p">[</span><span class="ss">:nest</span><span class="p">]</span> <span class="o">=</span> <span class="n">next_nest</span>
<span class="n">nest</span> <span class="o">=</span> <span class="n">next_nest</span><span class="p">[</span><span class="ss">:nest</span><span class="p">]</span>
<span class="n">h</span><span class="p">.</span><span class="nf">hash</span>
<span class="k">end</span>
<span class="k">rescue</span> <span class="no">SystemStackError</span>
<span class="nb">puts</span> <span class="s2">"Stack exploded at nesting </span><span class="si">#{</span><span class="n">i</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="n">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="kp">true</span><span class="p">)</span>
<span class="k">begin</span>
<span class="n">counter</span> <span class="o">+=</span><span class="mi">1</span>
<span class="nb">puts</span> <span class="s2">"starting test </span><span class="si">#{</span><span class="n">counter</span><span class="si">}</span><span class="s2">"</span>
<span class="n">compute_nest_depth</span>
<span class="k">rescue</span> <span class="no">SystemStackError</span> <span class="o">=></span> <span class="n">e</span>
<span class="kp">nil</span>
<span class="k">ensure</span>
<span class="nb">puts</span> <span class="s2">"test </span><span class="si">#{</span><span class="n">counter</span><span class="si">}</span><span class="s2"> complete"</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>results:</p>
<pre><code>starting test 1
nested 512
nested 1024
nested 1536
nested 2048
nested 2560
Stack exploded at nesting 2783
test 1 complete
starting test 2
nested 512
nested 1024
nested 1536
nested 2048
nested 2560
Segmentation fault (core dumped)
</code></pre> Ruby master - Bug #13151 (Open): File.writable? doesn't report correctly if a directory is writab...https://bugs.ruby-lang.org/issues/131512017-01-23T17:46:49Ztschoening (Thorsten Schöning)
<p>I've tried installing a gem per user using a 64 Bit version of Ruby for Windows and recognized that this failed because of permission errors. Ruby wanted to write the successfully downloaded gem to a system wide cache dir and failed because of missing permissions in that directly by default. I've reported the problem to rubygems and during investigation of the problem we recognized that File.writable? doesn't provide the correct information about if the target dir is writable or not under Windows. File.writable? ultimately checks using eaccess and access and Microsoft says the following about the latter:</p>
<blockquote>
<p>When used with directories, _access determines only whether the specified directory exists; in Windows 2000 and later operating systems, all directories have read and write access.</p>
</blockquote>
<p><a href="https://msdn.microsoft.com/en-us/library/1w06ktdy.aspx" class="external">https://msdn.microsoft.com/en-us/library/1w06ktdy.aspx</a></p>
<p>Because of the false return value, the downloaded gem is tried to be copied to the system wide cache dir and that fails. With win32-file there's a gem available which implements the correct check, because if that is required per user installation of a gem succeeds without even trying to copy anything system wide. The full story is on GitHub:</p>
<p><a href="https://github.com/rubygems/rubygems/issues/1784#issuecomment-274508768" class="external">https://github.com/rubygems/rubygems/issues/1784#issuecomment-274508768</a></p> Ruby master - Bug #12725 (Assigned): Trying to use ./miniruby before it existshttps://bugs.ruby-lang.org/issues/127252016-09-05T05:04:23Zduerst (Martin Dürst)duerst@it.aoyama.ac.jpRuby master - Bug #12689 (Open): Thread isolation of $~ and $_https://bugs.ruby-lang.org/issues/126892016-08-19T06:37:18Zheadius (Charles Nutter)headius@headius.com
<p>We are debating what is correct behavior now, and what should be correct behavior in the future, for the thread-visibility of the special variables <code>%~</code> and <code>$_</code></p>
<p>We have several examples from <a href="https://github.com/jruby/jruby/issues/3031" class="external">https://github.com/jruby/jruby/issues/3031</a> that seem to exhibit conflicting behavior...or at least the behavior is unexpected in many cases.</p>
<pre><code>$ ruby23 -e 'p = proc { p $~; "foo" =~ /foo/ }; Thread.new {p.call}.join; Thread.new{p.call}.join'
nil
nil
$ ruby23 -e 'def foo; proc { p $~; "foo" =~ /foo/ }; end; p = foo; Thread.new {p.call}.join; Thread.new{p.call}.join'
nil
#<MatchData "foo">
$ ruby23 -e 'p = proc { p $~; "foo" =~ /foo/ }; def foo(p); Thread.new {p.call}.join; Thread.new{p.call}.join; end; foo(p)'
nil
#<MatchData "foo">
$ ruby23 -e 'class Foo; P = proc { p $~; "foo" =~ /foo/ }; def foo; Thread.new {P.call}.join; Thread.new{P.call}.join; end; end; Foo.new.foo'
nil
#<MatchData "foo">
$ ruby23 -e 'def foo; p = proc { p $~; "foo" =~ /foo/ }; Thread.new {p.call}.join; Thread.new{p.call}.join; end; foo'
nil
nil
$ ruby23 -e 'def foo; p = proc { p $~; "foo" =~ /foo/ }; bar(p); end; def bar(p); Thread.new {p.call}.join; Thread.new{p.call}.join; end; foo'
nil
#<MatchData "foo">
</code></pre>
<p>These cases exhibit some oddities in whether $~ (and presumably $_) are shared across threads.</p>
<p>The immediate thought is that they should be both frame and thread-local...but ko1 points out that such a change would break cases like this:</p>
<pre><code>def foo
/foo/ =~ 'foo'
Proc.new{
p $~
}
end
Thread.new{
foo.call
}.join
</code></pre>
<p>So there's a clear conflict here. Users sometimes expect the $~ value to be shared across threads (at least for read, as in ko1's example) and sometimes do not want it shared at all (as in the case of <a href="https://github.com/jruby/jruby/issues/3031" class="external">https://github.com/jruby/jruby/issues/3031</a></p>
<p>Now we discuss.</p> Ruby master - Bug #12582 (Assigned): OpenSSL Authenticated Encryption should check for tag lengthhttps://bugs.ruby-lang.org/issues/125822016-07-11T07:35:30Zpatrick.oscity (Patrick Oscity)
<p>The current API for using ciphers with Authenticated Encryption (currently only AES-GCM) is rather misleading and quickly leads to subtle bugs related to the length of <code>auth_tag</code>.</p>
<p>In particular, the current implementation will <em>not</em> check for the length of the <code>auth_tag</code>. Because GCM mode allows arbitrary sizes of the <code>auth_tag</code> up to 128 bytes, only a single byte needs to be supplied to make the authentication pass. This means that an attacker needs at most 256 attempts in order to forge a valid <code>auth_tag</code>.</p>
<pre><code>data = 'secret'
cipher = OpenSSL::Cipher.new('aes-128-gcm')
cipher.encrypt
key = cipher.random_key
iv = cipher.random_iv
cipher.auth_data = 'auth_data'
ciphertext = cipher.update(data) + cipher.final
auth_tag = cipher.auth_tag
auth_tag = auth_tag[0] # single byte is sufficient
cipher = OpenSSL::Cipher.new('aes-128-gcm')
cipher.decrypt
cipher.key = key
cipher.iv = iv
cipher.auth_tag = auth_tag
cipher.auth_data = 'auth_data'
data = cipher.update(ciphertext) + cipher.final
# NO error raised
</code></pre>
<p>Currently, the only way to prevent such attacks is to manually assert the correct <code>auth_tag</code> length when decrypting/authenticating.</p>
<pre><code>raise 'incorrect auth_tag length' unless auth_tag.length == 16
</code></pre>
<p>I suggest the following improvements:</p>
<a name="Documentation-should-mention-the-importance-of-manually-checking-auth_tag-length"></a>
<h3 >Documentation should mention the importance of manually checking <code>auth_tag</code> length<a href="#Documentation-should-mention-the-importance-of-manually-checking-auth_tag-length" class="wiki-anchor">¶</a></h3>
<p>This can/should be done immediately even if the API should not change.</p>
<a name="Authentication-tag-length-should-be-an-input-parameter-to-the-cipher"></a>
<h3 >Authentication tag length should be an input parameter to the cipher<a href="#Authentication-tag-length-should-be-an-input-parameter-to-the-cipher" class="wiki-anchor">¶</a></h3>
<p>To improve the usability of the API and unburden users from performing additional manual checks without compromising security, I suggest to add an <code>auth_tag_len</code> accessor. This can be used to determine the size of the <code>auth_tag</code> both when generating and when authenticating the <code>auth_tag</code>. The default value should be 16 bytes (see below).</p>
<h3>
<code>#auth_tag</code> should use <code>auth_tag_len</code> to determine the output length</h3>
<p>During encryption:</p>
<p>If no parameter is given, <code>#auth_tag</code> should return an authentication tag according to the length configured in <code>auth_tag_len</code>.</p>
<p>If a length parameter is given, <code>#auth_tag</code> should use the supplied parameter to determine the length of the authentication tag. Although this parameter is not as useful any more it should be kept for backwards compatibility. Maybe it should be deprecated.</p>
<p>Currently the API supports different tag lengths by passing the length parameter to <code>#auth_tag</code>. This currently defaults to 16 bytes, which should be the default value for <code>auth_tag_len</code> in order to keep backwards compatibility.</p>
<h3>
<code>#final</code> should use <code>auth_tag_len</code> to assert the correct length of the <code>auth_tag</code>
</h3>
<p>During decryption:</p>
<p><code>auth_tag_len</code> should be used to assert that the supplied <code>auth_tag</code> has the correct length. The big difference to the existing API lies here, because users need to actively change the value of <code>auth_tag_len</code> in order to allow shorter tags.</p>
<p>When the check fails, an <code>OpenSSL::Cipher::CipherError</code> should be raised. The same type of error is already raised when authentication fails, so existing users should be fine without having to touch their error handling. A descriptive error message should be helpful. In order to distinguish between such errors and "actual" verification errors, we could also add a descriptive message for the latter.</p>
<p>I'd be happy to implement these changes, but I wanted to discuss them first.</p> Ruby master - Bug #12506 (Assigned): On cygwin, Feature #5994 does not workhttps://bugs.ruby-lang.org/issues/125062016-06-19T08:18:47Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<p>On cygwin, Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Dir.glob without wildcards returns pattern, not filename (Closed)" href="https://bugs.ruby-lang.org/issues/5994">#5994</a> doesn't seem to have been implemented. This can be confirmed with test/ruby/test_dir.rb (see the very end of this report), or even simpler, as follows:</p>
<pre><code>duerst@Arnisee /cygdrive/c/Data/testCygwin
$ ruby -e 'Dir.mkdir("Matsumoto")'
duerst@Arnisee /cygdrive/c/Data/testCygwin
$ ruby -e 'puts Dir.glob("Ma*to")'
Matsumoto
duerst@Arnisee /cygdrive/c/Data/testCygwin
$ ruby -e 'puts Dir.glob("ma*to")'
duerst@Arnisee /cygdrive/c/Data/testCygwin
$ ruby -e 'puts Dir.glob("matsumoto")'
matsumoto
</code></pre>
<p>The 4th execution shows the problem. Please note that the third execution is also strange.</p>
<pre><code>$ bin/ruby test/runner.rb test/ruby/test_dir.rb
Run options:
# Running tests:
[10/23] TestDir#test_glob_cases = 0.11 s
1) Failure:
TestDir#test_glob_cases [/cygdrive/c/Data/ruby/test/ruby/test_dir.rb:255]:
<a href="/issues/5994">[ruby-core:42469]</a> [Feature #5994]
Dir.glob should return the filename with actual cases on the filesystem.
<["FileWithCases"]> expected but was
<["filewithcases"]>.
Finished tests in 3.294094s, 6.9822 tests/s, 77.7148 assertions/s.
23 tests, 256 assertions, 1 failures, 0 errors, 0 skips
ruby -v: ruby 2.4.0dev (2016-06-19 trunk 55452) [x86_64-cygwin]
</code></pre> Ruby master - Bug #12445 (Assigned): Testing TestIO#test_open_fifo_does_not_block_other_threads r...https://bugs.ruby-lang.org/issues/124452016-05-31T10:15:12Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<p>When I run <code>bin/ruby test/runner.rb test/ruby/test_*</code>, testing stops at <code>TestIO#test_open_fifo_does_not_block_other_threads</code>. Checking the task manager shows that this is a deadlock (there are two ruby interpreters running, but they don't use any CPU at all).</p>
<p>This is what I see for ages:</p>
<pre><code>[1589/4545] TestIO#test_open_fifo_does_not_block_other_threads
</code></pre> Ruby master - Bug #12444 (Assigned): Segmentation fault when running TestException#test_machine_s...https://bugs.ruby-lang.org/issues/124442016-05-31T10:10:48Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<p>When I try to run <code>bin/ruby test/runner.rb test/ruby/test_*</code>, I get the error below. This is immediately followed by a very similar error for TestException#test_machine_stackoverflow_by_define_method.</p>
<pre><code>[ 942/4545] TestException#test_machine_stackoverflow = 1.27 s
19) Failure:
TestException#test_machine_stackoverflow [/cygdrive/c/Data/ruby/test/ruby/test_exception.rb:577]:
pid 16416 killed by SIGABRT (signal 6) (core dumped)
| -:7: [BUG] Segmentation fault at 0x000000ffe03fc0
| ruby 2.4.0dev (2016-05-31 trunk 55228) [x86_64-cygwin]
|
| -- Control frame information -----------------------------------------------
| c:0690 p:0014 s:1387 e:001386 LAMBDA -:7 [FINISH]
| c:0689 p:0014 s:1385 e:001384 LAMBDA -:7 [FINISH]
| c:0688 p:0014 s:1383 e:001382 LAMBDA -:7 [FINISH]
| c:0687 p:0014 s:1381 e:001380 LAMBDA -:7 [FINISH]
| c:0686 p:0014 s:1379 e:001378 LAMBDA -:7 [FINISH]
| c:0685 p:0014 s:1377 e:001376 LAMBDA -:7 [FINISH]
| c:0684 p:0014 s:1375 e:001374 LAMBDA -:7 [FINISH]
| c:0683 p:0014 s:1373 e:001372 LAMBDA -:7 [FINISH]
| c:0682 p:0014 s:1371 e:001370 LAMBDA -:7 [FINISH]
| c:0681 p:0014 s:1369 e:001368 LAMBDA -:7 [FINISH]
</code></pre>
<p>[very long list, ending in]</p>
<pre><code>| c:0009 p:0014 s:0025 e:000024 LAMBDA -:7 [FINISH]
| c:0008 p:0014 s:0023 e:000022 LAMBDA -:7 [FINISH]
| c:0007 p:0014 s:0021 e:000020 LAMBDA -:7 [FINISH]
| c:0006 p:0014 s:0019 e:000018 LAMBDA -:7 [FINISH]
| c:0005 p:0014 s:0017 e:000016 LAMBDA -:7 [FINISH]
| c:0004 p:0028 s:0015 E:001588 BLOCK -:8
| c:0003 p:0052 s:0012 e:000011 METHOD /cygdrive/c/Data/ruby/test/lib/test/unit/assertions.rb:74
| c:0002 p:0047 s:0004 E:000610 EVAL -:6 [FINISH]
| c:0001 p:0000 s:0002 E:001930 (none) [FINISH]
|
| -- Ruby level backtrace information ----------------------------------------
| -:6:in `<main>'
| /cygdrive/c/Data/ruby/test/lib/test/unit/assertions.rb:74:in `assert_raise'
| -:8:in `block in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
</code></pre>
<p>[again very long list, probably about same length, ending with]</p>
<pre><code>| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
| -:7:in `block (2 levels) in <main>'
|
| -- Other runtime information -----------------------------------------------
|
| * Loaded script: -
|
| * Loaded features:
|
| 0 enumerator.so
| 1 thread.rb
| 2 rational.so
| 3 complex.so
| 4 /cygdrive/c/Data/ruby/lib/ruby/2.4.0/x86_64-cygwin/enc/encdb.so
| 5 /cygdrive/c/Data/ruby/lib/ruby/2.4.0/x86_64-cygwin/enc/trans/transdb.so
| 6 /cygdrive/c/Data/ruby/lib/ruby/2.4.0/x86_64-cygwin/enc/windows_31j.so
| 7 /cygdrive/c/Data/ruby/lib/ruby/vendor_ruby/unicode_normalize.rb
| 8 /cygdrive/c/Data/ruby/lib/ruby/vendor_ruby/optparse.rb
| 9 /cygdrive/c/Data/ruby/lib/ruby/2.4.0/x86_64-cygwin/rbconfig.rb
| 10 /cygdrive/c/Data/ruby/test/lib/leakchecker.rb
| 11 /cygdrive/c/Data/ruby/test/lib/minitest/unit.rb
| 12 /cygdrive/c/Data/ruby/lib/ruby/vendor_ruby/prettyprint.rb
| 13 /cygdrive/c/Data/ruby/lib/ruby/vendor_ruby/pp.rb
| 14 /cygdrive/c/Data/ruby/test/lib/test/unit/assertions.rb
| 15 /cygdrive/c/Data/ruby/lib/ruby/vendor_ruby/open3.rb
| 16 /cygdrive/c/Data/ruby/lib/ruby/vendor_ruby/timeout.rb
| 17 /cygdrive/c/Data/ruby/test/lib/find_executable.rb
| 18 /cygdrive/c/Data/ruby/lib/ruby/2.4.0/x86_64-cygwin/rbconfig/sizeof.so
| 19 /cygdrive/c/Data/ruby/test/lib/envutil.rb
| 20 /cygdrive/c/Data/ruby/test/lib/test/unit/testcase.rb
| 21 /cygdrive/c/Data/ruby/test/lib/test/unit.rb
|
| [NOTE]
| You may have encountered a bug in the Ruby interpreter or extension libraries.
| Bug reports are welcome.
| For details: http://www.ruby-lang.org/bugreport.html
|
</code></pre> Ruby master - Bug #12442 (Assigned): TestArgf#test_textmode fails on cygwinhttps://bugs.ruby-lang.org/issues/124422016-05-31T10:01:19Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<p>When I try to run <code>bin/ruby test/runner.rb test/ruby/test_*</code> (because <code>make test-all</code> doesn't work), the first failure that I get is as below.</p>
<pre><code>$ bin/ruby test/runner.rb test/ruby/test_*
Run options:
# Running tests:
[ 156/4545] TestArgf#test_textmode = 1.60 s
1) Failure:
TestArgf#test_textmode [/cygdrive/c/Data/ruby/test/ruby/test_argf.rb:685]:
<a href="/issues/5268">[ruby-core:39234]</a>.
<"1\n2\n3\n4\n5\n6\n"> expected but was
<"1\n2\n3\n4\n5\r\n6\r\n">.
</code></pre> Ruby master - Bug #12179 (Open): Build failure due to VPATH expansionhttps://bugs.ruby-lang.org/issues/121792016-03-15T17:19:40Zrhenium (Kazuki Yamaguchi)k@rhe.jp
<p>On my environment (GNU Make 4.1), I can reproduce in this way:</p>
<pre><code class="sh syntaxhl" data-language="sh"><span class="nb">cd</span> /tmp
svn co http://svn.ruby-lang.org/repos/ruby/trunk ruby-src
<span class="nb">cd </span>ruby-src
autoconf <span class="o">&&</span> ./configure
<span class="nb">mkdir</span> <span class="nt">-p</span> /tmp/.ext/.timestamp/
<span class="nb">touch</span> /tmp/.ext/.timestamp/.RUBYARCHDIR.-.-test-.-.fatal.time
make <span class="nv">V</span><span class="o">=</span>1
</code></pre>
<p>results in:</p>
<pre><code>...
make[2]: Entering directory '/tmp/ruby-src/ext/-test-/fatal'
rm -f ../../../.ext/x86_64-linux/-test-/fatal/rb_fatal.so
gcc -shared -o ../../../.ext/x86_64-linux/-test-/fatal/rb_fatal.so rb_fatal.o -L. -L../../.. -L. -fstack-protector -rdynamic -Wl,-export-dynamic -lpthread -lgmp -ldl -lcrypt -lm -lc
/usr/bin/ld: cannot open output file ../../../.ext/x86_64-linux/-test-/fatal/rb_fatal.so: No such file or directory
collect2: error: ld returned 1 exit status
Makefile:260: recipe for target '../../../.ext/x86_64-linux/-test-/fatal/rb_fatal.so' failed
make[2]: *** [../../../.ext/x86_64-linux/-test-/fatal/rb_fatal.so] Error 1
make[2]: Leaving directory '/tmp/ruby-src/ext/-test-/fatal'
exts.mk:88: recipe for target 'ext/-test-/fatal/all' failed
...
</code></pre>
<p>This error happens because <code>/tmp/ruby-src/.ext/x86_64-linux/-test-/fatal</code> is not properly created.</p>
<p>This is because of the VPATH set in <code>ext/-test-/fatal/Makefile</code>:</p>
<pre><code>srcdir = $(top_srcdir)/ext/-test-/fatal
topdir = ../../..
hdrdir = $(top_srcdir)/include
arch_hdrdir = $(extout)/include/$(arch)
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
extout = $(topdir)/.ext
TIMESTAMP_DIR = $(extout)/.timestamp
$(TIMESTAMP_DIR)/.RUBYARCHDIR.-.-test-.-.fatal.time:
$(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR)
$(Q) $(TOUCH) $@
$(RUBYARCHDIR)/$(DLLIB): $(OBJS) Makefile $(TIMESTAMP_DIR)/.RUBYARCHDIR.-.-test-.-.fatal.time
$(ECHO) linking shared-object -test-/fatal/$(DLLIB)
...
</code></pre>
<p><code>$(TIMESTAMP_DIR)/.RUBYARCHDIR.-.-test-.-.fatal.time</code> target should create the directory prior to linking, but it doesn't work.<br>
Since the Makefile has VPATH, make wrongly finds <code>$(TIMESTAMP_DIR)/.RUBYARCHDIR.-.-test-.-.fatal.time</code> at <code>$(hdrdir)/ruby</code>, that is <code>/tmp/.ext/.timestamp/.RUBYARCHDIR.-.-test-.-.fatal.time</code>.</p> Ruby master - Bug #12040 (Assigned): [Win32] File.stat fails on a mounted volumehttps://bugs.ruby-lang.org/issues/120402016-02-01T08:13:24Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<p>On Windows, <code>File.stat</code> fails on the volume mount point directory whose name contains <code>"..."</code>.</p>
<p>Where <code>%vol%</code> is the volume ID of a new VHD volume,</p>
<pre><code>C:> set vol
\\?\Volume{3C458AE9-C8B1-11E5-A233-0800271D089F}\
C:> mkdir x...y
C:> mountvol x...y %vol%
C:> .\miniruby -e "p Dir.chdir('x...y'){File.stat('.')}" -e "p File.stat('x...y')"
#<File::Stat dev=0x2, ino=1407374883553285, mode=040755, nlink=1, uid=0, gid=0, rdev=0x2, size=4096, blksize=nil, blocks=nil, atime=2016-02-01 16:35:45 +0900, mtime=2016-02-01 16:35:45 +0900, ctime=2016-02-01 16:35:45 +0900>
-e:2:in `stat': No such file or directory @ rb_file_s_stat - x...y (Errno::ENOENT)
from -e:2:in `<main>'
</code></pre>
<p>Note that <code>Dir.chdir</code> and <code>File.stat</code> there succeed.<br>
This failures depends on the mount point name, because of <code>check_valid_dir()</code>.</p> Ruby master - Bug #11438 (Open): native_thread_init_stack() get machine.stack_start unequal to th...https://bugs.ruby-lang.org/issues/114382015-08-13T07:31:10Zrickerliang (l ly)rickerliang@outlook.com
<p>In function native_thread_init_stack() use VirtualQuery to get thread's stack start address.But some situation(ruby embbed in other application and initial it on the fly),native_thread_init_stack() will be called at low stack address and VirtualQuery return memory info BaseAddress + RegionSize < thread stack base(teb.StackBase).<br>
In this situation,subsequently call stack_check() at high stack address will cause stack_overflow exception,because esp > machine.stack_start:<br>
(teb.StackLimit < machine.stack_start < esp < teb.StackBase)<br>
but actually it is not stack overflow at this time.<br>
Use teb.StackBase instead of VirtualQuery get thread stack base is a more reliable solution.</p> Ruby master - Bug #10128 (Open): Quoting problem for arguments of Kernel.system, Kernel.exec on W...https://bugs.ruby-lang.org/issues/101282014-08-12T16:18:30ZMaxLap (Maxime Lapointe)hunter_spawn@hotmail.com
<p>On Windows, the methods that call shell commands and receive the parameters individually sometimes do not wrap the parameters sent in quotes.<br>
This results in Windows either splitting the parameter in 2 parameters or, worse, splitting the command in 2 commands.</p>
<p>I joined the file <em>puts_first.bat</em>, which simply outputs the first argument it received. When the parameter received was wrapped by ruby, you will see quotes, it's normal. Just run a irb from from the directory containing that file.</p>
<p>Lines that don't work properly (Using Kernel.exec will do the same thing):</p>
<pre><code># these write *hello*, then says 'world' is not recognized as an internal or external command
Kernel.system 'puts_first.bat', 'hello&world'
Kernel.system 'puts_first.bat', 'hello|world'
# these write *hello*
Kernel.system 'puts_first.bat', 'hello,world'
Kernel.system 'puts_first.bat', 'hello;world'
Kernel.system 'puts_first.bat', 'hello<world'
# this writes *hello* in the file world
Kernel.system 'puts_first.bat', 'hello>world'
# this writes *helloworld* without the ^
Kernel.system 'puts_first.bat', 'hello^world'
</code></pre>
<p>If we add a space anywhere in the above hello world strings, it will work as expected because ruby wraps the parameter if it finds a space.</p>
<pre><code># Ruby does try to wrap if it finds a double quote, but it escapes double quotes incorrectly:
# this writes *"hello\"world"*, double quotes should be escaped by putting 2 of them, so we should see: *"hello""world"*
Kernel.system 'puts_first.bat', 'hello"world'
# adding a space show the problem in action, this writes *"hello\"*
Kernel.system 'puts_first.bat', 'hello" world'
</code></pre>
<p>As a side note, the single quote is not special in Windows, so there is no need to wrap this (but I don't think it's a problem):</p>
<pre><code># this writes *"hello'world"*
Kernel.system 'puts_first.bat', "hello'world"
</code></pre>
<p>This bug also happens in 1.9.3, do you think this be backported?</p>
<p>Unless I did a mistake, this should be all of the problematic characters, I tested with every printable ascii characters.</p>
<p>Thank you</p> Ruby master - Bug #10009 (Open): IO operation is 10x slower in multi-thread environmenthttps://bugs.ruby-lang.org/issues/100092014-07-06T07:35:01Zariveira (Alexandre Riveira)alexandre@objectdata.com.br
<p>I created this issue <a class="issue tracker-5 status-1 priority-4 priority-default" title="Misc: better concurrency in threads (Open)" href="https://bugs.ruby-lang.org/issues/9832">#9832</a> but not have io operation.<br>
In the script attached I simulate IO operation in multi-thread environment.<br>
For ruby 1.9.2 apply <code>taskset -c -p 2 #{Process.pid}</code> for regulates threads behavior.<br>
The second Thread is a io operation</p>
<p>My results:</p>
<ol>
<li>
<p>ruby 2.1.2<br>
first 43500194<br>
second 95<br>
third 42184385</p>
</li>
<li>
<p>ruby-2.0.0-p451<br>
first 38418401<br>
second 95<br>
third 37444470</p>
</li>
<li>
<p>1.9.3-p545<br>
first 121260313<br>
second 50<br>
third 44275164</p>
</li>
<li>
<p>1.9.2-p320<br>
first 31189901<br>
second 897 <============<br>
third 31190598</p>
</li>
</ol>
<p>Regards</p>
<p>Alexandre Riveira</p> Ruby master - Bug #9189 (Assigned): Build failure on Windows in case of nonascii TEMP environment.https://bugs.ruby-lang.org/issues/91892013-12-01T18:06:20Zphasis68 (Heesob Park)phasis@gmail.com
<p>I experienced a build failure during build extension library with trunk on Windows.</p>
<pre><code>make[2]: Entering directory `/c/work/ruby-2.1.0-r43936/ext/bigdecimal'
generating bigdecimal-i386-mingw32.def
compiling bigdecimal.c
In file included from bigdecimal.c:20:0:
bigdecimal.h:62:1: error: static declaration of 'labs' follows non-static declar
ation
make[2]: *** [bigdecimal.o] Error 1
make[2]: Leaving directory `/c/work/ruby-2.1.0-r43936/ext/bigdecimal'
make[1]: *** [ext/bigdecimal/all] Error 2
make[1]: Leaving directory `/c/work/ruby-2.1.0-r43936'
make: *** [build-ext] Error 2
</code></pre>
<p>I found the cause of this error is mkmk failure.<br>
Here is a part of mkmf.log</p>
<pre><code>have_func: checking for labs() in stdlib.h... -------------------- no
"i686-w64-mingw32-gcc -o conftest.exe -I../../.ext/include/i386-mingw32 -I../.././include -I../.././ext/bigdecimal -D_WIN32_WINNT=0x0501 -D_FILE_OFFSET_BITS=64 -O3 -fno-omit-frame-pointer -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration conftest.c -L. -L../.. -L. -lmsvcrt-ruby210-static -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi "
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Cannot create temporary file in C:\Users\??苑?AppData\Local\Temp\: Invalid argument
</code></pre>
<p>The TEMP environment varable is</p>
<pre><code>C:\work\ruby-2.1.0-r43936>set TEMP
TEMP=C:\Users\희섭\AppData\Local\Temp
</code></pre>
<p>It seems that miniruby cannot handle encoding properly.</p>
<pre><code>C:\work\ruby-2.1.0-r43936>miniruby -ve "p ENV['TEMP']"
ruby 2.1.0dev (2013-11-30 trunk 43936) [i386-mingw32]
"C:\\Users\\\xED\x9D\xAC\xEC\x84\xAD\\AppData\\Local\\Temp"
C:\work\ruby-2.1.0-r43936>miniruby.exe -ve "p ENV['TEMP'].encoding"
ruby 2.1.0dev (2013-11-30 trunk 43936) [i386-mingw32]
#<Encoding:ASCII-8BIT>
</code></pre>
<p>Whereas, the final ruby can handle encoding properly.</p>
<pre><code>C:\work>ruby -ve "p ENV['TEMP']"
ruby 2.1.0dev (2013-11-30 trunk 43923) [i386-mingw32]
"C:\\Users\\희섭\\AppData\\Local\\Temp"
C:\work>ruby -ve "p ENV['TEMP'].encoding"
ruby 2.1.0dev (2013-11-30 trunk 43923) [i386-mingw32]
#<Encoding:CP949>
</code></pre> Ruby master - Bug #9115 (Assigned): Logger traps all exceptions; breaks Timeouthttps://bugs.ruby-lang.org/issues/91152013-11-16T12:30:25Zcphoenix (Chris Phoenix)cphoenix@gmail.com
<p>Line 577-579 of logger.rb</p>
<pre><code> rescue Exception => ignored
warn("log writing failed. #{ignored}")
end
</code></pre>
<p>Thus, when the system times out in the middle of writing a log message, it warns "log writing failed. execution expired" and just keeps right on running.</p>
<p>This is true in 1.9.3 as well. I haven't looked at older versions.</p>
<p>Pardon me while I go grep "rescue Exception" in the entire Ruby codebase, and see whether I can reliably use Timeout at all...</p>
<p>OK, you might check out C:\Ruby200\lib\ruby\gems\2.0.0\gems\activerecord-3.2.13\lib\active_record\railties\databases.rake</p>
<p>All the other "rescue Exception" seem to re-raise it, except maybe C:\Ruby200\lib\ruby\2.0.0\xmlrpc\server.rb and C:\Ruby200\lib\ruby\gems\2.0.0\gems\activesupport-3.2.13\lib\active_support\callbacks.rb</p> Ruby master - Bug #9010 (Assigned): ./configure --prefix= cannot handle directories with spaceshttps://bugs.ruby-lang.org/issues/90102013-10-10T07:50:41Zpostmodern (Hal Brodigan)postmodern.mod3@gmail.com
<p>It appears that the linking task fails when the --prefix value contains spaces.</p>
<p>Steps to Reproduce:</p>
<ol>
<li>./configure --prefix="$HOME/foo bar"</li>
<li>make</li>
</ol>
<p>Expected Result: success<br>
Actual Result:</p>
<p>make[2]: Entering directory <code>/home/hal/src/ruby-2.0.0-p247' linking ruby gcc: error: bar/lib: No such file or directory gcc: error: bar/lib: No such file or directory make[2]: *** [ruby] Error 1 make[2]: Leaving directory </code>/home/hal/src/ruby-2.0.0-p247'<br>
make[1]: *** [all] Error 2<br>
make[1]: Leaving directory `/home/hal/src/ruby-2.0.0-p247'<br>
make: *** [build-ext] Error 2</p> Ruby master - Bug #8445 (Assigned): IO.open and IO#set_enconding does not support :fallback optionhttps://bugs.ruby-lang.org/issues/84452013-05-24T22:03:00Zpjmtdw (Haruhiro Yoshimoto)pjmtdw@gmail.com
<p>RubyDoc says that <code>IO.open</code> and <code>IO#set_encoding</code> supports optional argument defined in <code>String#encode</code>.<br>
<a href="http://ruby-doc.org/core-2.0/IO.html#method-c-new-label-Options" class="external">http://ruby-doc.org/core-2.0/IO.html#method-c-new-label-Options</a><br>
In fact, <code>:invalid, :undef and :replace</code> works as expected.</p>
<p>However, <code>:fallback</code> option does not work neither for <code>IO.open</code> and <code>IO#set_encoding</code>.<br>
Following is the example code which does not work.<br>
<code>f(x)</code> is never called even if hoge.txt contains non convertible character.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s2">"./hoge.txt"</span><span class="p">,</span><span class="s2">"r:Shift_JIS:utf-8"</span><span class="p">,</span> <span class="ss">:fallback</span> <span class="o">=></span> <span class="nb">lambda</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="n">f</span><span class="p">(</span><span class="n">x</span><span class="p">)}){</span><span class="o">|</span><span class="n">f</span><span class="o">|</span>
<span class="o">...</span>
<span class="p">}</span>
<span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s2">"./hoge.txt"</span><span class="p">){</span><span class="o">|</span><span class="n">f</span><span class="o">|</span>
<span class="n">f</span><span class="p">.</span><span class="nf">set_encoding</span><span class="p">(</span><span class="s2">"Shift_JIS"</span><span class="p">,</span><span class="s2">"utf-8"</span><span class="p">,</span><span class="ss">:fallback</span> <span class="o">=></span> <span class="nb">lambda</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="n">f</span><span class="p">(</span><span class="n">x</span><span class="p">)})</span>
<span class="o">...</span>
<span class="p">}</span>
</code></pre>
<p>I Think this is because <code>fill_cbuf()</code> in <code>io.c</code> calls <code>rb_econv_convert()</code> from <code>transcode.c</code> directly.<br>
On the other hand, <code>fallback_func</code> is called in <code>transcode_loop()</code>, which is called by <code>str_encode()</code>.</p>
<p>Since <code>transcode_loop()</code> also calls <code>rb_econv_convert()</code>, I wrote a small patch which moves some codes from<br>
<code>transcode_loop()</code> to <code>rb_econv_convert()</code> to fix the problem.</p>
<p>The attached file is the patch. Hope this helps.</p> Ruby master - Bug #8185 (Open): Thread/fork issuehttps://bugs.ruby-lang.org/issues/81852013-03-30T03:33:57ZAnonymous
<p>Hello all,</p>
<p>I've found an issue where calling fork inside a thread, and passing a block<br>
to the fork, causes the forked process to continue after the block. I've<br>
reproduced the issue on the following versions of ruby:<br>
ruby 2.0.0p100 (2013-03-27 revision 39954) [x86_64-darwin10.8.0]<br>
ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-darwin10.8.0]</p>
<p>Here is the script I used to reproduce:</p>
<p>1000.times do |j|<br>
puts "run #{j}"<br>
threads = []<br>
100.times do |i|<br>
threads << Thread.new(i) do |local_i|<br>
opid = fork do<br>
# exit!(true) # fixes the issue<br>
# exit(true) # doesn't fix the issue<br>
# no 'exit' also exhibits issue<br>
end<br>
::Process.waitpid(opid, 0)<br>
File.open("/tmp/test_thread_fork_#{local_i}.pid", "w") {|f| f.write<br>
"1" }<br>
end<br>
end<br>
threads.map { |t| t.join }</p>
<p>borked = false<br>
100.times do |i|<br>
fn = "/tmp/test_thread_fork_#{i}.pid"<br>
contents = File.read(fn)<br>
if contents.size > 1<br>
puts "file #{fn} was written to many times (#{contents})"<br>
borked = true<br>
end<br>
end<br>
exit(false) if borked<br>
end</p>
<p>As you can see from the comments inside the fork I can work around the<br>
issue by using "exit!". I am correct in understanding that there should be<br>
no case in which the file is written to multiple times, correct?</p>
<p>Thank you,<br>
Jason Gladish</p> Ruby master - Bug #7968 (Assigned): Poor UDPSocket#send performance in ruby 2.0.0 on windowshttps://bugs.ruby-lang.org/issues/79682013-02-26T20:55:25Zcs96and (Alan Davies)alan.n.davies@gmail.com
<p>I have noticed that the performance of UDPSocket#send on ruby 2.0.0 on windows is much poorer than that of 1.9.3 or 1.8.7. Running the attahced script on 2.0.0 gives the following...</p>
<p>d:\scripts>bash -c "ruby --version"<br>
ruby 2.0.0p0 (2013-02-24) [x64-mingw32]</p>
<p>d:\scripts>bash -c "time ruby socketsendtest.rb"</p>
<p>real 0m2.572s<br>
user 0m0.000s<br>
sys 0m0.016s</p>
<p>However, running the same test with 1.9.3 is much faster...</p>
<p>d:\scripts>pik 193</p>
<p>d:\scripts>bash -c "ruby --version"<br>
ruby 1.9.3p374 (2013-01-15) [i386-mingw32]</p>
<p>d:\scripts>bash -c "time ruby socketsendtest.rb"</p>
<p>real 0m0.993s<br>
user 0m0.015s<br>
sys 0m0.016s</p>
<p>Additionally, if I change the send call to a print (commented out in the script), then the performance is fine on 2.0.0....</p>
<p>d:\scripts>pik 200</p>
<p>d:\scripts>bash -c "ruby --version"<br>
ruby 2.0.0p0 (2013-02-24) [x64-mingw32]</p>
<p>d:\scripts>bash -c "time ruby socketsendtest.rb"</p>
<p>real 0m0.907s<br>
user 0m0.000s<br>
sys 0m0.015s</p>
<p>What is send() doing that print() doesn't do that is causing the massive performance drop?</p>
<p>Thanks<br>
Alan.</p> Ruby master - Bug #7964 (Assigned): Writing an ASCII-8BIT String to a StringIO created from a UTF...https://bugs.ruby-lang.org/issues/79642013-02-26T16:32:50Zbrixen (Brian Shirai)brixen@gmail.com
<p>=begin<br>
In the following script, an ASCII-8BIT String is written to a StringIO created with a UTF-8 String without error. However, a << b or a + b will raise an exception, as will writing an ASCII-8BIT String to a File with UTF-8 external encoding.</p>
<ul>
<li>
<p>$ cat file_enc.rb</p>
<a name="encoding-utf-8"></a>
<h1 >encoding: utf-8<a href="#encoding-utf-8" class="wiki-anchor">¶</a></h1>
<p>require 'stringio'</p>
<p>a = "On a very cold morning, it was -8°F."<br>
b = a.dup.force_encoding "ascii-8bit"</p>
<p>io = StringIO.new a<br>
io.write(b)<br>
p io.string.encoding</p>
<p>File.open "data.txt", "w:utf-8" do |f|<br>
f.write a<br>
f.write b<br>
end</p>
</li>
<li>
<p>$ ruby2.0 -v file_enc.rb<br>
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin10.8.0]<br>
#<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a><br>
file_enc.rb:13:in <code>write': "\xC2" from ASCII-8BIT to UTF-8 (Encoding::UndefinedConversionError) from file_enc.rb:13:in </code>block in '<br>
from file_enc.rb:11:in <code>open' from file_enc.rb:11:in </code>'</p>
</li>
<li>
<p>$ ruby1.9.3 -v file_enc.rb<br>
ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-darwin10.8.0]<br>
#<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a><br>
file_enc.rb:13:in <code>write': "\xC2" from ASCII-8BIT to UTF-8 (Encoding::UndefinedConversionError) from file_enc.rb:13:in </code>block in '<br>
from file_enc.rb:11:in <code>open' from file_enc.rb:11:in </code>'<br>
=end</p>
</li>
</ul> Ruby master - Bug #7892 (Open): MIME encoding bug of NKF.nkfhttps://bugs.ruby-lang.org/issues/78922013-02-20T16:01:52Zmrkn (Kenta Murata)muraken@gmail.com
<p>NKF の MIME encoding の結果が 1.8 と 1.9/2.0 で異なってます。</p>
<a name="18-の場合"></a>
<h1 >1.8 の場合<a href="#18-の場合" class="wiki-anchor">¶</a></h1>
<p>$ /usr/bin/ruby -rnkf -ve "puts NKF.nkf('-jW -M --cp932', '「あああああああああああ by ああああああああああ」のレシピ')"<br>
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin11.0]<br>
=?ISO-2022-JP?B?GyRCIVYkIiQiJCIkIiQiJCIkIiQiJCIkIiQiGyhC?= by<br>
=?ISO-2022-JP?B?GyRCJCIkIiQiJCIkIiQiJCIkIiQiJCIhVyROJWwlNyVUGyhC?=</p>
<a name="193-p385-の場合"></a>
<h1 >1.9.3-p385 の場合<a href="#193-p385-の場合" class="wiki-anchor">¶</a></h1>
<p>$ ruby -rnkf -ve "puts NKF.nkf('-jW -M --cp932', '「あああああああああああ by ああああああああああ」のレシピ')"<br>
ruby 1.9.3p385 (2013-02-06 revision 39114) [x86_64-darwin11.4.2]<br>
=?ISO-2022-JP?B?GyRCIVYkIiQiJCIkIiQiJCIkIiQiJCIkIiQiGyhC?= by<br>
=?US-ASCII?Q??=<br>
=?ISO-2022-JP?B?GyRCJCIkIiQiJCIkIiQiJCIkIiQiJCIhVyROJWwlNyVUGyhC?=</p>
<a name="200-rc2-の場合"></a>
<h1 >2.0.0-rc2 の場合<a href="#200-rc2-の場合" class="wiki-anchor">¶</a></h1>
<p>$ RBENV_VERSION=2.0.0-rc2 rbenv exec ruby -rnkf -ve "puts NKF.nkf('-jW -M --cp932', '「あああああああああああ by ああああああああああ」のレシピ')"<br>
ruby 2.0.0dev (2013-02-08 trunk 39161) [x86_64-darwin11.4.2]<br>
=?ISO-2022-JP?B?GyRCIVYkIiQiJCIkIiQiJCIkIiQiJCIkIiQiGyhC?= by<br>
=?US-ASCII?Q??=<br>
=?ISO-2022-JP?B?GyRCJCIkIiQiJCIkIiQiJCIkIiQiJCIhVyROJWwlNyVUGyhC?=</p> Ruby master - Bug #6360 (Assigned): Debug information build even without requesting ithttps://bugs.ruby-lang.org/issues/63602012-04-26T08:46:44Zluislavena (Luis Lavena)luislavena@gmail.com
<p>Hello,</p>
<p>While working on latest RubyInstaller release for 1.9.3-p194 our team detected a bigger shared library and import library being generated.</p>
<p>After further inspection, we found this commit:<br>
<a href="https://github.com/ruby/ruby/commit/ffdaca1d748804f2b5ca2de612f17cf6c78d351b" class="external">https://github.com/ruby/ruby/commit/ffdaca1d748804f2b5ca2de612f17cf6c78d351b</a></p>
<p>Backported r34840 into ruby_1_9_3 branch</p>
<p>The above change added -ggdb to CFLAGS even when was not provided by debugflags configure option.</p>
<p>The following is the comparison of "make" summary with and without the change:</p>
<p>Current trunk:</p>
<pre>
C:\Users\Luis\Projects\oss\ruby\build32>make
CC = gcc
LD = ld
LDSHARED = gcc -shared
CFLAGS = -O3 -fno-omit-frame-pointer -ggdb -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Werror=pointer-arith -Werror=write-strings -Werror=declaration-after-statement -Werror=implicit-function-declaration
XCFLAGS = -include ruby/config.h -include ruby/missing.h -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fvisibility=hidden -DRUBY_EXPORT
CPPFLAGS = -DFD_SETSIZE=32767 -D_WIN32_WINNT=0x0501 -I. -I.ext/include/i386-mingw32 -I../include -I..
DLDFLAGS = -Wl,--enable-auto-image-base,--enable-auto-import -Wl,--out-implib=libmsvcrt-ruby200.dll.a msvcrt-ruby200.def -Wl,--stack,0x00200000,--enable-auto-import
SOLIBS = msvcrt-ruby200.res.o -lshell32 -lws2_32 -limagehlp
</pre>
<p>Reverting r34840:</p>
<pre>
C:\Users\Luis\Projects\oss\ruby\build32>make
CC = gcc
LD = ld
LDSHARED = gcc -shared -s
CFLAGS = -O3 -fno-omit-frame-pointer -g -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Werror=pointer-arith -Werror=write-strings -Werror=declaration-after-statement -Werror=implicit-function-declaration
XCFLAGS = -include ruby/config.h -include ruby/missing.h -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fvisibility=hidden -DRUBY_EXPORT
CPPFLAGS = -DFD_SETSIZE=32767 -D_WIN32_WINNT=0x0501 -I. -I.ext/include/i386-mingw32 -I../include -I..
DLDFLAGS = -Wl,--enable-auto-image-base,--enable-auto-import -Wl,--out-implib=libmsvcrt-ruby200.dll.a msvcrt-ruby200.def -Wl,--stack,0x00200000,--enable-auto-import
SOLIBS = msvcrt-ruby200.res.o -lshell32 -lws2_32 -limagehlp
</pre>
<p>Notice that -g changed into -ggdb instead.</p>
<p>I think debug symbols shouldn't be compiled unless requested and this is a regression.</p> Ruby master - Bug #6351 (Assigned): transcode table generator does not support multi characters o...https://bugs.ruby-lang.org/issues/63512012-04-24T20:41:39Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<p>改めてチケット起こします。<a href="/issues/6349">[ruby-dev:45576]</a> より。</p>
<p>On 2012/04/24 17:11, "Martin J. Dürst" wrote:</p>
<blockquote>
<p>On 2012/04/24 17:02, U.Nakamura wrote:</p>
<blockquote>
<p>データは例によってNetBSDのものが利用できそうです。<br>
なのですが、transcodeってUnicodeの第0面(BMP)以外はサポートし<br>
てましたっけ?</p>
</blockquote>
<p>もちろんです :-)</p>
</blockquote>
<p>もうちょっと調べました。BMP 以外は transcode の最初から全く問題ないです<br>
が、現時点で引っかかるのは次のものです<br>
(<a href="http://x0213.org/codetable/euc-jis-2004-std.txt" class="external">http://x0213.org/codetable/euc-jis-2004-std.txt</a> から抜粋):</p>
<p>0xA4F7 U+304B+309A # [2000]<br>
0xA4F8 U+304D+309A # [2000]<br>
0xA4F9 U+304F+309A # [2000]<br>
0xA4FA U+3051+309A # [2000]<br>
0xA4FB U+3053+309A # [2000]</p>
<p>0xA5F7 U+30AB+309A # [2000]<br>
0xA5F8 U+30AD+309A # [2000]<br>
0xA5F9 U+30AF+309A # [2000]<br>
0xA5FA U+30B1+309A # [2000]<br>
0xA5FB U+30B3+309A # [2000]<br>
0xA5FC U+30BB+309A # [2000]<br>
0xA5FD U+30C4+309A # [2000]<br>
0xA5FE U+30C8+309A # [2000]</p>
<p>0xA6F8 U+31F7+309A # [2000]</p>
<p>0xABC4 U+00E6+0300 # [2000]</p>
<p>0xABC8 U+0254+0300 # [2000]<br>
0xABC9 U+0254+0301 # [2000]<br>
0xABCA U+028C+0300 # [2000]<br>
0xABCB U+028C+0301 # [2000]<br>
0xABCC U+0259+0300 # [2000]<br>
0xABCD U+0259+0301 # [2000]<br>
0xABCE U+025A+0300 # [2000]<br>
0xABCF U+025A+0301 # [2000]</p>
<p>0xABE5 U+02E9+02E5 # [2000]<br>
0xABE6 U+02E5+02E9 # [2000]</p>
<p>ようするに、JIS X 0213 で一文字になっているが、Unicode で二文字になって<br>
いるものです。EUC-JISX0213 から UTF-8 は問題ないですが、逆は現在引っかか<br>
ります。windows-1258 も (逆ですが) 同じ問題がありますので、いずれはなく<br>
さないといけないと思いましたが、今回はいいきっかけのではないかと思います。</p>
<p>よろしくお願いします。 Martin.</p>