Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112023-03-29T13:47:47ZRuby Issue Tracking System
Redmine Ruby master - Bug #19558 (Open): str.dump.undump crashes when str contains both Unicode and ASCII...https://bugs.ruby-lang.org/issues/195582023-03-29T13:47:47Zikaronen-relex (Ilmari Karonen)
<p>Recently, as a result of a question I asked on Stack Overflow (<a href="https://stackoverflow.com/q/75866159" class="external">https://stackoverflow.com/q/75866159</a>), I learned about the existence of String#dump and String#undump. However, I also found what seems like a bug in them, in that apparently dumping and then undumping a string containing a sufficiently diverse selection of characters (such as at least one ASCII C0 control character and at least one non-ASCII Unicode character) causes the undump to raise a RuntimeError.</p>
<p>Specifically, evaluating e.g. any of the following expressions:</p>
<pre><code>"\u0000\uFFFF".dump.undump
"\u0001\uABCD".dump.undump
"\u007F\u0080".dump.undump
</code></pre>
<p>raises a RuntimeError with the message "hex escape and Unicode escape are mixed". This contradicts the documentation of String#undump, which says that it "does the inverse of String#dump."</p>
<p>The behavior is the same on all Ruby versions I have tested this on, including master (3.3.0), 2.6.10 and JRuby 9.3.10.0.</p>
<p>The obvious fix would be to simply remove the check for mixed hex and Unicode escape sequences, essentially reverting <a href="https://github.com/ruby/ruby/commit/05d1d29d1f4a87620371463d8c7942e170be031f" class="external">https://github.com/ruby/ruby/commit/05d1d29d1f4a87620371463d8c7942e170be031f</a>. However, as I don't understand why the check is there in the first place, I'm also not sure if removing it could somehow have some unwanted consequences.</p> Ruby master - Bug #19557 (Open): Deadlock on STDOUT(ERR) lock on signal handlerhttps://bugs.ruby-lang.org/issues/195572023-03-29T08:27:05Zko1 (Koichi Sasada)
<p>The following Ruby code produces <code>deadlock; recursive locking (ThreadError)</code>.<br>
It means some IO operations (<code>puts</code>, ...) is not used on trap handlers safely.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">trap</span><span class="p">(</span><span class="ss">:USR1</span><span class="p">){</span><span class="nb">puts</span> <span class="s1">'world'</span><span class="p">}</span>
<span class="no">Thread</span><span class="p">.</span><span class="nf">new</span><span class="p">{</span><span class="kp">loop</span><span class="p">{</span><span class="no">Process</span><span class="p">.</span><span class="nf">kill</span><span class="p">(</span><span class="ss">:USR1</span><span class="p">,</span> <span class="vg">$$</span><span class="p">);</span> <span class="nb">sleep</span> <span class="mf">0.5</span><span class="p">}}</span>
<span class="kp">loop</span><span class="p">{</span><span class="nb">puts</span> <span class="s1">'hello'</span><span class="p">}</span>
</code></pre>
<pre><code>...
hello
hello
hello
hello
hello
../../src/clean/test.rb:2:in `write': deadlock; recursive locking (ThreadError)
from ../../src/clean/test.rb:2:in `puts'
from ../../src/clean/test.rb:2:in `puts'
from ../../src/clean/test.rb:2:in `block in <main>'
from ../../src/clean/test.rb:4:in `write'
from ../../src/clean/test.rb:4:in `puts'
from ../../src/clean/test.rb:4:in `puts'
from ../../src/clean/test.rb:4:in `block in <main>'
from <internal:kernel>:187:in `loop'
from ../../src/clean/test.rb:4:in `<main>'
</code></pre>
<a name="Reason"></a>
<h2 >Reason<a href="#Reason" class="wiki-anchor">¶</a></h2>
<ul>
<li>
<code>puts()</code> calls <code>rb_io_writev()</code>
</li>
<li>it calls <code>IO#write</code>
</li>
<li>it calls <code>io_write_m()</code>
</li>
<li>it calls <code>io_writev()</code>
</li>
<li>it calls <code>io_fwritev()</code>
</li>
<li>it calls <code>io_binwritev()</code>
</li>
<li>it calls <code>rb_mutex_synchronize()</code> with <code>io_binwritev_internal()</code>
<ul>
<li>STDOUT's <code>fptr->write_lock</code> is acquired here</li>
</ul>
</li>
<li>
<code>io_binwritev_internal()</code> calls <code>rb_writev_internal()</code>
</li>
<li>it calls <code>rb_thread_io_blocking_region()</code> with <code>internal_writev_func()</code>
</li>
</ul>
<p>Here, <code>internal_writev_func()</code> can be interrupted by signals and if a trap handler is registered, call the trap handler (written in Ruby, <code>puts 'world'</code> in this case) and call <code>Kernel#puts()</code> and <code>fptr->write_lock</code> is already acquired -> <code>deadlock; recursive locking</code>.</p>
<a name="Ideas"></a>
<h2 >Ideas<a href="#Ideas" class="wiki-anchor">¶</a></h2>
<p>I'm not sure why <code>fptr->write_lock</code> is needed, but if there is no internal consistency issue, we can make <code>fptr->write_lock</code> <code>nil</code> at least for STDOUT/ERR.</p>
<p>Another idea is, calling trap handlers (or other interruptible Ruby code such as finalizers and so on) after releasing the lock. But I'm not sure it is feasible.</p> Ruby master - Bug #19473 (Open): can't be called from trap context (ThreadError) is too limitinghttps://bugs.ruby-lang.org/issues/194732023-03-02T12:04:28ZEregon (Benoit Daloze)
<p>Simple reproducer:</p>
<pre><code>$ ruby -ve 'm=Mutex.new; trap(:HUP) { m.synchronize { p :OK } }; Process.kill :HUP, Process.pid; sleep 0.1'
ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-linux]
-e:1:in `synchronize': can't be called from trap context (ThreadError)
from -e:1:in `block in <main>'
from -e:1:in `kill'
from -e:1:in `<main>'
</code></pre>
<p>Expected behavior:</p>
<pre><code>$ ruby -ve 'm=Mutex.new; trap(:HUP) { m.synchronize { p :OK } }; Process.kill :HUP, Process.pid; sleep 0.1'
truffleruby 22.3.1, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
:OK
$ ruby -ve 'm=Mutex.new; trap(:HUP) { m.synchronize { p :OK } }; Process.kill :HUP, Process.pid; sleep 0.1'
jruby 9.4.0.0 (3.1.0) 2022-11-23 95c0ec159f OpenJDK 64-Bit Server VM 17.0.6+10 on 17.0.6+10 +jit [x86_64-linux]
:OK
</code></pre>
<p>This exception is highly problematic, for instance it breaks <code>Timeout.timeout</code> in <code>trap</code>:<br>
<a href="https://github.com/ruby/timeout/issues/17#issuecomment-1142035939" class="external">https://github.com/ruby/timeout/issues/17#issuecomment-1142035939</a></p>
<p>I suppose this behavior is because <em>sometimes</em> it's problematic to lock a Mutex in trap, e.g., if it's already locked by the main thread/fiber.<br>
But that would otherwise already raise <code>deadlock; recursive locking (ThreadError)</code>, so there is no point to fail early.<br>
And that's just one case, not all, so we should not always raise an exception.</p>
<p>There seems to be no valid reason to prevent <em>all</em> <code>Mutex#synchronize</code> in <code>trap</code>.<br>
After all, if the Mutex for instance is only used in <code>trap</code>, it's well-defined AFAIK.<br>
For instance a given trap handler does not seem executed concurrently:</p>
<pre><code>$ ruby -ve 'trap(:HUP) { puts "in trap\n"+caller.join("\n")+"\n\n"; sleep 0.1 }; pid = Process.pid; Process.wait fork { 20.times { Process.kill :HUP, pid } }; sleep 1'
ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-linux]
in trap
-e:1:in `wait'
-e:1:in `<main>'
in trap
-e:1:in `wait'
-e:1:in `<main>'
in trap
-e:1:in `wait'
-e:1:in `<main>'
in trap
-e:1:in `wait'
-e:1:in `<main>'
in trap
-e:1:in `wait'
-e:1:in `<main>'
in trap
-e:1:in `wait'
-e:1:in `<main>'
</code></pre>
<p>And if the trap handler using the Mutex is never called while the Mutex is held by the main thread/fiber, there is also no problem.</p> Ruby master - Bug #19470 (Open): Frequent small range-reads from and then writes to a large array...https://bugs.ruby-lang.org/issues/194702023-03-01T05:36:52Zginer (Stanislav German-Evtushenko)
<p>Write to a large array gets very slow when done after range-reading more than 3 items. In such case the original array gets marked as shared which triggers CoW on a small change afterwards. This leads to a significant performance impact and high memory utilization in cases when we need to range-read/write from/to the same array many times. While this issue can be avoided by reading <= 3 elements at a time the main problem is that this behaviour is not obvious and hard to catch on on-trivial projects.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">times</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">100000</span>
<span class="n">times</span><span class="p">.</span><span class="nf">push</span> <span class="mi">0</span>
<span class="mi">100000</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span>
<span class="n">time_start</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
<span class="n">arr</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">=</span> <span class="mi">100</span> <span class="c1"># takes 0.01662315899999512</span>
<span class="n">times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">-</span> <span class="n">time_start</span>
<span class="k">end</span>
<span class="n">times</span><span class="p">.</span><span class="nf">push</span> <span class="mi">0</span>
<span class="mi">100000</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span>
<span class="n">arr</span><span class="p">[</span><span class="mi">0</span><span class="o">..</span><span class="mi">2</span><span class="p">]</span>
<span class="n">time_start</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
<span class="n">arr</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">=</span> <span class="mi">100</span> <span class="c1"># takes 0.01826406799999659</span>
<span class="n">times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">-</span> <span class="n">time_start</span>
<span class="k">end</span>
<span class="n">times</span><span class="p">.</span><span class="nf">push</span> <span class="mi">0</span>
<span class="mi">100000</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span>
<span class="n">arr</span><span class="p">[</span><span class="mi">0</span><span class="o">..</span><span class="mi">3</span><span class="p">]</span>
<span class="n">time_start</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
<span class="n">arr</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">=</span> <span class="mi">100</span> <span class="c1"># takes 7.757753919000069</span>
<span class="n">times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">-</span> <span class="n">time_start</span>
<span class="k">end</span>
<span class="n">times</span><span class="p">.</span><span class="nf">push</span> <span class="mi">0</span>
<span class="mi">100000</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">dup</span>
<span class="n">time_start</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
<span class="n">arr</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">=</span> <span class="mi">100</span> <span class="c1"># takes 7.626929300999957</span>
<span class="n">times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">-</span> <span class="n">time_start</span>
<span class="k">end</span>
<span class="n">times</span><span class="p">.</span><span class="nf">push</span> <span class="mi">0</span>
<span class="mi">100000</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">clone</span>
<span class="n">time_start</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
<span class="n">arr</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">=</span> <span class="mi">100</span> <span class="c1"># takes 8.216933763000046</span>
<span class="n">times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">-</span> <span class="n">time_start</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="n">times</span>
</code></pre> Ruby master - Bug #19438 (Open): Ruby 2.7 -> 3.2 Performance Regression in so_k_nucleotide benchmarkhttps://bugs.ruby-lang.org/issues/194382023-02-15T13:30:14Znick.schwaderer (Nicholas Schwaderer)nicholas.schwaderer@gmail.com
<a name="Introduction"></a>
<h2 >Introduction<a href="#Introduction" class="wiki-anchor">¶</a></h2>
<p>Recently I had been going through some of the old benchmarks in the <a href="https://programmingzen.com/the-great-ruby-shootout-july-2010/" class="external">Ruby Great Implementation Shootout</a> from around 2010.</p>
<p>As an experiment, one night I ran the benchmarks against Ruby 3.2.0, Ruby 3.2.0 --yjit, TruffleRuby, TruffleRuby +GraalVM, and Ruby 2.6.10.</p>
<p>Most results were as expected. However there was a benchmark that Ruby 2.6.10 was <em>consistently</em> outperforming all new Rubies on.</p>
<a name="Method"></a>
<h2 >Method<a href="#Method" class="wiki-anchor">¶</a></h2>
<p>After pairing with <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/31800">@eightbitraptor (Matthew Valentine-House)</a>, we discovered that this old benchmark was remarkably similar to an existing benchmark in the <code>/benchmark</code><br>
directory, <a href="https://github.com/ruby/ruby/blob/master/benchmark/so_k_nucleotide.yml" class="external">so_k_nucleotide.yml</a>. We decided to go with that benchmark. For brevity I have not included the full 150 lines of the benchmark here.</p>
<p>I tested this benchmark out with 100 runs using <code>benchmark-driver</code> against Ruby 2.7,3.0,3.1,3.2. (I had discovered that 2.7 was even faster than 2.6.).</p>
<p>It appears that about half of the regression occured from 2.7 -> 3.0; the other half from 3.0 -> 3.2. One other interesting finding is that each minor version does appear to regress<br>
from the last, even if a little.</p>
<a name="Code"></a>
<h2 >Code<a href="#Code" class="wiki-anchor">¶</a></h2>
<p>This is my benchmark running code and harnass. <a href="https://gist.github.com/Schwad/16edf3d7cc5316af4baf23497f3c6a8f" class="external">The full code and data can be found here</a></p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">RUNS</span> <span class="o">=</span> <span class="mi">100</span>
<span class="n">results</span> <span class="o">=</span> <span class="no">Hash</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="o">|</span><span class="n">h</span><span class="p">,</span> <span class="n">k</span><span class="o">|</span> <span class="n">h</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="p">}</span>
<span class="no">RUNS</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="nb">puts</span> <span class="n">i</span>
<span class="n">run</span> <span class="o">=</span> <span class="sb">`benchmark-driver so_k_nucleotide.yml --chruby '2.7.5;3.0.5;3.1.3;3.2.0' -o simple`</span>
<span class="n">run</span><span class="p">.</span><span class="nf">scan</span><span class="p">(</span><span class="sr">/\d\.\d\.\d/</span><span class="p">).</span><span class="nf">each_with_index</span> <span class="k">do</span> <span class="o">|</span><span class="n">version</span><span class="p">,</span> <span class="n">index</span><span class="o">|</span>
<span class="n">results</span><span class="p">[</span><span class="n">version</span><span class="p">]</span> <span class="o"><<</span> <span class="n">run</span><span class="p">.</span><span class="nf">scan</span><span class="p">(</span><span class="sr">/\d\.\d\d\d/</span><span class="p">)[</span><span class="n">index</span><span class="p">]</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">require</span> <span class="s1">'csv'</span>
<span class="n">columns</span> <span class="o">=</span> <span class="n">results</span><span class="p">.</span><span class="nf">keys</span>
<span class="n">outdata</span> <span class="o">=</span> <span class="no">CSV</span><span class="p">.</span><span class="nf">generate</span> <span class="k">do</span> <span class="o">|</span><span class="n">csv</span><span class="o">|</span>
<span class="n">csv</span> <span class="o"><<</span> <span class="n">columns</span>
<span class="no">RUNS</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">csv</span> <span class="o"><<</span> <span class="n">columns</span><span class="p">.</span><span class="nf">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">c</span><span class="o">|</span> <span class="n">results</span><span class="p">[</span><span class="n">c</span><span class="p">][</span><span class="n">i</span><span class="p">]</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">File</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="s2">"output.csv"</span><span class="p">,</span> <span class="n">outdata</span><span class="p">)</span>
</code></pre>
<a name="Data"></a>
<h2 >Data<a href="#Data" class="wiki-anchor">¶</a></h2>
<p>Ruby 2.7.5 was consistently ~18-20% faster than Ruby 3.2.0 in this Benchmark</p>
<p><img src="https://user-images.githubusercontent.com/7865030/219038430-4a124cc6-0d23-46e2-9794-d89d1f26e227.png" alt="Screenshot 2023-02-15 at 13 16 10"></p>
<a name="Next-Steps"></a>
<h2 >Next Steps<a href="#Next-Steps" class="wiki-anchor">¶</a></h2>
<p>I am happy to help investigate or learn more about this regression if anyone has any ideas.</p> Ruby master - Bug #19413 (Open): Can't move object when 2 ivars refer to same objecthttps://bugs.ruby-lang.org/issues/194132023-02-04T22:15:59Zluke-gru (Luke Gruber)luke.gru@gmail.com
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span>
<span class="k">def</span> <span class="nf">initialize</span>
<span class="vi">@a</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="vi">@b</span> <span class="o">=</span> <span class="vi">@a</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="k">do</span> <span class="o">|</span><span class="n">err</span><span class="o">|</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="k">end</span>
<span class="n">r</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="no">A</span><span class="p">.</span><span class="nf">new</span><span class="p">,</span> <span class="ss">move: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># Allocator undefined for Ractor::MovedObject</span>
<span class="n">r</span><span class="p">.</span><span class="nf">take</span>
</code></pre>
<p>To fix it we could have a hash of old to new objects during traversal/replacement and use the same new object over again if necessary.</p> Ruby master - Bug #19412 (Open): Socket starts queueing and not responding after a certain amount...https://bugs.ruby-lang.org/issues/194122023-02-03T23:44:54Zbrodock (Gabriel Mazetto)brodock@gmail.com
<p>Here is a an example code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'socket'</span>
<span class="no">PORT</span> <span class="o">=</span> <span class="mi">8080</span>
<span class="no">BACKLOG</span> <span class="o">=</span> <span class="mi">50</span>
<span class="no">LISTEN</span> <span class="o">=</span> <span class="s1">'127.0.0.1'</span>
<span class="k">def</span> <span class="nf">handle_connection</span><span class="p">(</span><span class="n">connection</span><span class="p">,</span> <span class="n">_addrinfo</span><span class="p">)</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">connection</span><span class="p">.</span><span class="nf">gets</span>
<span class="nb">puts</span> <span class="n">request</span>
<span class="n">connection</span><span class="p">.</span><span class="nf">write</span> <span class="s2">"HTTP/1.1 200</span><span class="se">\r\n</span><span class="s2">"</span>
<span class="n">connection</span><span class="p">.</span><span class="nf">write</span> <span class="s2">"Content-Type: text/html</span><span class="se">\r\n</span><span class="s2">"</span>
<span class="n">connection</span><span class="p">.</span><span class="nf">write</span> <span class="s2">"</span><span class="se">\r\n</span><span class="s2">"</span>
<span class="n">connection</span><span class="p">.</span><span class="nf">write</span> <span class="s2">"Hello world! Current time is </span><span class="si">#{</span><span class="no">Time</span><span class="p">.</span><span class="nf">now</span><span class="si">}</span><span class="s2">"</span>
<span class="k">ensure</span>
<span class="n">connection</span><span class="p">.</span><span class="nf">close</span>
<span class="k">end</span>
<span class="k">begin</span>
<span class="n">socket</span> <span class="o">=</span> <span class="no">Socket</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:INET</span><span class="p">,</span> <span class="ss">:STREAM</span><span class="p">)</span>
<span class="n">socket</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="no">Addrinfo</span><span class="p">.</span><span class="nf">tcp</span><span class="p">(</span><span class="no">LISTEN</span><span class="p">,</span> <span class="no">PORT</span><span class="p">))</span>
<span class="n">socket</span><span class="p">.</span><span class="nf">listen</span><span class="p">(</span><span class="no">BACKLOG</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"Requested queue size: </span><span class="si">#{</span><span class="no">BACKLOG</span><span class="si">}</span><span class="s2"> bigger then limit: </span><span class="si">#{</span><span class="no">Socket</span><span class="o">::</span><span class="no">SOMAXCONN</span><span class="si">}</span><span class="s2">"</span> <span class="k">if</span> <span class="no">BACKLOG</span> <span class="o">></span> <span class="no">Socket</span><span class="o">::</span><span class="no">SOMAXCONN</span>
<span class="kp">loop</span> <span class="k">do</span>
<span class="n">listening</span><span class="p">,</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">select</span><span class="p">([</span><span class="n">socket</span><span class="p">])</span>
<span class="n">io</span><span class="p">,</span> <span class="o">=</span> <span class="n">listening</span>
<span class="n">connection</span><span class="p">,</span> <span class="n">addrinfo</span> <span class="o">=</span> <span class="n">io</span><span class="p">.</span><span class="nf">accept</span>
<span class="n">handle_connection</span><span class="p">(</span><span class="n">connection</span><span class="p">,</span> <span class="n">addrinfo</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">ensure</span>
<span class="n">socket</span><span class="p">.</span><span class="nf">close</span>
<span class="k">end</span>
</code></pre>
<p>This tries to simulate a TCP server that responds as if it was an HTTP server.</p>
<p>The amount of requests it can sustain seems to depend on the OS. On a Linux machine running ubuntu 20.04 I get something around 7.6K to 7.8K until it stops responding.</p>
<pre><code>$ uname -a
Linux ... 5.17.5-x86_64-linode154 #1 SMP PREEMPT Mon May 2 15:07:22 EDT 2022 x86_64 x86_64 x86_64 GNU/Linux
$ ab -n 20000 -c 50 http://127.0.0.1:8080/
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 2000 requests
Completed 4000 requests
Completed 6000 requests
apr_pollset_poll: The timeout specified has expired (70007)
Total of 7883 requests completed
</code></pre>
<p>on MacOS Ventura I get around 16K:</p>
<pre><code>$ uname -a
Darwin ... 22.2.0 Darwin Kernel Version 22.2.0: Fri Nov 11 02:04:44 PST 2022; root:xnu-8792.61.2~4/RELEASE_ARM64_T8103 arm64
$ ab -n 20000 -c 50 http://127.0.0.1:8080/
This is ApacheBench, Version 2.3 <$Revision: 1901567 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 2000 requests
Completed 4000 requests
Completed 6000 requests
Completed 8000 requests
Completed 10000 requests
Completed 12000 requests
Completed 14000 requests
Completed 16000 requests
apr_socket_recv: Operation timed out (60)
Total of 16375 requests completed
</code></pre>
<p>in both cases when that limit reaches, if I abort the program (CTRL-C) and try to run it again it takes a while until the port is released:</p>
<pre><code>...
GET / HTTP/1.0
GET / HTTP/1.0
GET / HTTP/1.0
^Csocketserver.rb:29:in `select': Interrupt
from socketserver.rb:29:in `block in <main>'
from socketserver.rb:28:in `loop'
from socketserver.rb:28:in `<main>'
$ ruby socketserver.rb
socketserver.rb:23:in `bind': Address already in use - bind(2) for 127.0.0.1:8080 (Errno::EADDRINUSE)
from socketserver.rb:23:in `<main>'
</code></pre>
<p>After killing the process it seems no process is holding the port:</p>
<pre><code>lsof -wni tcp:8080
</code></pre>
<p>Running the command above does not return anything (it does when the program is still running).</p>
<p>I think we may be failing to release something when interacting with the Socket on syscalls/kernel level and we endup filling up some queue/buffer that eventually gets freed.</p> Ruby master - Bug #19384 (Open): ASCII 128..154 characters in IO.popen or %x output do not reflec...https://bugs.ruby-lang.org/issues/193842023-01-26T21:17:30Zstringsn88keys (Thomas Powell)
<p>Operating systems: Windows 10 and Windows Server 2022 (likely all recent versions of Windows)<br>
Ruby: confirmed on 2.7.7 through 3.1.3</p>
<p>On macOS and Linux I can create a file named "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ" and then do a directory listing via IO.popen or %x and find the file name in the output string.</p>
<p>In Windows, while the encoding is reported as #<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a>, I have to .force_encoding on the output to be able to find the string in the output:</p>
<a name="xdir-tmp"></a>
<h2 >%x|dir tmp|<a href="#xdir-tmp" class="wiki-anchor">¶</a></h2>
<p>output encoding: #<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a><br>
Output can be made to match by forcing the following encodings:<br>
IBM437<br>
CP850<br>
IBM865</p>
<a name="IOpopendir-tmpread"></a>
<h2 >IO.popen(dir tmp).read<a href="#IOpopendir-tmpread" class="wiki-anchor">¶</a></h2>
<p>output encoding: #<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a><br>
Output can be made to match by forcing the following encodings:<br>
IBM437<br>
CP850<br>
IBM865</p>
<p>But on macOS or Linux:<br>
❯ ruby directory_test.rb</p>
<a name="xls-tmp"></a>
<h2 >%x|ls tmp|<a href="#xls-tmp" class="wiki-anchor">¶</a></h2>
<p>output encoding: #<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a><br>
output matches without forcing encoding<br>
Output can be made to match by forcing the following encodings:<br>
UTF-8<br>
UTF8-MAC<br>
CESU-8<br>
UTF8-DoCoMo<br>
UTF8-KDDI<br>
UTF8-SoftBank</p>
<a name="IOpopenls-tmpread"></a>
<h2 >IO.popen(ls tmp).read<a href="#IOpopenls-tmpread" class="wiki-anchor">¶</a></h2>
<p>output encoding: #<a href="Encoding:UTF-8" class="external">Encoding:UTF-8</a><br>
output matches without forcing encoding<br>
Output can be made to match by forcing the following encodings:<br>
UTF-8<br>
UTF8-MAC<br>
CESU-8<br>
UTF8-DoCoMo<br>
UTF8-KDDI<br>
UTF8-SoftBank</p>
<p>Note:<br>
The example is contrived because the actual IO.popen output is from a customer system with umlaut characters. However, I have found creating a filename with these characters will adequately reproduce the issue.<br>
Also, I'm only using ASCII/IBM437 as an encoding to create a contiguous set of characters, "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ" as a contrived example.</p> Ruby master - Bug #19313 (Open): Leaked file descriptors while running test-allhttps://bugs.ruby-lang.org/issues/193132023-01-05T18:55:37ZEregon (Benoit Daloze)
<pre><code>$ make test-all TESTOPTS="-j8"
Run options:
--seed=25187
"--ruby=./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems"
--excludes-dir=./test/excludes
--name=!/memory_leak/
-j8
# Running tests:
Skipping Gem::PackageTask tests. rake not found.s_test_2 227226=test_mjit 227227=test_signal 227228=test_gem_comman
Leaked file descriptor: TestFileUtils#test_chown_error: 11 #<File::Stat dev=0xfd00, ino=16777261, mode=0100664, nlink=1, uid=0, gid=0, rdev=0x0, size=9253600, blksize=4096, blocks=18080, atime=2023-01-05 18:16:02.96509764 +0100, mtime=2022-02-23 13:12:06.095215536 +0100, ctime=2022-02-23 13:12:06.095215536 +0100>
Leaked file descriptor: TestFileUtils#test_chown_error: 12 #<File::Stat dev=0xfd00, ino=16777274, mode=0100664, nlink=1, uid=0, gid=0, rdev=0x0, size=6940392, blksize=4096, blocks=13560, atime=2023-01-05 18:16:04.425114636 +0100, mtime=2022-02-23 13:13:58.955685143 +0100, ctime=2022-02-23 13:13:58.955685143 +0100>
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ruby 227230 eregon 11r REG 253,0 9253600 16777261 /var/lib/sss/mc/passwd
ruby 227230 eregon 12r REG 253,0 6940392 16777274 /var/lib/sss/mc/group
Leaked file descriptor: Fiddle::TestFunc#test_qsort1: 12 #<File::Stat dev=0x1, ino=9463, mode=0100777, nlink=0, uid=1000, gid=1000, rdev=0x0, size=4096, blksize=4096, blocks=8, atime=2023-01-05 19:50:42.892803183 +0100, mtime=2023-01-05 19:50:42.892803183 +0100, ctime=2023-01-05 19:50:42.892803183 +0100>
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ruby 227225 eregon 12u REG 0,1 4096 9463 /memfd:libffi (deleted)
Leaked file descriptor: TestFileExhaustive#test_expand_path_home_dir_string: 9 #<File::Stat dev=0xfd00, ino=16777261, mode=0100664, nlink=1, uid=0, gid=0, rdev=0x0, size=9253600, blksize=4096, blocks=18080, atime=2023-01-05 18:16:02.96509764 +0100, mtime=2022-02-23 13:12:06.095215536 +0100, ctime=2022-02-23 13:12:06.095215536 +0100>
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ruby 227226 eregon 9r REG 253,0 9253600 16777261 /var/lib/sss/mc/passwd
Leaked file descriptor: TestDir#test_home: 12 #<File::Stat dev=0xfd00, ino=16777261, mode=0100664, nlink=1, uid=0, gid=0, rdev=0x0, size=9253600, blksize=4096, blocks=18080, atime=2023-01-05 18:16:02.96509764 +0100, mtime=2022-02-23 13:12:06.095215536 +0100, ctime=2022-02-23 13:12:06.095215536 +0100>
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ruby 227224 eregon 12r REG 253,0 9253600 16777261 /var/lib/sss/mc/passwd
Leaked file descriptor: Fiddle::TestFunction#test_argument_count: 13 #<File::Stat dev=0x1, ino=13688, mode=0100777, nlink=0, uid=1000, gid=1000, rdev=0x0, size=4096, blksize=4096, blocks=8, atime=2023-01-05 19:50:49.882901778 +0100, mtime=2023-01-05 19:50:49.882901778 +0100, ctime=2023-01-05 19:50:49.882901778 +0100>
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ruby 227230 eregon 13u REG 0,1 4096 13688 /memfd:libffi (deleted)
Leaked file descriptor: TestProcess#test_uid_from_name: 12 #<File::Stat dev=0xfd00, ino=16777261, mode=0100664, nlink=1, uid=0, gid=0, rdev=0x0, size=9253600, blksize=4096, blocks=18080, atime=2023-01-05 18:16:02.96509764 +0100, mtime=2022-02-23 13:12:06.095215536 +0100, ctime=2022-02-23 13:12:06.095215536 +0100>
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ruby 227229 eregon 12r REG 253,0 9253600 16777261 /var/lib/sss/mc/passwd
Retrying...
Finished tests in 64.982686s, 360.4191 tests/s, 86076.9433 assertions/s.
23421 tests, 5593511 assertions, 0 failures, 0 errors, 156 skips
ruby -v: ruby 3.3.0dev (2023-01-05T18:06:01Z master 54950a78e3) [x86_64-linux]
</code></pre>
<p>On Fedora 37.</p>
<p>If this does not happen on Debian-based OS or macOS I guess it could be a glibc or maybe even a OS bug.</p>
<p>This doesn't cause test failures but makes the output quite noisy.<br>
I have a few leaked descriptors for a while on Fedora when running test-all, also on previous Fedora versions.</p> Ruby master - Bug #19297 (Open): Don't download content from internet to execute Ruby test suitehttps://bugs.ruby-lang.org/issues/192972023-01-02T13:41:57Zvo.x (Vit Ondruch)v.ondruch@tiscali.cz
<p>Trying to build Ruby 3.2.0 for Fedora and execute its test suite via <code>make check</code> as we always did <a href="https://src.fedoraproject.org/rpms/ruby/blob/631163e3b8a51ed610528181aabe0da008049bb6/f/ruby.spec#_1008" class="external">1</a>, the test suite suddenly fails (while it was working with <a class="changeset" title="darwin: resolve rb symbols from ext by `-flat_namespace` to see libruby transitively This repair..." href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/c5eefb7f37db2865891298dd1a1e60dff09560ad">git|c5eefb7f37</a>):</p>
<pre><code>... snip ...
C-API Util function ruby_strtod
- converts a string to a double and returns the remaining string
- returns 0 and the full string if there's no numerical value
Finished in 45.737677 seconds
3827 files, 31635 examples, 177877 expectations, 0 failures, 0 errors, 0 tagged
./miniruby -I/builddir/build/BUILD/ruby-3.2.0/lib -I. -I.ext/common /builddir/build/BUILD/ruby-3.2.0/tool/runruby.rb --extout=.ext -- --disable-gems -C "/builddir/build/BUILD/ruby-3.2.0" bin/gem install --no-document \
--install-dir .bundle --conservative "bundler" "rake" "rspec:~> 3" #"ruby-prof"
ERROR: Could not find a valid gem 'bundler' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - SocketError: Failed to open TCP connection to rubygems.org:443 (getaddrinfo: Temporary failure in name resolution) (https://rubygems.org/specs.4.8.gz)
ERROR: Could not find a valid gem 'rspec' (~> 3), here is why:
Unable to download data from https://rubygems.org/ - SocketError: Failed to open TCP connection to rubygems.org:443 (getaddrinfo: Temporary failure in name resolution) (https://rubygems.org/specs.4.8.gz)
make: Leaving directory '/builddir/build/BUILD/ruby-3.2.0/redhat-linux-build'
make: *** [uncommon.mk:1464: yes-test-syntax-suggest-prepare] Error 2
</code></pre>
<p>This is obviously due to the test suite trying to download <code>rspec</code> from the internet, while Fedora builders does not have internet access (and won't ever have for security reasons). If I am not mistaken, this is caused by <a class="changeset" title="Test syntax_suggest by `make check`" href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/cae53842735237ccf71a13873fd0d1ae7f165582">git|cae53842735237ccf71a13873fd0d1ae7f165582</a>. Now</p>
<ol>
<li>Can this be fixed?</li>
<li>Can the tarball be always self contained?</li>
</ol> Ruby master - Bug #19288 (Open): Ractor JSON parsing significantly slower than linear parsinghttps://bugs.ruby-lang.org/issues/192882022-12-30T10:39:56Zmaciej.mensfeld (Maciej Mensfeld)maciej@mensfeld.pl
<p>a simple benchmark:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'json'</span>
<span class="nb">require</span> <span class="s1">'benchmark'</span>
<span class="no">CONCURRENT</span> <span class="o">=</span> <span class="mi">5</span>
<span class="no">RACTORS</span> <span class="o">=</span> <span class="kp">true</span>
<span class="no">ELEMENTS</span> <span class="o">=</span> <span class="mi">100_000</span>
<span class="n">data</span> <span class="o">=</span> <span class="no">CONCURRENT</span><span class="p">.</span><span class="nf">times</span><span class="p">.</span><span class="nf">map</span> <span class="k">do</span>
<span class="no">ELEMENTS</span><span class="p">.</span><span class="nf">times</span><span class="p">.</span><span class="nf">map</span> <span class="k">do</span>
<span class="p">{</span>
<span class="nb">rand</span> <span class="o">=></span> <span class="nb">rand</span><span class="p">,</span>
<span class="nb">rand</span> <span class="o">=></span> <span class="nb">rand</span><span class="p">,</span>
<span class="nb">rand</span> <span class="o">=></span> <span class="nb">rand</span><span class="p">,</span>
<span class="nb">rand</span> <span class="o">=></span> <span class="nb">rand</span>
<span class="p">}.</span><span class="nf">to_json</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">ractors</span> <span class="o">=</span> <span class="no">CONCURRENT</span><span class="p">.</span><span class="nf">times</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="no">Ractor</span><span class="p">.</span><span class="nf">receive</span><span class="p">.</span><span class="nf">each</span> <span class="p">{</span> <span class="no">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">_1</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">result</span> <span class="o">=</span> <span class="no">Benchmark</span><span class="p">.</span><span class="nf">measure</span> <span class="k">do</span>
<span class="k">if</span> <span class="no">RACTORS</span>
<span class="no">CONCURRENT</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="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">send</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="ss">move: </span><span class="kp">false</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">ractors</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="k">else</span>
<span class="c1"># Linear without any threads</span>
<span class="n">data</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">piece</span><span class="o">|</span>
<span class="n">piece</span><span class="p">.</span><span class="nf">each</span> <span class="p">{</span> <span class="no">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">_1</span><span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="n">result</span>
</code></pre>
<p>Gives following results on my 8 core machine:</p>
<pre><code class="shell syntaxhl" data-language="shell"><span class="c"># without ractors:</span>
2.731748 0.003993 2.735741 <span class="o">(</span> 2.736349<span class="o">)</span>
<span class="c"># with ractors</span>
12.580452 5.089802 17.670254 <span class="o">(</span> 5.209755<span class="o">)</span>
</code></pre>
<p>I would expect Ractors not to be two times slower on the CPU intense work.</p> Ruby master - Bug #19268 (Open): Mingw64 Build Failurehttps://bugs.ruby-lang.org/issues/192682022-12-27T09:42:22Zcfis (Charlie Savage)
<p>For both Ruby 3.1.3 and Ruby 3.2.0, building on msys2/ucrt64 fails:</p>
<pre><code class="c syntaxhl" data-language="c"><span class="n">linking</span> <span class="n">miniruby</span><span class="p">.</span><span class="n">exe</span>
<span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">sh</span><span class="o">:</span> <span class="o">-</span><span class="n">c</span><span class="o">:</span> <span class="n">line</span> <span class="mi">1</span><span class="o">:</span> <span class="n">syntax</span> <span class="n">error</span> <span class="n">near</span> <span class="n">unexpected</span> <span class="n">token</span> <span class="err">`</span><span class="p">(</span><span class="err">'</span>
<span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">sh</span><span class="o">:</span> <span class="o">-</span><span class="n">c</span><span class="o">:</span> <span class="n">line</span> <span class="mi">1</span><span class="o">:</span> <span class="err">`</span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="n">ruby</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">ruby</span> <span class="o">--</span><span class="n">disable</span><span class="o">=</span><span class="n">gems</span> <span class="o">-</span><span class="n">n</span> <span class="o">-</span><span class="n">e</span> <span class="n">BEGIN</span><span class="p">{</span><span class="n">version</span><span class="o">=</span><span class="n">ARGV</span><span class="p">.</span><span class="n">shift</span><span class="p">;</span><span class="n">mis</span><span class="o">=</span><span class="n">ARGV</span><span class="p">.</span><span class="n">dup</span><span class="p">}</span> <span class="o">-</span><span class="n">e</span> <span class="n">END</span><span class="p">{</span><span class="n">abort</span> <span class="s">"UNICODE version mismatch: #{mis}"</span> <span class="n">unless</span> <span class="n">mis</span><span class="p">.</span><span class="n">empty</span><span class="o">?</span><span class="p">}</span> <span class="o">-</span><span class="n">e</span> <span class="p">(</span><span class="n">mis</span><span class="p">.</span><span class="n">delete</span><span class="p">(</span><span class="n">ARGF</span><span class="p">.</span><span class="n">path</span><span class="p">);</span> <span class="n">ARGF</span><span class="p">.</span><span class="n">close</span><span class="p">)</span> <span class="k">if</span> <span class="o">/</span><span class="n">ONIG_UNICODE_VERSION_STRING</span> <span class="o">+</span><span class="s">"#{Regexp.quote(version)}"</span><span class="o">/</span><span class="n">o</span> <span class="mi">15</span><span class="p">.</span><span class="mi">0</span><span class="p">.</span><span class="mi">0</span> <span class="p">.</span><span class="o">/</span><span class="n">enc</span><span class="o">/</span><span class="n">unicode</span><span class="o">/</span><span class="mi">15</span><span class="p">.</span><span class="mi">0</span><span class="p">.</span><span class="mi">0</span><span class="o">/</span><span class="n">casefold</span><span class="p">.</span><span class="n">h</span> <span class="p">.</span><span class="o">/</span><span class="n">enc</span><span class="o">/</span><span class="n">unicode</span><span class="o">/</span><span class="mi">15</span><span class="p">.</span><span class="mi">0</span><span class="p">.</span><span class="mi">0</span><span class="o">/</span><span class="n">name2ctype</span><span class="p">.</span><span class="n">h</span><span class="err">'</span>
<span class="n">make</span><span class="o">:</span> <span class="o">***</span> <span class="p">[</span><span class="n">uncommon</span><span class="p">.</span><span class="n">mk</span><span class="o">:</span><span class="mi">878</span><span class="o">:</span> <span class="p">.</span><span class="n">rbconfig</span><span class="p">.</span><span class="n">time</span><span class="p">]</span> <span class="n">Error</span> <span class="mi">2</span>
</code></pre>
<p>The fix that works for me is changing:</p>
<pre><code class="c syntaxhl" data-language="c"> <span class="o">-</span><span class="n">e</span> <span class="err">'</span><span class="p">(</span><span class="n">mis</span><span class="p">.</span><span class="n">delete</span><span class="p">(</span><span class="n">ARGF</span><span class="p">.</span><span class="n">path</span><span class="p">);</span> <span class="n">ARGF</span><span class="p">.</span><span class="n">close</span><span class="p">)</span> <span class="k">if</span> <span class="o">/</span><span class="n">ONIG_UNICODE_VERSION_STRING</span> <span class="o">+</span><span class="s">"#{Regexp.quote(version)}"</span><span class="o">/</span><span class="n">o</span><span class="err">'</span> \
</code></pre>
<p>To</p>
<pre><code class="c syntaxhl" data-language="c"> <span class="o">-</span><span class="n">e</span> <span class="s">"(mis.delete(ARGF.path); ARGF.close) if /ONIG_UNICODE_VERSION_STRING +</span><span class="se">\"</span><span class="s">#{Regexp.quote(version)}</span><span class="se">\"</span><span class="s">/o"</span> \
</code></pre>
<pre><code></code></pre> Ruby master - Bug #19266 (Open): URI::Generic should use URI::RFC3986_PARSER instead of URI::DEFA...https://bugs.ruby-lang.org/issues/192662022-12-26T18:52:36Zgareth (Gareth Adams)
<p>In June 2014, <a href="https://github.com/ruby/ruby/commit/bb83f32dc3e0424d25fa4e55d8ff32b061320e41" class="external"><code>uri/common</code> was updated</a> to introduce a RFC3986-compliant parser (<code>URI::RFC3986_PARSER</code>) as an alternative to the previous RFC2396 parser, and common methods like <code>URI()</code> were updated to use that new parser by default. The only methods in <code>common</code> not updated were <a href="https://github.com/ruby/ruby/blob/28a17436503c3c4cb7a35b423a894b697cd80da9/lib/uri/common.rb#L233-L297" class="external"><code>URI.extract</code> and <code>URI.regexp</code></a> which are marked as obsolete. (The old parser was kept in the <code>DEFAULT_PARSER</code> constant despite it not being the default for those methods, presumably for backward compatibility.)</p>
<p>However, similar <a href="https://github.com/ruby/ruby/blob/28a17436503c3c4cb7a35b423a894b697cd80da9/lib/uri/generic.rb#L169-L175" class="external">methods called on <code>URI::Generic</code></a> were never updated to use this new parser. This means that methods like <code>URI::Generic.build</code> fail when given input that succeeds normally, and this also affects subclasses like URI::HTTP:</p>
<pre><code>$ pry -r uri -r uri/common -r uri/generic
[1] pry(main)> URI::Generic.build(host: "underscore_host.example")
URI::InvalidComponentError: bad component(expected host component): underscore_host.example
from /Users/gareth/.asdf/installs/ruby/3.1.3/lib/ruby/3.1.0/uri/generic.rb:591:in `check_host'
[2] pry(main)> URI::HTTP.build(host: "underscore_host.example")
URI::InvalidComponentError: bad component(expected host component): underscore_host.example
from /Users/gareth/.asdf/installs/ruby/3.1.3/lib/ruby/3.1.0/uri/generic.rb:591:in `check_host'
[3] pry(main)> URI("http://underscore_host.example")
=> #<URI::HTTP http://underscore_host.example>
</code></pre>
<p><code>URI::Generic.new</code> allows a configurable <code>parser</code> positional argument to override the class' default parser, but other factory methods like <code>.build</code> don't allow this override.</p>
<p>Arguably this doesn't cause problems because at least in the case above, the URI can be built with the polymorphic constructor, but having the option to build URIs from explicit named parts is useful, and leaving the outdated functionality in the <code>Generic</code> class is ambiguous. It's possible that the whole Generic class and its subclasses aren't intended to be used directly how I'm intending here, but there's nothing I could see that suggested this is the case.</p>
<p>I'm not aware of the entire list of differences between RFC2396 and RFC3986. The relevant difference here is that in RFC2396 an individual segment of a host (<a href="https://www.rfc-editor.org/rfc/rfc2396#section-3.2.2" class="external"><code>domainlabel</code>s</a>) could only be <code>alphanum | alphanum *( alphanum | "-" ) alphanum</code>, whereas RFC3986 allows <a href="https://www.rfc-editor.org/rfc/rfc3986#page-13" class="external">hostnames</a> to include any of <code>ALPHA / DIGIT / "-" / "." / "_" / "~"</code>. It's possible that other differences might cause issues for developers, but since this has gone over 8 years without anyone else caring about this, this is definitely not especially urgent.</p> Ruby master - Bug #19251 (Open): Limit amount of test failures due to updates of tzdatahttps://bugs.ruby-lang.org/issues/192512022-12-22T08:19:02Zvo.x (Vit Ondruch)v.ondruch@tiscali.cz
<p>It seems that recently, Ruby test suite is broken ~ twice a year due to changes in tzdata. I am not sure how detailed the test suite needs to be to have the right amount of test coverage, but it would be nice if Ruby developers had more control above this changes then this changes being forced upon us via OS update. This is followup to <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Ruby 3.1.3 testsuite fails after timezone 2022g update is applied (Closed)" href="https://bugs.ruby-lang.org/issues/19187">#19187</a>.</p>
<p>BTW with my Fedora / RHEL maintainer hat on, this is a bit annoying, because:</p>
<ol>
<li>It tends to hide other issues</li>
<li>In Fedora, it might block other development</li>
<li>Especially in RHEL, where there is not so big churn, it is unpleasant to start work on fixing CVE just to discover one needs to fix the tzdata test failures first</li>
</ol> Ruby master - Bug #19231 (Open): Integer#step and Float::INFINITY - inconsistent behaviour when c...https://bugs.ruby-lang.org/issues/192312022-12-13T15:17:41Zandrykonchin (Andrew Konchin)
<p>The initial issue was reported here <a href="https://github.com/oracle/truffleruby/issues/2797" class="external">https://github.com/oracle/truffleruby/issues/2797</a>.</p>
<p><code>0.step(Float::INFINITY, 10)</code> returns:</p>
<ul>
<li>
<code>Integers</code> when called with a block</li>
<li>
<code>Floats</code> when called without a block</li>
</ul>
<p>I would expect <code>Floats</code> to be returned in both cases.</p>
<p>Examples:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">0</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="no">Float</span><span class="o">::</span><span class="no">INFINITY</span><span class="p">,</span> <span class="mi">10</span><span class="p">).</span><span class="nf">take</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:class</span><span class="p">)</span>
<span class="o">=></span> <span class="p">[</span><span class="no">Float</span><span class="p">]</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">0</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="no">Float</span><span class="o">::</span><span class="no">INFINITY</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">offset</span><span class="o">|</span> <span class="nb">p</span> <span class="n">offset</span><span class="p">.</span><span class="nf">class</span><span class="p">;</span> <span class="k">break</span> <span class="p">}</span>
<span class="c1"># Integer</span>
</code></pre>
<p>When <code>to</code> argument is a finite <code>Float</code> value then calling with a block returns <code>Floats</code> as well:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">0</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="mf">100.0</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">offset</span><span class="o">|</span> <span class="nb">p</span> <span class="n">offset</span><span class="p">.</span><span class="nf">class</span><span class="p">;</span> <span class="k">break</span> <span class="p">}</span>
<span class="c1"># Float</span>
</code></pre>
<p>Wondering whether it's intentional behaviour.</p>
<p>I've found a related issue <a href="https://bugs.ruby-lang.org/issues/15518" class="external">https://bugs.ruby-lang.org/issues/15518</a>.</p> Ruby master - Bug #19192 (Open): IO has third data mode, document is incomplete.https://bugs.ruby-lang.org/issues/191922022-12-09T16:02:34ZYO4 (Yoshinao Muramatsu)
<p>The documentation on the mode parameter of File.open is incomplete, I would like to clarify IO's data mode actual behavior here.</p>
<p>document says</p>
<pre><code>To specify whether data is to be treated as text or as binary data, either of the following may be suffixed to any of the string read/write modes above:
't': Text data; sets the default external encoding to Encoding::UTF_8; on Windows, enables conversion between EOL and CRLF and enables interpreting 0x1A as an end-of-file marker.
'b': Binary data; sets the default external encoding to Encoding::ASCII_8BIT; on Windows, suppresses conversion between EOL and CRLF and disables interpreting 0x1A as an end-of-file marker.
If neither is given, the stream defaults to text data.
</code></pre>
<p>But actually it's more complicated than that.</p>
<p>There is three Data Mode</p>
<ul>
<li>text mode. Can convert encoding and newline.</li>
<li>binary mode. Cannot convert encoding nor newline. Encoding is treated as Encoding::ASCII_8BIT.</li>
<li>third mode: DOS TEXT mode. That enables conversion between EOL and CRLF and enables interpreting 0x1A as an end-of-file marker.</li>
</ul>
<p>On Windows platform<br>
't' textmode with universal newline conversion.<br>
'b' binary mode.<br>
If neither is given, DOS TEXT mode.</p>
<p>On other platforms<br>
't' textmode with universal newline conversion.<br>
'b' binary mode.<br>
If neither is given, textmode without newline conversion.</p>
<p>On Windows, there are some special cases.<br>
If Encoding conversion is specified, DOS TEXT mode is ignored and universal newline conversion applied.<br>
If access mode is "a+", last (only one) EOF charactor is overwritten when DOS TEXT mode.<br>
There are more parameter combinations, see <a href="https://gist.github.com/YO4/262e9bd5e44a37a7a2fa9118e271b30b" class="external">https://gist.github.com/YO4/262e9bd5e44a37a7a2fa9118e271b30b</a><br>
Is this all? I have not fully investigated.</p>
<p>Since the topic of data mode spanned access mode and encoding conversion, I don't think my English skills will allow me to summarize this into rdoc without breaking something...</p> Test - Bug #19186 (Open): test2https://bugs.ruby-lang.org/issues/191862022-12-06T01:25:49Zshugo (Shugo Maeda)
<p>Hello, this is a test issue.<br>
This is a second line with umlaut: ü</p> Test - Bug #19185 (Open): testhttps://bugs.ruby-lang.org/issues/191852022-12-06T01:24:24Zshugo (Shugo Maeda)
<p>hello, this is a test issue.<br>
This is a second line.</p> Ruby master - Bug #19172 (Open): `ruby_thread_has_gvl_p` is innacurate sometimes -- document or c...https://bugs.ruby-lang.org/issues/191722022-12-02T09:14:59Zivoanjo (Ivo Anjo)ivo.anjo@datadoghq.com
<p>Howdy 👋! I work for Datadog <a href="https://github.com/DataDog/dd-trace-rb" class="external">on the ddtrace gem</a> and I found a... sharp edge on the internal <code>ruby_thread_has_gvl_p</code> API.</p>
<p>I am aware that <code>ruby_thread_has_gvl_p</code> is documented an experimental API that is exported as a symbol but not present on the VM include files.</p>
<a name="Background"></a>
<h3 >Background<a href="#Background" class="wiki-anchor">¶</a></h3>
<p>In the ddtrace profiling component, we setup a signal handler and then periodically send SIGPROF signals to try to interrupt the running Ruby thread (e.g. the thread that is holding the global VM lock or equivalent).</p>
<p>In the signal handler, we need to perform some API calls which are not safe to do without the GVL. So we need to check if the signal handler got called in the thread that has the GVL.</p>
<a name="The-issue"></a>
<h3 >The issue<a href="#The-issue" class="wiki-anchor">¶</a></h3>
<pre><code class="c syntaxhl" data-language="c"><span class="kt">int</span>
<span class="nf">ruby_thread_has_gvl_p</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">rb_thread_t</span> <span class="o">*</span><span class="n">th</span> <span class="o">=</span> <span class="n">ruby_thread_from_native</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="n">th</span> <span class="o">&&</span> <span class="n">th</span><span class="o">-></span><span class="n">blocking_region_buffer</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
<p>In its current implementation, <code>ruby_thread_has_gvl_p</code> only checks if the thread has a <code>blocking_region_buffer</code> or not. Unfortunately, this means that when called from a thread that lost the GVL but not due to blocking (e.g. via <code>rb_thread_schedule()</code>), it can still claim that a thread is holding the GVL when that is not the case.</p>
<p>I ran into this issue in <a href="https://github.com/DataDog/dd-trace-rb/pull/2415" class="external">https://github.com/DataDog/dd-trace-rb/pull/2415</a>, and needed to find a workaround.</p>
<a name="Next-steps"></a>
<h3 >Next steps<a href="#Next-steps" class="wiki-anchor">¶</a></h3>
<p>Since this is an internal VM API, I'm not sure you'd want to change the current behavior, so I was thinking of perhaps two options:</p>
<ul>
<li>
<p>Is it worth changing <code>ruby_thread_has_gvl_p</code> to be accurate in the case I've listed?</p>
</li>
<li>
<p>If not, would you accept a PR to document its current limitations, so that others don't run into the same issue I did?</p>
</li>
</ul> Ruby master - Bug #19165 (Open): Method (with no param) delegation with *, **, and ... is slowhttps://bugs.ruby-lang.org/issues/191652022-12-01T08:49:16Zmatsuda (Akira Matsuda)ronnie@dio.jp
<p>I found that method delegation via Forwardable is much slower than normal method call when delegating a method that does not take parameters.</p>
<p>Here's a benchmark that explains what I mean.</p>
<pre><code>require 'forwardable'
require 'pp'
require 'benchmark/ips'
class Obj
extend Forwardable
attr_accessor :other
def initialize
@other = Other.new
end
def foo_without_splat
@other.foo
end
def foo_with_splat(*)
@other.foo(*)
end
def foo_with_splat_with_name(*args)
@other.foo(*args)
end
def foo_with_splat_and_double_splat(*, **)
@other.foo(*, **)
end
def foo_with_triple_dots(...)
@other.foo(...)
end
delegate :foo => :@other
end
class Other
def foo() end
end
o = Obj.new
Benchmark.ips do |x|
x.report 'simple call' do
o.other.foo
end
x.report 'delegate without splat' do
o.foo_without_splat
end
x.report 'delegate with splat' do
o.foo_with_splat
end
x.report 'delegate with splat with name' do
o.foo_with_splat_with_name
end
x.report 'delegate with splat and double splat' do
o.foo_with_splat_and_double_splat
end
x.report 'delegate with triple dots' do
o.foo_with_triple_dots
end
x.report 'delegate via forwardable' do
o.foo
end
end
(result)
simple call 38.918M (± 0.9%) i/s - 194.884M
delegate without splat
31.933M (± 1.6%) i/s - 159.611M
delegate with splat 10.269M (± 1.6%) i/s - 51.631M
delegate with splat with name
9.888M (± 1.0%) i/s - 49.588M
delegate with splat and double splat
4.117M (± 0.9%) i/s - 20.696M
delegate with triple dots
4.169M (± 0.9%) i/s - 20.857M
delegate via forwardable
9.204M (± 2.1%) i/s - 46.295M
</code></pre>
<p>It shows that Method delegation with a splat is 3-4 times slower (regardless of whether the parameter is named or not), and delegation with a triple-dot literal is 9-10 times slower than a method delegation without an argument.<br>
This may be because calling a method taking a splat always assigns an Array object even when no actual argument was given, and calling a method taking triple-dots assigns five Array objects and two Hash objects (this is equivalent to <code>*, **</code>).</p>
<p>Are there any chance reducing these object assignments and making them faster? My concern is that the Rails framework heavily uses this kind of method delegations, and presumably it causes unignorable performance overhead.</p> Ruby master - Bug #19157 (Open): URI bad component validation can be trickedhttps://bugs.ruby-lang.org/issues/191572022-11-28T23:46:13Zstraight-shoota (Johannes Müller)
<p><code>URI::HTTP</code> checks the validity of the URI components. For example, the path of a URI with authority component must be either empty or start with a slash.</p>
<p>This validation applies on the <code>.build</code> constructor as well as on the <code>path</code> setter.<br>
But it can be tricked when setting an empty authority component and scheme before setting a relative path, and then setting the authority and scheme again.<br>
This produces an invalid and incorrect URI.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s2">"uri"</span>
<span class="n">uri</span> <span class="o">=</span> <span class="no">URI</span><span class="o">::</span><span class="no">HTTP</span><span class="p">.</span><span class="nf">build</span><span class="p">({})</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">scheme</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">path</span> <span class="o">=</span> <span class="s2">"resource"</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">host</span> <span class="o">=</span> <span class="s2">"example.com"</span> <span class="c1"># this should raise URI::InvalidComponentError</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">scheme</span> <span class="o">=</span> <span class="s2">"http"</span>
<span class="n">uri</span><span class="p">.</span><span class="nf">to_s</span> <span class="c1"># => "http://example.comresource"</span>
</code></pre> Ruby master - Bug #19112 (Open): Ractor garbage collection breaks/disables all active tracepointshttps://bugs.ruby-lang.org/issues/191122022-11-08T10:58:37Zivoanjo (Ivo Anjo)ivo.anjo@datadoghq.com
<p>Howdy 👋! I work for Datadog <a href="https://github.com/DataDog/dd-trace-rb" class="external">on the <code>ddtrace</code> gem</a> and I found an issue with Ractors + TracePoint.</p>
<a name="Background"></a>
<h3 >Background<a href="#Background" class="wiki-anchor">¶</a></h3>
<p>For tracking time spent in Garbage Collection on our Ruby profiler, we use a tracepoint that listens to the internal GC events. While doing other experiments around Ractors and profiling, I noticed that our tracepoint would suddenly stop working after Ractors were used in the application. I was able to reduce this down to the testcase below.</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>I was able to reproduce this on any Ruby 3 version, including master (<code>ruby 3.2.0dev (2022-11-08T08:08:48Z master cdb3ec3af8) [x86_64-linux]</code>).</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">puts</span> <span class="no">RUBY_DESCRIPTION</span>
<span class="k">if</span> <span class="no">ENV</span><span class="p">[</span><span class="s1">'RUN_RACTOR'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'true'</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="mi">10</span> <span class="p">}.</span><span class="nf">take</span>
<span class="nb">puts</span> <span class="s2">"Ractor ran!"</span>
<span class="k">else</span>
<span class="nb">puts</span> <span class="s2">"Ractor DID NOT ran!"</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s2">"Enabling tracepoint"</span>
<span class="n">tracepoint</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="o">|</span><span class="n">tp</span><span class="o">|</span> <span class="nb">p</span> <span class="p">[</span><span class="n">tp</span><span class="p">.</span><span class="nf">path</span><span class="p">,</span> <span class="n">tp</span><span class="p">.</span><span class="nf">lineno</span><span class="p">,</span> <span class="n">tp</span><span class="p">.</span><span class="nf">event</span><span class="p">]</span> <span class="p">}.</span><span class="nf">tap</span><span class="p">(</span><span class="o">&</span><span class="ss">:enable</span><span class="p">)</span>
<span class="mi">5</span><span class="p">.</span><span class="nf">times</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s2">"Triggering gc!"</span><span class="p">;</span> <span class="no">GC</span><span class="p">.</span><span class="nf">start</span> <span class="p">}</span>
<span class="nb">puts</span> <span class="s2">"Tracepoint state is enabled? </span><span class="si">#{</span><span class="n">tracepoint</span><span class="p">.</span><span class="nf">enabled?</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span> <span class="s2">"Re-enabling tracepoint"</span>
<span class="n">tracepoint</span><span class="p">.</span><span class="nf">enable</span>
<span class="nb">puts</span> <span class="s2">"Finished!"</span>
</code></pre>
<a name="Expectation-and-result"></a>
<h3 >Expectation and result<a href="#Expectation-and-result" class="wiki-anchor">¶</a></h3>
<p>Without the Ractor, the tracepoint works as intended:</p>
<pre><code># RUN_RACTOR=false ./ruby ../ruby-3.1.2/triggergc.rb
ruby 3.2.0dev (2022-11-08T08:08:48Z master cdb3ec3af8) [x86_64-linux]
Ractor DID NOT ran!
Enabling tracepoint
["<internal:kernel>", 91, :line]
["../ruby-3.1.2/triggergc.rb", 14, :line]
["../ruby-3.1.2/triggergc.rb", 14, :line]
Triggering gc!
["<internal:gc>", 34, :line]
["../ruby-3.1.2/triggergc.rb", 14, :line]
Triggering gc!
["<internal:gc>", 34, :line]
["../ruby-3.1.2/triggergc.rb", 14, :line]
Triggering gc!
["<internal:gc>", 34, :line]
["../ruby-3.1.2/triggergc.rb", 14, :line]
Triggering gc!
["<internal:gc>", 34, :line]
["../ruby-3.1.2/triggergc.rb", 14, :line]
Triggering gc!
["<internal:gc>", 34, :line]
["../ruby-3.1.2/triggergc.rb", 16, :line]
["<internal:trace_point>", 257, :line]
Tracepoint state is enabled? true
["../ruby-3.1.2/triggergc.rb", 17, :line]
Re-enabling tracepoint
["../ruby-3.1.2/triggergc.rb", 18, :line]
["<internal:trace_point>", 213, :line]
["../ruby-3.1.2/triggergc.rb", 20, :line]
["../ruby-3.1.2/triggergc.rb", 20, :line]
Finished!
</code></pre>
<p>...but once the Ractor runs and is garbage collected, we see that the tracepoint breaks:</p>
<pre><code># RUN_RACTOR=true ./ruby ../ruby-3.1.2/triggergc.rb
ruby 3.2.0dev (2022-11-08T08:08:48Z master cdb3ec3af8) [x86_64-linux]
../ruby-3.1.2/triggergc.rb:5: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
Ractor ran!
Enabling tracepoint
["<internal:kernel>", 91, :line]
["../ruby-3.1.2/triggergc.rb", 14, :line]
["../ruby-3.1.2/triggergc.rb", 14, :line]
Triggering gc!
["<internal:gc>", 34, :line]
Triggering gc!
Triggering gc!
Triggering gc!
Triggering gc!
Tracepoint state is enabled? true
Re-enabling tracepoint
["../ruby-3.1.2/triggergc.rb", 20, :line]
["../ruby-3.1.2/triggergc.rb", 20, :line]
Finished
</code></pre>
<a name="Additional-notes"></a>
<h3 >Additional notes<a href="#Additional-notes" class="wiki-anchor">¶</a></h3>
<p>This is a somewhat annoying bug, because it can break all gems that use tracepoints, including <code>ddtrace</code>. In particular for <code>ddtrace</code>, our plan is to disable the feature that uses tracepoints for Ruby 3 users, to avoid any issues from our tracepoints getting disabled.</p> Ruby master - Bug #19048 (Open): Install of Ruby 3.1.x fails on Ubuntu 20.04 running on WSLhttps://bugs.ruby-lang.org/issues/190482022-10-11T13:39:55ZNickGrahamDfE (Nick Graham)Ruby master - Bug #19044 (Open): Attempting to compile a static ruby 3.1 fails with MinGWhttps://bugs.ruby-lang.org/issues/190442022-10-09T12:24:03Zmaxirmx (Maxim Samsonov)
<ol>
<li>
<p>I use the code from <a href="https://github.com/ruby/ruby/tree/ruby_3_1" class="external">https://github.com/ruby/ruby/tree/ruby_3_1</a> and GHA workflow at <a href="https://github.com/ruby/ruby/blob/ruby_3_1/.github/workflows/mingw.yml" class="external">https://github.com/ruby/ruby/blob/ruby_3_1/.github/workflows/mingw.yml</a> as a baseline</p>
</li>
<li>
<p>I alter configure command in the workflow from</p>
</li>
</ol>
<pre><code>- name: configure
run: >
../src/configure --disable-install-doc --prefix=/.
--build=$CHOST --host=$CHOST --target=$CHOST
</code></pre>
<pre><code> to
</code></pre>
<pre><code>- name: configure
run: >
../src/configure --disable-install-doc --with-static-linked-ext --disable-shared --without-gmp -- prefix=/.
--build=$CHOST --host=$CHOST --target=$CHOST
</code></pre>
<p>and uncomment <code>option nodynamic</code> in <code>ext/Setup</code></p>
<ol start="3">
<li>The first failure I observe is:</li>
</ol>
<pre><code>C:\msys64\ucrt64\bin\dllwrap.exe: WARNING: C:\msys64\ucrt64\bin\dllwrap.exe is deprecated, use gcc -shared or ld -shared instead
C:\msys64\ucrt64\bin\dllwrap.exe: no export definition file provided.
Creating one, but that may not be what you want
x86_64-w64-mingw32-cc: error: unrecognized command-line option '-mno-cygwin'; did you mean '-mno-clwb'?
C:\msys64\ucrt64\bin\dllwrap.exe: x86_64-w64-mingw32-cc exited with status 1
make: *** [GNUmakefile:73: ruby.exp] Error 1
</code></pre>
<pre><code> In order to resolve it I comment out ``` DLLWRAP += -mno-cygwin``` in ```cygwin/GNUmakefile.in```
</code></pre>
<ol start="4">
<li>Then I get the second failure:</li>
</ol>
<pre><code>creating ruby.exp
C:\msys64\ucrt64\bin\dllwrap.exe: WARNING: C:\msys64\ucrt64\bin\dllwrap.exe is deprecated, use gcc -shared or ld -shared instead
C:\msys64\ucrt64\bin\dllwrap.exe: no export definition file provided.
Creating one, but that may not be what you want
C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: warning: cannot find entry symbol _DllMainCRTStartup@12; defaulting to 0000000063981000
C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: warning: cannot find entry symbol _DllMainCRTStartup@12; defaulting to 0000000063981000
C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: warning: cannot find entry symbol _DllMainCRTStartup@12; defaulting to 0000000063981000
C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: ruby.o:ruby.c:(.text+0x54f5): undefined reference to `Init_enc'
collect2.exe: error: ld returned 1 exit status
make: *** [GNUmakefile:74: ruby.exp] Error 1
</code></pre>
<p>I believe that when <code>GNUMakefile</code> is generated <code>disable-shared</code> flag is ignored silently</p> Ruby master - Bug #19043 (Open): Segfault on macOS 11.7 while using StringScanner in multiple thr...https://bugs.ruby-lang.org/issues/190432022-10-06T21:08:47Zkeithdoggett (Keith Doggett)
<p>During testing on our CI, one of the runners failed due to a segfault that appears to have originated from the <code>StringScanner</code> class, specifically the <code>scan_until</code> method. The test ensures that we are able to properly parse strings in a multithreaded environment.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">def</span> <span class="nf">test_multithreaded</span>
<span class="n">parser</span> <span class="o">=</span> <span class="no">RGeo</span><span class="o">::</span><span class="no">WKRep</span><span class="o">::</span><span class="no">WKTParser</span><span class="p">.</span><span class="nf">new</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">fixtures</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s2">"isere.wkt"</span><span class="p">).</span><span class="nf">read</span>
<span class="no">Array</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span> <span class="k">do</span>
<span class="no">Thread</span><span class="p">.</span><span class="nf">fork</span> <span class="k">do</span>
<span class="n">parser</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:join</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
<p>Here's the <code>parse</code> method</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="n">str</span><span class="p">)</span>
<span class="vi">@mutex</span><span class="p">.</span><span class="nf">synchronize</span> <span class="k">do</span>
<span class="n">str</span> <span class="o">=</span> <span class="n">str</span><span class="p">.</span><span class="nf">downcase</span>
<span class="vi">@cur_factory</span> <span class="o">=</span> <span class="vi">@exact_factory</span>
<span class="k">if</span> <span class="vi">@cur_factory</span>
<span class="vi">@cur_factory_support_z</span> <span class="o">=</span> <span class="vi">@cur_factory</span><span class="p">.</span><span class="nf">property</span><span class="p">(</span><span class="ss">:has_z_coordinate</span><span class="p">)</span> <span class="p">?</span> <span class="kp">true</span> <span class="p">:</span> <span class="kp">false</span>
<span class="vi">@cur_factory_support_m</span> <span class="o">=</span> <span class="vi">@cur_factory</span><span class="p">.</span><span class="nf">property</span><span class="p">(</span><span class="ss">:has_m_coordinate</span><span class="p">)</span> <span class="p">?</span> <span class="kp">true</span> <span class="p">:</span> <span class="kp">false</span>
<span class="k">end</span>
<span class="vi">@cur_expect_z</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="vi">@cur_expect_m</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="vi">@cur_srid</span> <span class="o">=</span> <span class="vi">@default_srid</span>
<span class="k">if</span> <span class="vi">@support_ewkt</span> <span class="o">&&</span> <span class="n">str</span> <span class="o">=~</span> <span class="sr">/^srid=(\d+);/i</span>
<span class="n">str</span> <span class="o">=</span> <span class="vg">$'</span>
<span class="vi">@cur_srid</span> <span class="o">=</span> <span class="no">Regexp</span><span class="p">.</span><span class="nf">last_match</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="nf">to_i</span>
<span class="k">end</span>
<span class="k">begin</span>
<span class="n">start_scanner</span><span class="p">(</span><span class="n">str</span><span class="p">)</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">parse_type_tag</span>
<span class="k">if</span> <span class="vi">@cur_token</span> <span class="o">&&</span> <span class="o">!</span><span class="vi">@ignore_extra_tokens</span>
<span class="k">raise</span> <span class="no">Error</span><span class="o">::</span><span class="no">ParseError</span><span class="p">,</span> <span class="s2">"Extra tokens beginning with </span><span class="si">#{</span><span class="vi">@cur_token</span><span class="p">.</span><span class="nf">inspect</span><span class="si">}</span><span class="s2">."</span>
<span class="k">end</span>
<span class="k">ensure</span>
<span class="n">clean_scanner</span>
<span class="k">end</span>
<span class="n">obj</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Where the <code>StringScanner</code> is created and assigned to <code>@scanner</code> in <code>start_scanner</code> and <code>@scanner</code> is set to <code>nil</code> in <code>clean_scanner</code>. According to the control frame information in the log, the error is caused in the <code>scan_until</code> method, but it might be due to <code>gc_sweep</code> being run at some point.</p>
<p>Unfortunately since this happened on a CI system I don't have access to the diagnostic file. We've tried to replicate this locally unsuccessfully. The best we've done is caused a deadlock while trying to join the threads, but cannot reliably reproduce that. Here's a link to the CI run that caused the issue if that's helpful (<a href="https://github.com/rgeo/rgeo/actions/runs/3144578897/jobs/5110771257" class="external">https://github.com/rgeo/rgeo/actions/runs/3144578897/jobs/5110771257</a>).</p>
<p>If there's any tips on how to reproduce or anything you want me to try to get more information please let me know.</p> Ruby master - Bug #19039 (Open): Closing an IO being select'ed in another thread does not resume ...https://bugs.ruby-lang.org/issues/190392022-10-06T05:30:13Zmame (Yusuke Endoh)mame@ruby-lang.org
<p>Is this intentional?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">r1</span><span class="p">,</span> <span class="n">w1</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">pipe</span>
<span class="n">r2</span><span class="p">,</span> <span class="n">w2</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">pipe</span>
<span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="nb">select</span><span class="p">([</span><span class="n">r1</span><span class="p">,</span> <span class="n">r2</span><span class="p">])</span>
<span class="nb">p</span> <span class="ss">:ok</span>
<span class="k">end</span>
<span class="nb">sleep</span> <span class="mi">1</span>
<span class="nb">p</span> <span class="n">r1</span><span class="p">.</span><span class="nf">close</span>
<span class="c1"># expected: closing r1 resumes select([r1, r2]) in the thread</span>
<span class="c1"># actual: select([r1, r2]) continues to wait</span>
<span class="nb">sleep</span> <span class="mi">1</span>
<span class="n">w2</span> <span class="o"><<</span> <span class="s2">"foo"</span>
<span class="c1"># Making r2 readable resumes select([r1, r2])</span>
<span class="c1"># And it raises an exception: closed stream (IOError)</span>
<span class="nb">sleep</span> <span class="mi">1</span>
</code></pre>
<p>Incidentally, IO#read is resumed by closing the IO.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">r1</span><span class="p">,</span> <span class="n">w1</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">pipe</span>
<span class="no">Thread</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">r1</span><span class="p">.</span><span class="nf">read</span>
<span class="nb">p</span> <span class="ss">:ok</span>
<span class="k">end</span>
<span class="nb">sleep</span> <span class="mi">1</span>
<span class="nb">p</span> <span class="n">r1</span><span class="p">.</span><span class="nf">close</span>
<span class="c1"># Closing r1 resumes r1.read in the thread</span>
<span class="c1"># And it raises: stream closed in another thread (IOError)</span>
<span class="nb">sleep</span> <span class="mi">1</span>
</code></pre> Ruby master - Bug #19017 (Open): Net::HTTP may block when attempting to reuse a persistent connec...https://bugs.ruby-lang.org/issues/190172022-09-22T20:56:35Zjoshc (Josh C)josh.nw@gmail.com
<p>Ruby's Net::HTTP code performs a blocking <code>Net::BufferedIO#eof?</code> check when attempting to reuse a persistent HTTP connection. See <a href="https://github.com/ruby/ruby/blob/6b099328af2ae2d04cbfd06fedc36a19cdecd30d/lib/net/http.rb#L1573" class="external">https://github.com/ruby/ruby/blob/6b099328af2ae2d04cbfd06fedc36a19cdecd30d/lib/net/http.rb#L1573</a>. The bug is the check can hang for up to the HTTP <code>read_timeout</code>, which is 60 seconds by default.</p>
<p>The code calls <code>TCPSocket#wait_readable(0)</code> to see if the socket is readable before calling the blocking <code>eof?</code> method. However, it's possible for the socket to be readable with SSL Handshake records and no Application Data. So the call to <code>eof?</code> will process the SSL Handshake records, but hang since no Application Data is available.</p>
<p>The issue can be triggered if a TLS 1.3 server sends a <code>NewSessionTicket</code> sometime after Application Data is written. The attached client and server code demonstrate the problem. Note it's important that the client and server be on separate hosts otherwise <code>eof?</code> will always return immediately.</p>
<p>On the server, copy <code>Server.java</code> and <code>certs.p12</code> into a directory, install JDK 17, compile the server and run it:</p>
<pre><code>$ openssl pkcs12 -info -in certs.p12 -noout -passin pass:password
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
$ sudo apt install -y openjdk-17-jdk openjdk-17-jre
$ javac Server.java
$ java -Djavax.net.debug=ssl,verbose Server
Loaded pkcs12
</code></pre>
<p>On the client, copy <code>http.rb</code> and <code>ca.pem</code> into a directory, add the IP address for the server as <code>pluto</code> to <code>/etc/hosts</code>:</p>
<pre><code>$ file ca.pem
$ sudo vi /etc/hosts
...
192.168.0.10 pluto
...
$ ruby --version
ruby 2.7.6p219 (2022-04-12 revision c9c2245c0a) [x86_64-linux]
$ openssl version
OpenSSL 1.1.1f 31 Mar 2020
</code></pre>
<p>Run the client to make the first request:</p>
<pre><code>$ ruby http.rb
opening connection to pluto:8888...
opened
starting SSL for pluto:8888...
</code></pre>
<p>The server will handle request_1 and trigger a new session ticket:</p>
<pre><code>javax.net.ssl|DEBUG|10|main|2022-09-22 18:18:23.269 UTC|SSLCipher.java:466|jdk.tls.keyLimits: entry = AES/GCM/NoPadding KeyUpdate 2^37. AES/GCM/NOPADDING:KEYUPDATE = 137438953472
Connected to 37532
Handling request_0
... snip ...
javax.net.ssl|DEBUG|10|main|2022-09-22 18:18:25.310 UTC|SSLCipher.java:2024|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|DEBUG|10|main|2022-09-22 18:18:25.335 UTC|SSLCipher.java:1870|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
read body
updated session data
javax.net.ssl|ALL|10|main|2022-09-22 18:18:25.343 UTC|SSLSocketImpl.java:1564|trigger new session ticket
wrote response
Handling request_1
</code></pre>
<p>The client will hang when trying to reuse the persistent connection:</p>
<pre><code>OSSL_DEBUG: SSL SESSION new callback added [ossl_ssl.c:963]
SSL established, protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384
<- "POST / HTTP/1.1\r\nAccept-Encoding: identity\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: pluto:8888\r\nContent-Length: 0\r\n\r\n"
<- ""
OSSL_DEBUG: SSL SESSION new callback entered [ossl_ssl.c:454]
-> "HTTP/1.1 200 OK\r\n"
-> "Content-Length: 0\r\n"
-> "\r\n"
reading 0 bytes...
-> ""
read 0 bytes
Conn keep-alive
OSSL_DEBUG: SSL SESSION new callback entered [ossl_ssl.c:454]
</code></pre>
<p>Pressing Ctrl-C shows the backtrace:</p>
<pre><code>^CTraceback (most recent call last):
11: from http.rb:10:in `<main>'
10: from /home/josh/.rbenv/versions/2.7.6/lib/ruby/2.7.0/net/http.rb:933:in `start'
9: from http.rb:17:in `block in <main>'
8: from /home/josh/.rbenv/versions/2.7.6/lib/ruby/2.7.0/net/http.rb:1294:in `post'
7: from /home/josh/.rbenv/versions/2.7.6/lib/ruby/2.7.0/net/http.rb:1506:in `send_entity'
6: from /home/josh/.rbenv/versions/2.7.6/lib/ruby/2.7.0/net/http.rb:1492:in `request'
5: from /home/josh/.rbenv/versions/2.7.6/lib/ruby/2.7.0/net/http.rb:1518:in `transport_request'
4: from /home/josh/.rbenv/versions/2.7.6/lib/ruby/2.7.0/net/http.rb:1573:in `begin_transport'
3: from /home/josh/.rbenv/versions/2.7.6/lib/ruby/2.7.0/net/protocol.rb:134:in `eof?'
2: from /home/josh/.rbenv/versions/2.7.6/lib/ruby/2.7.0/openssl/buffering.rb:300:in `eof?'
1: from /home/josh/.rbenv/versions/2.7.6/lib/ruby/2.7.0/openssl/buffering.rb:57:in `fill_rbuff'
/home/josh/.rbenv/versions/2.7.6/lib/ruby/2.7.0/openssl/buffering.rb:57:in `sysread': Interrupt
</code></pre>
<p>I get the same behavior with latest ruby too:</p>
<pre><code>$ ruby --version
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
</code></pre>
<p>Changing Net::HTTP to the following:</p>
<pre><code>elsif @socket.io.read_nonblock(0, exception: false).nil?
</code></pre>
<p>Resolves the issue:</p>
<pre><code>$ ruby http.rb
opening connection to pluto:8888...
opened
starting SSL for pluto:8888...
OSSL_DEBUG: SSL SESSION new callback added [ossl_ssl.c:963]
SSL established, protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384
<- "POST / HTTP/1.1\r\nAccept-Encoding: identity\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: pluto:8888\r\nContent-Length: 0\r\n\r\n"
<- ""
OSSL_DEBUG: SSL SESSION new callback entered [ossl_ssl.c:454]
-> "HTTP/1.1 200 OK\r\n"
-> "Content-Length: 0\r\n"
-> "\r\n"
reading 0 bytes...
-> ""
read 0 bytes
Conn keep-alive
<- "POST / HTTP/1.1\r\nAccept-Encoding: identity\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: pluto:8888\r\nContent-Length: 0\r\n\r\n"
<- ""
OSSL_DEBUG: SSL SESSION new callback entered [ossl_ssl.c:454]
-> "HTTP/1.1 200 OK\r\n"
-> "Content-Length: 0\r\n"
-> "\r\n"
reading 0 bytes...
-> ""
read 0 bytes
Conn keep-alive
</code></pre>
<p>However, based on <a href="https://github.com/ruby/ruby/pull/1089#issuecomment-159878003" class="external">https://github.com/ruby/ruby/pull/1089#issuecomment-159878003</a> that change may not be correct. Or it could be that Ruby on Windows doesn't have this issue anymore.</p> Ruby master - Bug #18995 (Open): IO#set_encoding sometimes set an IO's internal encoding to the d...https://bugs.ruby-lang.org/issues/189952022-09-04T23:06:54Zjavanthropus (Jeremy Bopp)jeremy@bopp.net
<p>This script demonstrates the behavior:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">show</span><span class="p">(</span><span class="n">io</span><span class="p">)</span>
<span class="nb">printf</span><span class="p">(</span>
<span class="s2">"external encoding: %-25p internal encoding: %-25p</span><span class="se">\n</span><span class="s2">"</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="k">end</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_external</span> <span class="o">=</span> <span class="s1">'iso-8859-1'</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="s1">'iso-8859-2'</span>
<span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s1">'/dev/null'</span><span class="p">)</span> <span class="k">do</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">'utf-8'</span><span class="p">,</span> <span class="kp">nil</span><span class="p">)</span>
<span class="n">show</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="c1"># f.internal_encoding is iso-8859-2, as expected</span>
<span class="n">f</span><span class="p">.</span><span class="nf">set_encoding</span><span class="p">(</span><span class="s1">'utf-8'</span><span class="p">,</span> <span class="s1">'invalid'</span><span class="p">)</span>
<span class="n">show</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="c1"># f.internal_encoding is now iso-8859-1!</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_external</span> <span class="o">=</span> <span class="s1">'iso-8859-3'</span>
<span class="no">Encoding</span><span class="p">.</span><span class="nf">default_internal</span> <span class="o">=</span> <span class="s1">'iso-8859-4'</span>
<span class="n">show</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="c1"># f.internal_encoding is now iso-8859-3!</span>
<span class="k">end</span>
</code></pre>
<p>In the 1st case, we see that the IO's internal encoding is set to the current setting of Encoding.default_internal. In the 2nd case, the IO's internal encoding is set to Encoding.default_external instead. The 3rd case is more interesting because it shows that the IO's internal encoding is actually following the current setting of Encoding.default_external. It didn't just copy it when #set_encoding was called. It changes whenever Encoding.default_external changes.</p>
<p>What should the correct behavior be?</p> Ruby master - Bug #18993 (Open): Inconsistent Range#size for Float and Rationalhttps://bugs.ruby-lang.org/issues/189932022-09-02T18:18:04Zmasasakano (Masa Sakano)
<p>The returned values of Range#size between Rational and Float and also with regard to <code>exclude_end</code> of true and false are inconsistent.</p>
<p>The example below highlights the difference. The first and second should return the same value. The difference between the first and third seems strange - if this is the specification, it should be clearly described in the <a href="https://ruby-doc.org/core-3.1.2/Range.html#method-i-size" title="Ruby-3.1.2 official doc of Range" class="external">doc</a>. This point may be related to the issue "Misc <a class="issue tracker-5 status-1 priority-4 priority-default" title="Misc: Doc for Range#size for Float/Rational does not make sense (Open)" href="https://bugs.ruby-lang.org/issues/18984">#18984</a>".</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="mi">5</span><span class="p">.</span><span class="nf">quo</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">...</span><span class="mi">5</span><span class="p">).</span><span class="nf">size</span> <span class="c1"># => 3</span>
<span class="p">(</span><span class="mi">5</span><span class="p">.</span><span class="nf">quo</span><span class="p">(</span><span class="mi">3</span><span class="p">).</span><span class="nf">to_f</span><span class="o">...</span><span class="mi">5</span><span class="p">).</span><span class="nf">size</span> <span class="c1"># => 4</span>
<span class="p">(</span><span class="mi">5</span><span class="p">.</span><span class="nf">quo</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="o">..</span><span class="mi">5</span><span class="p">).</span><span class="nf">size</span> <span class="c1"># => 4</span>
<span class="p">(</span><span class="mi">5</span><span class="p">.</span><span class="nf">quo</span><span class="p">(</span><span class="mi">3</span><span class="p">).</span><span class="nf">to_f</span><span class="o">..</span><span class="mi">5</span><span class="p">).</span><span class="nf">size</span> <span class="c1"># => 4</span>
</code></pre> Ruby master - Bug #18966 (Open): Strange behavior when numbered parameters and method definition ...https://bugs.ruby-lang.org/issues/189662022-08-19T08:51:27Ztompng (tomoya ishida)tomoyapenguin@gmail.com
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s1">'a'</span><span class="p">.</span><span class="nf">tap</span> <span class="p">{</span> <span class="nb">p</span> <span class="n">_1</span><span class="p">;</span> <span class="k">def</span> <span class="nf">f</span><span class="p">()</span><span class="o">=</span><span class="mi">42</span> <span class="p">}</span> <span class="c1">#=> "a"</span>
<span class="s1">'a'</span><span class="p">.</span><span class="nf">tap</span> <span class="p">{</span> <span class="nb">p</span> <span class="n">_1</span><span class="p">;</span> <span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">a</span><span class="p">)</span><span class="o">=</span><span class="mi">42</span> <span class="p">}</span> <span class="c1">#=> nil</span>
<span class="s1">'a'</span><span class="p">.</span><span class="nf">tap</span> <span class="p">{</span> <span class="k">def</span> <span class="nf">f</span><span class="p">()</span><span class="o">=</span><span class="mi">42</span><span class="p">;</span> <span class="nb">p</span> <span class="n">_1</span> <span class="p">}</span> <span class="c1">#=> "a"</span>
<span class="s1">'a'</span><span class="p">.</span><span class="nf">tap</span> <span class="p">{</span> <span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">a</span><span class="p">)</span><span class="o">=</span><span class="mi">42</span><span class="p">;</span> <span class="nb">p</span> <span class="n">_1</span> <span class="p">}</span> <span class="c1"># Syntax Error -:1: ordinary parameter is defined</span>
</code></pre> Ruby master - Bug #18947 (Open): Unexpected Errno::ENAMETOOLONG on Windowshttps://bugs.ruby-lang.org/issues/189472022-07-29T07:08:19Zinversion (Yura Babak)
<p>On Windows 10, I am working on a script to copy a complex folder structure.</p>
<p>Pathname and FileUtils work fine for me until there is a folder with a <strong>very long path</strong> (>260 chars).</p>
<p>Normally you cannot access such a folder with Ruby.<br>
The next operations will raise <code>Errno::ENOENT</code></p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Pathname</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="p">).</span><span class="nf">children</span>
<span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkpath</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="p">)</span>
</code></pre>
<p>But there is a way in Windows to remove the MAX_PATH limitation.<br>
You can find a small .reg file in this article:<br>
<a href="https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry" class="external">https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry</a></p>
<p>After changing this system option, things start to work strangely in Ruby.</p>
<p>This will now raise <code>Errno::ENAMETOOLONG</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Pathname</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="p">).</span><span class="nf">children</span>
</code></pre>
<p>But at the same time, you can create a folder with such a long path and write-read a file in it</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkpath</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="p">)</span>
<span class="n">file</span> <span class="o">=</span> <span class="no">Pathname</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="o">+</span><span class="s1">'/file.txt'</span><span class="p">)</span>
<span class="n">file</span><span class="p">.</span><span class="nf">write</span> <span class="s1">'oooooooooo'</span>
<span class="nb">puts</span> <span class="no">Pathname</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="o">+</span><span class="s1">'/file.txt'</span><span class="p">).</span><span class="nf">read</span>
</code></pre>
<p>So you can work with individual items but attempts to list such folders' content fail (<code>.children</code>, <code>.glob</code>, <code>.copy</code>, etc).<br>
In my case, deep <code>.glob</code> is broken for all the parent folders of that deep long-path folder ((</p>
<p>The only way I found for listing is</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'win32ole'</span>
<span class="n">fso</span> <span class="o">=</span> <span class="no">WIN32OLE</span><span class="p">.</span><span class="nf">new</span> <span class="s1">'Scripting.FileSystemObject'</span>
<span class="k">for</span> <span class="n">file</span> <span class="k">in</span> <span class="n">fso</span><span class="o">.</span><span class="no">GetFolder</span><span class="p">(</span><span class="mi">300</span><span class="n">_chars_path</span><span class="p">).</span><span class="nf">files</span>
<span class="n">file</span><span class="p">.</span><span class="nf">name</span>
<span class="n">file</span><span class="p">.</span><span class="nf">path</span><span class="p">.</span><span class="nf">length</span>
<span class="k">end</span>
</code></pre>
<p>But using this workaround breaks all my code workflow built on top of Pathname and FileUtils ((.</p>
<p>So for me, it looks like some operations with long-path folders are not working just because in Ruby there is a check for the path length and not a real operation problem. And in some places (see .mkpath) there is no such check and all works fine.</p>
<p>Also notice that other applications on Windows have no problems with long-path folders (like Total Commander).</p>
<p>Please consider reviewing if we really need to raise <code>Errno::ENAMETOOLONG</code> if the <code>LongPathsEnabled</code> option is enabled in the Windows registry.</p> Ruby master - Bug #18923 (Open): Dir.glob Errno::ENAMETOOLONG - Caused by outdated logic in open_...https://bugs.ruby-lang.org/issues/189232022-07-17T20:33:45Ztest35965@gmail.com (Alexander Riccio)
<p>This bug - as do most of my bug reports - started out while dealing with something productive and completely unrelated :)</p>
<p>In short: <code>open_dir_handle</code> in <code>win32.c</code> handles long paths incorrectly.</p>
<p>At best, this will cause programs that use <code>Dir.glob</code> to crash on windows when paths in the tree exceed the length allocated by ruby. I believe this is wrong in master too.</p>
<p>I'm a bit confused by error handling for <a href="https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew" class="external"><code>GetFinalPathNameByHandleW</code></a>. It <em>looks correct</em> , but its a confusing enough API that I'm going to mention it further down just in case.</p>
<p>In more detail:</p>
<p>As the developer of altWinDirStat, I'm way more familiar than I'd like with the labyrinth of weirdness that is handling paths on Windows. Long file paths have been supported through UNC paths and similar weirdness for as long as I've been around, maybe since the beginning of NT.</p>
<p>Many probably know all of this already, but will recap off the top of my head for context:</p>
<p>"Long" means up to the UTF-16 limit of 32k characters or so (and yes, IIRC, official documentation does not give the exact number of 32,768 because they say something about substitutions and such), which in practice is half the max value <code>UNICODE_STRING</code> struct can store in the <code>USHORT</code> <code>Length</code> member. Windows 10 has recently removed the <code>MAX_PATH</code> restriction from many dated Windows APIs that used to require kinda-UNC path prefixing (<code>"\\?\"</code>), which makes things easier for users, but also broke a lot of poorly written software that handled buffers incorrectly.</p>
<p>In ruby, any program that relies on <code>Dir.glob</code> will crash with a valid <em>final</em> path that exceeds MAX_PATH, since <a href="https://github.com/ruby/ruby/blob/82add06f9cbe00ad611e99692d8d49b77159c601/win32/win32.c#L2061" class="external"><code>GetFinalPathNameByHandleW</code> will return a length longer than <code>FINAL_PATH_MAX</code></a>.</p>
<p>One option to fix this is to make the stack buffer large enough to hold any possible string. I don't think this is a good idea. But it would be the smallest change.</p>
<p>A different option is to add this error explicitly to the <code>Dir.glob</code> docs, and make every single program work around this. I don't think that's a good fix either.</p>
<p>Another option to fix this that I do not <em>necessarily</em> recommend is to do the classic windows thing and call <code>GetFinalPathNameByHandleW</code> once with a zero-sized buffer and then use the return value of <code>GetFinalPathNameByHandleW</code> to allocate a sufficiently large buffer on the heap to hold the buffer, then call it again. Much slower, but definitely works well. This could cause a lot of heap churn if you have a lot of files (e.g. anybody who has a node_modules somewhere in their monorepo). Apparently people are already paying attention to <a href="https://bugs.ruby-lang.org/issues/9934" class="external">filepath-sized allocations in ruby</a>.</p>
<p>I'm very very OCD about how I use heap when I'm writing native code, it's a huge pain, but OCD means OCD <em>and</em> slightly better performance :). If you want to do it, the other option I see is <em>first</em> try the API with a <code>MAX_PATH</code> sized stack buffer, and if that works, excellent! Lightning fast code, no heap. If the stack buffer is too small, <em>then</em> I'll allocate a heap buffer big enough to hold the size of the string requested by whatever that win32 api has suggested I use in the return code. Excellent performance, but you need to make sure you're not introducing new bugs when you implement the code twice now, and not to mix up the heap/stack buffers.</p>
<p>With any fix, I suggest checking the last error on failure and reporting that instead. That may be better than just using the length of the input string. If the error is any of the errors listed in the documentation, it probably doesn't make sense to use the length of the input string anyways... in that case there's something wrong?</p>
<p>It might be a good idea for someone with the time to go through and update all the <code>MAX_PATH</code>-adjacent code to support long paths. That will be a huge endeavor, but worth it.</p>
<p>You can reproduce this with one line, calling <code>Dir.glob([])</code> on any valid path that's longer than 260 characters.</p>
<p>I'm also noticing that ruby is still using <code>lstrlenW</code> and <code>lstrcat</code> in <code>win32.c</code>... this is a terrible idea! <code>lstrcat</code> catches access violations/segfaults and then just continues program execution. I've seen this happen in other software and lost data to it. It's a pervasive enough problem on windows that I once thought of writing an EMET-style shim to redirect those system calls to normal c stdlib functions that crash on access violations. You don't need to switch to strsafe funcs or secure c lib funcs, it's an easy enough drop-in fix to switch to standard functions. Nothing will break unless something was already broken. I'll open a simple bug for that.</p>
<hr>
<p>The "maybe an issue" is that the <code>GetFinalPathNameByHandleW</code> appears even more confusing than most old win32 path-handling functions. <a href="https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew" class="external">The docs</a> say:</p>
<pre><code>If the function succeeds, the return value is the length of the string received by lpszFilePath, in TCHARs. This value does not include the size of the terminating null character.
</code></pre>
<p>...then a note for the ANSI version on vista and following windows versions, with subtly contradictory behavior, and then the failure behavior:</p>
<pre><code>If the function fails because lpszFilePath is too small to hold the string plus the terminating null character, the return value is the required buffer size, in TCHARs. This value includes the size of the terminating null character.
If the function fails for any other reason, the return value is zero. To get extended error information, call GetLastError.
</code></pre>
<p>...and then a table that probably talks about the possible values <code>GetLastError</code> will return, though annoyingly, doesn't say that explicitly.</p>
<p>I've been off-by-one when dealing with APIs like this enough times to not trust myself or any human around it. The SAL in the headers isn't as good as it is for some similarly-worded APIs, so it's not useful here.</p> Ruby master - Bug #18903 (Open): Stack overflow signal handling seems to be triggered once and th...https://bugs.ruby-lang.org/issues/189032022-07-07T14:33:01Zchrisseaton (Chris Seaton)chris@chrisseaton.com
<p>This program creates a recursive object graph and then tries to convert it to JSON with no max depth, so it stack overflows in C code that does no co-operative stack overflow checks, as the bytecode interpreter would. This therefore triggers a segmentation fault and the stack overflow detection there. It works the first time, but the second time around it doesn't and the program hard crashes on M1.</p>
<p>Is there something like a guard page permission that is switched during the handling, and needs to switched back for the guard page to work again?</p>
<p>Note that it isn't JSON specific - I think any stack overflow within C code would do it.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s1">'json'</span>
<span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">a</span> <span class="o"><<</span> <span class="n">a</span>
<span class="k">begin</span>
<span class="no">JSON</span><span class="p">.</span><span class="nf">dump</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="k">rescue</span> <span class="no">Exception</span>
<span class="nb">puts</span> <span class="s1">'rescued'</span>
<span class="k">end</span>
<span class="no">JSON</span><span class="p">.</span><span class="nf">dump</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</code></pre> Ruby master - Bug #18878 (Open): parse.y: Foo::Bar {} is inconsistently rejectedhttps://bugs.ruby-lang.org/issues/188782022-06-26T13:06:35Zqnighy (Masaki Hara)
<p>The following source doesn't parse:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Foo</span><span class="o">::</span><span class="no">Bar</span> <span class="p">{}</span>
</code></pre>
<p>despite the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">bar</span> <span class="c1"># local variable or method call</span>
<span class="no">Bar</span> <span class="c1"># constant</span>
<span class="n">bar</span><span class="p">()</span> <span class="c1"># method call</span>
<span class="no">Bar</span><span class="p">()</span> <span class="c1"># method call</span>
<span class="n">bar</span> <span class="p">{}</span> <span class="c1"># method call</span>
<span class="no">Bar</span> <span class="p">{}</span> <span class="c1"># method call</span>
<span class="n">bar</span><span class="p">()</span> <span class="p">{}</span> <span class="c1"># method call</span>
<span class="no">Bar</span><span class="p">()</span> <span class="p">{}</span> <span class="c1"># method call</span>
<span class="no">Foo</span><span class="o">::</span><span class="n">bar</span> <span class="c1"># method call</span>
<span class="no">Foo</span><span class="o">::</span><span class="no">Bar</span> <span class="c1"># constant</span>
<span class="no">Foo</span><span class="o">::</span><span class="n">bar</span><span class="p">()</span> <span class="c1"># method call</span>
<span class="no">Foo</span><span class="o">::</span><span class="no">Bar</span><span class="p">()</span> <span class="c1"># method call</span>
<span class="no">Foo</span><span class="o">::</span><span class="n">bar</span> <span class="p">{}</span> <span class="c1"># method call</span>
<span class="c1"># Foo::Bar {} # SyntaxError</span>
<span class="no">Foo</span><span class="o">::</span><span class="n">bar</span><span class="p">()</span> <span class="p">{}</span> <span class="c1"># method call</span>
<span class="no">Foo</span><span class="o">::</span><span class="no">Bar</span><span class="p">()</span> <span class="p">{}</span> <span class="c1"># method call</span>
</code></pre>
<p>Especially considering <code>Bar {}</code>, this looks like a missing implementation rather than an intentional behavior.</p> Ruby master - Bug #18842 (Open): Ruby's Resolv library does not handle correctly the `NODATA` casehttps://bugs.ruby-lang.org/issues/188422022-06-19T17:39:19Zpiradata (Guilherme Ferreira)
<p>Hello, I am opening this issue based on the following DNS bug sleuthing:</p>
<p><a href="https://gitlab.com/gitlab-org/charts/gitlab/-/issues/3303" class="external">https://gitlab.com/gitlab-org/charts/gitlab/-/issues/3303</a></p>
<p>As described by Stan Hu, seems like the Ruby's Resolv library does not handle correctly the <code>NODATA</code> case because if any of the searchpaths return the <code>NODATA</code> response the search stops there and the domain is not correctly resolved, as the correct resolution should be using the input address as FQDN.</p>
<p>Ruby looks at the DNS response code (<a href="https://github.com/ruby/ruby/blob/9c0df2e81c22e6e35f3c5d69a070c2a3cf67e320/lib/resolv.rb#L532-L552" class="external">https://github.com/ruby/ruby/blob/9c0df2e81c22e6e35f3c5d69a070c2a3cf67e320/lib/resolv.rb#L532-L552</a>), which is described in <a href="https://datatracker.ietf.org/doc/html/rfc2929#section-2.3" class="external">https://datatracker.ietf.org/doc/html/rfc2929#section-2.3</a>.</p>
<p>We are assuming that, as described in the issue, the .aws search path caused the DNS to return "No error" and DNS Resolver interprets it as valid.</p>
<p>Busybox's nslookup implementation mentions the NODATA case here: <a href="https://git.busybox.net/busybox/tree/networking/nslookup.c?h=1_35_stable#n650" class="external">https://git.busybox.net/busybox/tree/networking/nslookup.c?h=1_35_stable#n650</a>. <a href="https://datatracker.ietf.org/doc/html/rfc2308#section-2.2.1" class="external">https://datatracker.ietf.org/doc/html/rfc2308#section-2.2.1</a> and may describe the problem with Ruby's Resolv implementation:</p>
<pre><code>There are a large number of resolvers currently in existence that
fail to correctly detect and process all forms of NODATA response.
Some resolvers treat a TYPE 1 NODATA response as a referral. To
alleviate this problem it is recommended that servers that are
authoritative for the NODATA response only send TYPE 2 NODATA
responses, that is the authority section contains a SOA record and no
NS records. Sending a TYPE 1 NODATA response from a non-
authoritative server to one of these resolvers will only result in an
unnecessary query. If a server is listed as a FORWARDER for another
resolver it may also be necessary to disable the sending of TYPE 1
NODATA response for non-authoritative NODATA responses.
Some name servers fail to set the RCODE to NXDOMAIN in the presence
of CNAMEs in the answer section. If a definitive NXDOMAIN / NODATA
answer is required in this case the resolver must query again using
the QNAME as the query label.
</code></pre>
<p>As it sounded like a Ruby bug report I decided to open this issue in order to correctly to handle the NODATA case.</p>
<p>The link for the sleuthing of the problem part: <a href="https://gitlab.com/gitlab-org/charts/gitlab/-/issues/3303#note_950108922" class="external">https://gitlab.com/gitlab-org/charts/gitlab/-/issues/3303#note_950108922</a> and the specific problem can be found on the start of the comment when we could not resolve the DNS unless we removed the aws searchpath as this serachpath specifically was returning the <code>NODATA</code> response.</p> Ruby master - Bug #18804 (Open): Invalid line number for putnil instructionhttps://bugs.ruby-lang.org/issues/188042022-05-25T09:22:32Zhurricup (Alexandr Evstigneev)hurricup@gmail.com
<p>Looks like this is a pretty old bug. Consider example:</p>
<pre><code>def foo1
if true
nil
else
1
end
end
def foo2
if true
42
else
1
end
end
foo1_method = method(:foo1)
puts RubyVM::InstructionSequence.of(foo1_method).disasm
foo2_method = method(:foo2)
puts RubyVM::InstructionSequence.of(foo2_method).disasm
</code></pre>
<p>Gives us:</p>
<pre><code>== disasm: #<ISeq:foo1@/home/hurricup/RubymineProjects/untitled28/test.rb:1 (1,0)-(7,3)> (catch: FALSE)
0000 putnil ( 2)[LiCa]
0001 leave ( 7)[Re]
== disasm: #<ISeq:foo2@/home/hurricup/RubymineProjects/untitled28/test.rb:9 (9,0)-(15,3)> (catch: FALSE)
0000 putobject 42 ( 11)[LiCa]
0002 leave ( 15)[Re]
</code></pre>
<p><code>putnil</code> has line set to 2 (and it should be 3)<br>
<code>putobject 42</code> has line set to 11 and this is correct one.</p>
<p>User unable to put a breakpoint to the nil in debugger because of this.</p> Ruby master - Bug #18794 (Open): Windows - intermittent SEGV TestObjSpace#test_reachable_objects_...https://bugs.ruby-lang.org/issues/187942022-05-20T17:19:08ZMSP-Greg (Greg L)
<p>Test runs in retry, generates the following (removed path from x64-ucrt-ruby320.dll). mswin build runs it as a single test, I don't believe it's failed.</p>
<pre><code> 1) Failure:
TestObjSpace#test_reachable_objects_during_iteration Line: 145
assert_separately failed with error message
pid 70572 exit 3
| -:8: [BUG] Unnormalized Fixnum value 0x0000023f8eeb2119
| ruby 3.2.0dev (2022-05-20T15:42:07Z master 11336c7ddb) [x64-mingw-ucrt]
|
| -- Control frame information -----------------------------------------------
| c:0006 p:---- s:0021 e:000020 CFUNC :to_s
| c:0005 p:---- s:0018 e:000017 CFUNC :inspect
| c:0004 p:0004 s:0014 e:000013 BLOCK -:8 [FINISH]
| c:0003 p:---- s:0010 e:000009 CFUNC :each_object
| c:0002 p:0073 s:0006 e:000005 EVAL -:7 [FINISH]
| c:0001 p:0000 s:0003 E:002060 (none) [FINISH]
|
| -- Ruby level backtrace information ----------------------------------------
| -:7:in `<main>'
| -:7:in `each_object'
| -:8:in `block in <main>'
| -:8:in `inspect'
| -:8:in `to_s'
|
| -- C level backtrace information -------------------------------------------
| C:\Windows\SYSTEM32\ntdll.dll(NtWaitForSingleObject+0x14) [0x00007ffbdb40ef74]
| C:\Windows\System32\KERNELBASE.dll(WaitForSingleObjectEx+0x8e) [0x00007ffbd89fe7ae]
| x64-ucrt-ruby320.dll(rb_vm_bugreport+0x313) [0x00007ffba62417c3]
| x64-ucrt-ruby320.dll(rb_bug_without_die+0x75) [0x00007ffba6039d15]
| x64-ucrt-ruby320.dll(rb_bug+0x33) [0x00007ffba626e014]
| x64-ucrt-ruby320.dll(rb_out_of_int+0x42) [0x00007ffba626f81b]
| x64-ucrt-ruby320.dll(rb_vm_invoke_proc+0x22c) [0x00007ffba622c34c]
| x64-ucrt-ruby320.dll(rb_eval_cmd_kw+0x5ea) [0x00007ffba6230e7a]
| x64-ucrt-ruby320.dll(rb_funcallv+0x11) [0x00007ffba62310c1]
| x64-ucrt-ruby320.dll(rb_inspect+0x17) [0x00007ffba60f9417]
| x64-ucrt-ruby320.dll(rb_hash_values+0xfc1) [0x00007ffba606e791]
| x64-ucrt-ruby320.dll(rb_hash_values+0x102c) [0x00007ffba606e7fc]
| x64-ucrt-ruby320.dll(rb_st_foreach_check+0x77) [0x00007ffba61a1637]
| x64-ucrt-ruby320.dll(rb_hash_set_default_proc+0x1e19) [0x00007ffba60724a9]
| x64-ucrt-ruby320.dll(rb_ensure+0x18f) [0x00007ffba60453af]
| x64-ucrt-ruby320.dll(rb_hash_set_default_proc+0x2272) [0x00007ffba6072902]
| x64-ucrt-ruby320.dll(rb_hash_aset+0x1d1f) [0x00007ffba6077c2f]
| x64-ucrt-ruby320.dll(rb_mutex_trylock+0x51c) [0x00007ffba61d864c]
| x64-ucrt-ruby320.dll(rb_exec_recursive+0x17) [0x00007ffba61e0217]
| x64-ucrt-ruby320.dll(rb_error_arity+0x26e) [0x00007ffba62182ee]
| x64-ucrt-ruby320.dll(rb_vm_call_with_refinements+0x47d) [0x00007ffba6233fed]
| x64-ucrt-ruby320.dll(rb_vm_exec+0x255) [0x00007ffba62252a5]
| x64-ucrt-ruby320.dll(rb_yield+0x1e8) [0x00007ffba622ac88]
| x64-ucrt-ruby320.dll(rb_obj_id+0x1c94) [0x00007ffba6057024]
| x64-ucrt-ruby320.dll(rb_size_mul_or_raise+0x154) [0x00007ffba605c464]
| x64-ucrt-ruby320.dll(rb_ensure+0x18f) [0x00007ffba60453af]
| x64-ucrt-ruby320.dll(rb_objspace_each_objects_without_setup+0x1ac) [0x00007ffba606562c]
| x64-ucrt-ruby320.dll(rb_error_arity+0x26e) [0x00007ffba62182ee]
| x64-ucrt-ruby320.dll(rb_vm_search_method_slowpath+0x723) [0x00007ffba621ce33]
| x64-ucrt-ruby320.dll(rb_vm_call_with_refinements+0x4e8) [0x00007ffba6234058]
| x64-ucrt-ruby320.dll(rb_vm_exec+0x255) [0x00007ffba62252a5]
| x64-ucrt-ruby320.dll(rb_call_end_proc+0x130) [0x00007ffba603e400]
| x64-ucrt-ruby320.dll(ruby_run_node+0xa5) [0x00007ffba6044145]
| [0x00007ff62fcc15a8]
| [0x00007ff62fcc13b1]
| [0x00007ff62fcc14e6]
| C:\Windows\System32\KERNEL32.DLL(BaseThreadInitThunk+0x10) [0x00007ffbd93c4ed0]
</code></pre> Ruby master - Bug #18733 (Open): Ruby GC problems cause performance issue with Ractorhttps://bugs.ruby-lang.org/issues/187332022-04-15T05:04:10Zjakit (Jakit Liang)
<p>Code:</p>
<pre><code>require 'benchmark'
def fib(n)
return n if [0,1].include?(n)
fib(n-1) + fib(n-2)
end
tp = []
puts Benchmark.measure {
8.times do
tp << fork { fib(37) }
end
tp.each { |t| Process.wait(t) }
}
puts Benchmark.measure {
8.times.map {
Ractor.new { fib(37) }
}.each{ |r| r.take }
}
</code></pre>
<p>Result:</p>
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
</tr>
</thead>
<tbody>
<tr>
<td>fork</td>
<td>0.000264 0.003439 87.181198 ( 11.211349)</td>
</tr>
<tr>
<td>Ractor</td>
<td>80.292916 15.062559 95.355475 ( 39.569527)</td>
</tr>
</tbody>
</table>
<p>And I found that here's the problem showing on the ActiveMonitor.app:</p>
<p><img src="http://jakit.cn/screen_shot_ruby_bug.jpg" alt="ruby_bug_with_m1"></p>
<p>As you can see, the process of ruby is always using all Performance Cores on my Apple M1 Mac.</p>
<p>But there's no one of the Efficiency Cores was in used by ruby Ractor.</p> Ruby master - Bug #18661 (Open): Net::HTTP behavior changed between 2.6 and 3.1 on windows.https://bugs.ruby-lang.org/issues/186612022-03-25T13:57:07Zjleblanc (Joshua LeBlanc)
<p>We are upgrading a rails application from Ruby 2.6 to Ruby 3.1 on Windows.</p>
<p>Running rails systems tests hang on Ruby 3.1, while they succeed on Ruby 2.6.</p>
<p>I tracked this down to Ruby 3.1's Net::HTTP using Socket.tcp rather than the old TCPSocket.</p>
<p>Specifically, in <code>socket.rb</code>, <code>connect_internal</code> calls <code>connect_nonblock(self, exception: false)</code>, which ultimately hangs until timing out on windows.<br>
Modifying the <code>socket.rb</code> source to use <code>connect(self)</code> instead results in a successful operation.</p>
<p>To be clear, the hanging operation is <code>socket.rb#connect_nonblock</code>, which is on line 1214</p>
<p>Reproduction:</p>
<ol>
<li>Install Ruby 3.1 on Windows - I used RubyInstaller: <a href="https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-3.1.1-1/rubyinstaller-devkit-3.1.1-1-x64.exe" class="external">https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-3.1.1-1/rubyinstaller-devkit-3.1.1-1-x64.exe</a>
</li>
<li>Clone the reproduction project: <a href="https://github.com/joshleblanc/windows_net_http_problem" class="external">https://github.com/joshleblanc/windows_net_http_problem</a>
</li>
<li>Run <code>bundle install</code>
</li>
<li>Run <code>rails test:system</code>
</li>
</ol>
<p>Chrome will open, however a connection will never be made, ultimately timing out.</p>
<p>To test this same process in earlier versions of ruby, simply create a new rails project with <code>rails new -O -J -S <name></code>, add the <code>ffi</code> and <code>tzinfo-data</code> gems to the gemfile, and scaffold a new resource. Running <code>rails test:system</code> from this point should succeed.</p> Ruby master - Bug #18622 (Open): const_get still looks in Object, while lexical constant lookup n...https://bugs.ruby-lang.org/issues/186222022-03-10T16:12:55ZEregon (Benoit Daloze)
<p>There is some inconsistency here between literal constant lookup and the meta API (const_get).</p>
<p>Lexical constant lookup no longer uses a special case for Object, and this is good as it avoids surprises: <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: remove top-level constant lookup (Closed)" href="https://bugs.ruby-lang.org/issues/11547">#11547</a></p>
<p>However, <code>const_get</code> still looks in Object, even though that's confusing, inconsistent and IMHO shouldn't really happen.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">ConstantSpecsTwo</span>
<span class="no">Foo</span> <span class="o">=</span> <span class="ss">:cs_two_foo</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">ConstantSpecs</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="no">ConstantSpecs</span><span class="p">.</span><span class="nf">const_get</span><span class="p">(</span><span class="s2">"ConstantSpecsTwo::Foo"</span><span class="p">)</span> <span class="c1"># => :cs_two_foo</span>
<span class="nb">p</span> <span class="no">ConstantSpecs</span><span class="o">::</span><span class="no">ConstantSpecsTwo</span><span class="o">::</span><span class="no">Foo</span> <span class="c1"># => const_get.rb:9:in `<main>': uninitialized constant ConstantSpecs::ConstantSpecsTwo (NameError)</span>
</code></pre>
<p>I think we should change it so both behave the same (i.e., NameError).<br>
It's like if <code>cd /foo/bar</code> would go to <code>/bar</code> if <code>/foo/bar</code> does not exist and <code>/bar</code> does.</p>
<p><code>const_get</code> is a meta API so it cannot know the surrounding <code>Module.nesting</code>, but so I think it should consider the receiver of <code>const_get</code> as the only nesting (so just <code>ConstantSpecs</code> in this case, not <code>Object</code>).</p>
<p>Note this does not affect nested constants inside the <code>const_get</code> like <code>Foo</code> above (another way to look at the inconsistency that the first component is treated differently).</p>
<p>From <a href="https://bugs.ruby-lang.org/issues/11547#note-19" class="external">https://bugs.ruby-lang.org/issues/11547#note-19</a></p> Ruby master - Bug #18608 (Open): `require': cannot load such file -- ripper (LoadError) after `ma...https://bugs.ruby-lang.org/issues/186082022-03-03T19:51:39Zbrandonrdn (Brandon Riden)
<p>When compiling multiple instances of Ruby (In our case, two separate prefixes), using the following build code causes the 2nd installed Ruby to throw an error on any ruby/irb call.</p>
<p>Changing the code to delete the extracted <code>ruby-3.1.0</code> folder and re-extract from the tarball fixes this issue, so I believe it's something in the <code>make distclean</code> that's causing issues. This was not an issue for ruby 2.6.3 or 2.6.7, just on 3.0+ versions.</p>
<p>Build code:</p>
<pre><code># Build Ruby
RUN set -e ; \
. /etc/profile.d/ccache.sh ; \
wget -q https://cache.ruby-lang.org/pub/ruby/${RUBY_VERSION%.*}/ruby-${RUBY_VERSION}.tar.gz ; \
tar zxf ruby-${RUBY_VERSION}.tar.gz ; \
rm -f ruby-${RUBY_VERSION}.tar.gz ; \
pushd ruby-${RUBY_VERSION} ; \
type -p gcc ; \
for prefix in /usr/local /opt/vendored_ruby ; do \
./configure --prefix=$prefix --with-compress-debug-sections=no --disable-install-doc ; \
make ; \
make install ; \
make distclean ; \
done ; \
popd ; \
ccache --show-stats ; \
rm -rf ruby-${RUBY_VERSION} /root/.ccache
</code></pre>
<p>Error:</p>
<pre><code><internal:/opt/vendored_ruby/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require': cannot load such file -- ripper (LoadError)
from <internal:/opt/vendored_ruby/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from /opt/vendored_ruby/lib/ruby/3.1.0/irb.rb:12:in `<top (required)>'
from <internal:/opt/vendored_ruby/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from <internal:/opt/vendored_ruby/lib/ruby/3.1.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from /opt/vendored_ruby/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:9:in `<top (required)>'
from /opt/vendored_ruby/bin/irb:25:in `load'
from /opt/vendored_ruby/bin/irb:25:in `<main>'
[root@cc75157e1b69 /]# /usr/local/bin/irb
irb(main):001:0>
</code></pre>
<p>This error pops up on any reference to ruby or irb, including the base commands.</p>
<p>Steps to reproduce:</p>
<ul>
<li>Compile/make/make install Ruby 3.0+ with the 1st prefix</li>
<li>Run <code>make distclean</code>
</li>
<li>Compile/make/make install Ruby 3.0+ with the 2nd prefix</li>
<li>run the <code>irb</code> and <code>ruby</code> commands in both paths.</li>
</ul> Ruby master - Bug #18605 (Open): Fails to run on (newer) 32bit Windows with ucrthttps://bugs.ruby-lang.org/issues/186052022-03-03T07:31:55Zlazka (Christoph Reiter)
<p>32bit ruby using ucrt has started to fail on newer Windows with "unexpected ucrtbase.dll" -> <a href="https://github.com/ruby/ruby/blob/3fb7d2cadc18472ec107b14234933b017a33c14d/win32/win32.c#L2591" class="external">https://github.com/ruby/ruby/blob/3fb7d2cadc18472ec107b14234933b017a33c14d/win32/win32.c#L2591</a></p>
<p>The problem is that ruby depends on ucrt internals and those have apparently changed with newer versions.</p>
<p>See <a href="https://github.com/msys2/MINGW-packages/pull/10878" class="external">https://github.com/msys2/MINGW-packages/pull/10878</a> and <a href="https://github.com/msys2/MINGW-packages/issues/10896" class="external">https://github.com/msys2/MINGW-packages/issues/10896</a> for some background and a potential fix. But ideally ruby wouldn't depend on Windows internals like this.</p>
<p>thanks!</p> Ruby master - Bug #18510 (Open): Unexpected waiting for console when starting ruby on windowshttps://bugs.ruby-lang.org/issues/185102022-01-23T14:53:12ZYO4 (Yoshinao Muramatsu)
<a name="ruby-version"></a>
<h1 >ruby version<a href="#ruby-version" class="wiki-anchor">¶</a></h1>
<p>C:\Ruby31-x64\bin>"c:\Ruby31-x64\bin\ruby.exe" -v<br>
ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x64-mingw-ucrt]</p>
<p>older versions have same issue too.</p>
<a name="how-to-reproduce"></a>
<h1 >how to reproduce<a href="#how-to-reproduce" class="wiki-anchor">¶</a></h1>
<p>execute ruby.exe from cmd.exe command promput like concatenating the quoted path and file name notation</p>
<pre><code>C:\Ruby31-x64\bin>"c:\Ruby31-x64\bin\"ruby.exe -v
# => wait for console input unexpectedly
puts "This is Console Input"^Z
=> This is Console Input
# ruby terminated, version not appear
</code></pre>
<p>It seems to commandline separation issue.</p> Ruby master - Bug #18507 (Open): Incorrect target_os detection in configure scripthttps://bugs.ruby-lang.org/issues/185072022-01-21T15:19:23Zrcl (Andrew Kosteltsev)
<p>configure.ac incorrectly detect target_os by target triplet such as arm-unknown-linux-gnueabihf. In case arm-unknown-linux-gnueabihf suffix we have incorrect ruby arch = 'arm-linux-eabihf' instead of 'arm-linux'.</p>
<p>configure.ac: 246:<br>
target_os=<code>echo $target_os | sed 's/linux-gnu$/linux/;s/linux-gnu/linux-/'</code></p>
<p>should be changed to:<br>
target_os=<code>echo $target_os | sed 's/linux-gnu[[^ ]]*$/linux/;s/linux-gnu/linux-/'</code></p>
<p>and correspondently configure: 7619:<br>
target_os=<code>echo $target_os | sed 's/linux-gnu$/linux/;s/linux-gnu/linux-/'</code></p>
<p>should be changed to:<br>
target_os=<code>echo $target_os | sed 's/linux-gnu[^ ]*$/linux/;s/linux-gnu/linux-/'</code></p> Ruby master - Bug #18506 (Open): make and make install rebuild items every time unnecessarily - s...https://bugs.ruby-lang.org/issues/185062022-01-21T13:28:24Zalex.kanavin@gmail.com (Alexander Kanavin)
<p>The makefiles are written in a way that a few items are regenerated on every invocation of make, even if nothing changes, including, actually libruby.so. This would've been ok, but from ruby 3.1 onwards it started to cause races in parallel make installs, where items in capi/ext/ and libruby are re-linked at the same time, causing capi/ext ones to fail the linking step. This is how it looks like:</p>
<pre><code>| building spec/ruby/optional/capi/ext/integer_spec.so
| ../ruby-3.1.0/revision.h unchanged
| generating enc.mk
| building spec/ruby/optional/capi/ext/proc_spec.so
| compiling enc/encinit.c
| linking shared-library libruby.so.3.1.0
| ./libruby.so: file not recognized: file format not recognized
| collect2: error: ld returned 1 exit status
| ../ruby-3.1.0/defs/gmake.mk:413: recipe for target 'spec/ruby/optional/capi/ext/proc_spec.so' failed
| make: *** [spec/ruby/optional/capi/ext/proc_spec.so] Error 1
| make: *** Waiting for unfinished jobs....
| linking ruby
</code></pre>
<p><a href="https://autobuilder.yoctoproject.org/typhoon/api/v2/logs/4328780/raw" class="external">https://autobuilder.yoctoproject.org/typhoon/api/v2/logs/4328780/raw</a></p>
<p>To reproduce, configure with --enable-shared, and run 'make' several times.</p> Ruby master - Bug #18492 (Open): `rb_rescue2` inside `rb_protect` segfaults on Windowshttps://bugs.ruby-lang.org/issues/184922022-01-14T15:17:58Zbyroot (Jean Boussier)byroot@ruby-lang.org
<p>I ran into and interpreter segfault that <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/42491">@peterzhu2118 (Peter Zhu)</a> helped me reduce to s simple test case:</p>
<pre><code class="c syntaxhl" data-language="c"><span class="cp">#include</span> <span class="cpf"><ruby.h></span><span class="cp">
</span>
<span class="k">static</span> <span class="n">VALUE</span>
<span class="nf">rescue_return_false</span><span class="p">(</span><span class="n">VALUE</span> <span class="n">arg</span><span class="p">,</span> <span class="n">VALUE</span> <span class="n">e</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="n">Qfalse</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">static</span> <span class="n">VALUE</span>
<span class="nf">try_callback</span><span class="p">(</span><span class="n">VALUE</span> <span class="n">arg</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">rb_raise</span><span class="p">(</span><span class="n">rb_eStandardError</span><span class="p">,</span> <span class="s">"Repro"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">static</span> <span class="n">VALUE</span>
<span class="nf">prot_callback</span><span class="p">(</span><span class="n">VALUE</span> <span class="n">arg</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="n">rb_rescue2</span><span class="p">(</span>
<span class="n">try_callback</span><span class="p">,</span> <span class="n">arg</span><span class="p">,</span>
<span class="n">rescue_return_false</span><span class="p">,</span> <span class="n">Qnil</span><span class="p">,</span>
<span class="n">rb_eRuntimeError</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">VALUE</span> <span class="nf">repro_call</span><span class="p">(</span><span class="n">VALUE</span> <span class="n">self</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">state</span><span class="p">;</span>
<span class="n">rb_protect</span><span class="p">(</span><span class="n">prot_callback</span><span class="p">,</span> <span class="n">Qnil</span><span class="p">,</span> <span class="o">&</span><span class="n">state</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">state</span><span class="p">)</span> <span class="p">{</span>
<span class="n">rb_jump_tag</span><span class="p">(</span><span class="n">state</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">Qtrue</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span>
<span class="nf">Init_repro</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">VALUE</span> <span class="n">m_Repro</span> <span class="o">=</span> <span class="n">rb_define_module_under</span><span class="p">(</span><span class="n">rb_cObject</span><span class="p">,</span> <span class="s">"Repro"</span><span class="p">);</span>
<span class="n">rb_define_singleton_method</span><span class="p">(</span><span class="n">m_Repro</span><span class="p">,</span> <span class="s">"call"</span><span class="p">,</span> <span class="n">repro_call</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s2">"test_helper"</span>
<span class="k">class</span> <span class="nc">ReproTest</span> <span class="o"><</span> <span class="no">Minitest</span><span class="o">::</span><span class="no">Test</span>
<span class="k">def</span> <span class="nf">test_raises</span>
<span class="n">assert_raises</span> <span class="k">do</span>
<span class="no">Repro</span><span class="p">.</span><span class="nf">call</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<a name="Expected-behavior"></a>
<h3 >Expected behavior<a href="#Expected-behavior" class="wiki-anchor">¶</a></h3>
<p>I expect <code>Repro.call</code> to reraise the <code>StandardError</code>.</p>
<a name="Actual-behavior"></a>
<h3 >Actual behavior<a href="#Actual-behavior" class="wiki-anchor">¶</a></h3>
<p>It works as expected on Ubuntu and MacOS, but segfaults on Windows:</p>
<pre><code>D:/a/rbprotect-repro/rbprotect-repro/test/repro_test.rb:8: [BUG] Segmentation fault
ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x64-mingw-ucrt]
-- Control frame information -----------------------------------------------
c:0026 p:---- s:0138 e:000137 CFUNC :call
c:0025 p:0011 s:0134 e:000133 BLOCK D:/a/rbprotect-repro/rbprotect-repro/test/repro_test.rb:8
c:0024 p:0064 s:0131 e:000130 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/assertions.rb:402
c:0023 p:0004 s:0124 e:000123 METHOD D:/a/rbprotect-repro/rbprotect-repro/test/repro_test.rb:7
c:0022 p:0018 s:0120 e:000119 BLOCK C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:98
c:0021 p:0002 s:0117 e:000116 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:195
c:0020 p:0004 s:0112 e:000111 BLOCK C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:95
c:0019 p:0015 s:0109 e:000108 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:281
c:0018 p:0004 s:0104 e:000103 BLOCK C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:94
c:0017 p:0029 s:0101 e:000100 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:376
c:0016 p:0044 s:0093 E:000a98 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:221
c:0015 p:0004 s:0086 E:0022c0 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:93
c:0014 p:0008 s:0082 e:000081 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:1042
c:0013 p:0026 s:0075 e:000073 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:350
c:0012 p:0009 s:0067 e:000066 BLOCK C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:337 [FINISH]
c:0011 p:---- s:0063 e:000062 CFUNC :each
c:0010 p:0005 s:0059 e:000058 BLOCK C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:336
c:0009 p:0029 s:0056 e:000055 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:376
c:0008 p:0029 s:0048 E:000a58 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:363
c:0007 p:0117 s:0041 E:0025e8 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:335
c:0006 p:0008 s:0032 e:000031 BLOCK C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:169 [FINISH]
c:0005 p:---- s:0028 e:000027 CFUNC :map
c:0004 p:0035 s:0024 e:000023 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:169
c:0003 p:0142 s:0015 e:000014 METHOD C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:146
c:0002 p:0073 s:0008 E:0015a0 BLOCK C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:73 [FINISH]
c:0001 p:0000 s:0003 E:0009a0 (none) [FINISH]
-- Ruby level backtrace information ----------------------------------------
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:73:in `block in autorun'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:146:in `run'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:169:in `__run'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:169:in `map'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:169:in `block in __run'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:335:in `run'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:363:in `with_info_handler'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:376:in `on_signal'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:336:in `block in run'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:336:in `each'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:337:in `block (2 levels) in run'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:350:in `run_one_method'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:1042:in `run_one_method'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:93:in `run'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:221:in `with_info_handler'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:376:in `on_signal'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:94:in `block in run'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest.rb:281:in `time_it'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:95:in `block (2 levels) in run'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:195:in `capture_exceptions'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/test.rb:98:in `block (3 levels) in run'
D:/a/rbprotect-repro/rbprotect-repro/test/repro_test.rb:7:in `test_raises'
C:/hostedtoolcache/windows/Ruby/3.1.0/x64/lib/ruby/gems/3.1.0/gems/minitest-5.15.0/lib/minitest/assertions.rb:402:in `assert_raises'
D:/a/rbprotect-repro/rbprotect-repro/test/repro_test.rb:8:in `block in test_raises'
D:/a/rbprotect-repro/rbprotect-repro/test/repro_test.rb:8:in `call'
-- C level backtrace information -------------------------------------------
C:\Windows\SYSTEM32\ntdll.dll(NtWaitForSingleObject+0x14) [0x00007ffa0905fa74]
C:\Windows\System32\KERNELBASE.dll(WaitForSingleObjectEx+0x93) [0x00007ffa059485c3]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vm_bugreport+0x2b3) [0x00007ff9d488b633]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_bug_for_fatal_signal+0x88) [0x00007ff9d4683d88]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_fiber_scheduler_address_resolve+0x2be) [0x00007ff9d47dc02e]
[0x00007ff6c4731f32]
C:\Windows\System32\ucrtbase.dll(_C_specific_handler+0xa0) [0x00007ffa05c1e210]
C:\Windows\SYSTEM32\ntdll.dll(_chkstk+0x11f) [0x00007ffa09064a2f]
C:\Windows\SYSTEM32\ntdll.dll(RtlWalkFrameChain+0x14bf) [0x00007ffa08fc4cef]
C:\Windows\SYSTEM32\ntdll.dll(KiUserExceptionDispatcher+0x2e) [0x00007ffa0906379e]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_obj_is_kind_of+0x77) [0x00007ff9d473f697]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vrescue2+0x32b) [0x00007ff9d468eb0b]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_rescue2+0x2a) [0x00007ff9d468ebaa]
[0x00007ff9d3fd1447]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_protect+0x155) [0x00007ff9d468ed45]
[0x00007ff9d3fd13dc]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_error_arity+0x26e) [0x00007ff9d486280e]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vm_call_with_refinements+0x45d) [0x00007ff9d487e1ad]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vm_exec+0x142) [0x00007ff9d486f052]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_yield+0x1e8) [0x00007ff9d4874be8]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_ary_each+0x3d) [0x00007ff9d45e62cd]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_error_arity+0x26e) [0x00007ff9d486280e]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vm_search_method_slowpath+0x692) [0x00007ff9d4866e72]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vm_call_with_refinements+0x4bf) [0x00007ff9d487e20f]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vm_exec+0x142) [0x00007ff9d486f052]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_yield+0x1e8) [0x00007ff9d4874be8]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_ary_sort_bang+0xda2) [0x00007ff9d45ee402]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_error_arity+0x26e) [0x00007ff9d486280e]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vm_search_method_slowpath+0x692) [0x00007ff9d4866e72]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vm_call_with_refinements+0x4bf) [0x00007ff9d487e20f]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vm_exec+0x142) [0x00007ff9d486f052]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_vm_invoke_proc+0x78) [0x00007ff9d4876178]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_proc_call+0x94) [0x00007ff9d477b484]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_ec_error_print+0xaf8) [0x00007ff9d468cbd8]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_ec_error_print+0xdcb) [0x00007ff9d468ceab]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(rb_ec_error_print+0x10a2) [0x00007ff9d468d182]
C:\hostedtoolcache\windows\Ruby\3.1.0\x64\bin\x64-ucrt-ruby310.dll(ruby_run_node+0xaf) [0x00007ff9d468ddbf]
[0x00007ff6c4732ab9]
[0x00007ff6c47313b1]
[0x00007ff6c47314e6]
C:\Windows\System32\KERNEL32.DLL(BaseThreadInitThunk+0x14) [0x00007ffa08b57974]
</code></pre>
<a name="Full-repro"></a>
<h3 >Full repro<a href="#Full-repro" class="wiki-anchor">¶</a></h3>
<p>The full repro source code can be found at <a href="https://github.com/casperisfine/rbprotect-repro" class="external">https://github.com/casperisfine/rbprotect-repro</a></p>
<p>The CI is configured to run on Windows, Ubuntu and MacOS, from Ruby 2.5 to ruby-head</p> Ruby master - Bug #18476 (Open): Call to require stuck forever after receiving EAGAIN on writev w...https://bugs.ruby-lang.org/issues/184762022-01-11T18:30:15ZJelteF (Jelte Fennema)
<a name="Environment"></a>
<h1 >Environment<a href="#Environment" class="wiki-anchor">¶</a></h1>
<p>I'm using Ubuntu 18.04 running on Windows using WSL2:</p>
<pre><code>$ uname -a
Linux myhostname 5.10.60.1-microsoft-standard-WSL2 #1 SMP Wed Aug 25 23:20:18 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.6 LTS
Release: 18.04
Codename: bionic
</code></pre>
<a name="Problem-description"></a>
<h1 >Problem description<a href="#Problem-description" class="wiki-anchor">¶</a></h1>
<p>When using <code>zeus</code> to run a ruby project in an effort to cache dependency loading it gets stuck when calling <code>require 'rubocop'</code> on Ruby 3.0 and 3.1. Everything works fine on Ruby 2.6.</p>
<p>When looking at strace output of the stuck process it shows a <code>writev</code> call that receives an <code>EAGAIN</code> right before the process gets to its stuck state:</p>
<pre><code>[pid 24872] writev(14, [{iov_base="/home/jelte/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rubocop-1.23.0/lib/rubocop/cop/lint/number_conversion.rb", iov_len=115}, {iov_base="\n", iov_len=1}], 2) = 116
[pid 24872] writev(14, [{iov_base="/home/jelte/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rubocop-1.23.0/lib/rubocop/cop/lint/numbered_parameter_assignment.rb", iov_len=127}, {iov_base="\n", iov_len=1}], 2) = 128
[pid 24872] writev(14, [{iov_base="/home/jelte/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rubocop-1.23.0/lib/rubocop/cop/lint/or_assignment_to_constant.rb", iov_len=123}, {iov_base="\n", iov_len=1}], 2) = 124
[pid 24872] writev(14, [{iov_base="/home/jelte/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rubocop-1.23.0/lib/rubocop/cop/lint/ordered_magic_comments.rb", iov_len=120}, {iov_base="\n", iov_len=1}], 2) = 121
[pid 24872] writev(14, [{iov_base="/home/jelte/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rubocop-1.23.0/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb", iov_len=121}, {iov_base="\n", iov_len=1}], 2) = 122
[pid 24872] writev(14, [{iov_base="/home/jelte/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rubocop-1.23.0/lib/rubocop/cop/lint/parentheses_as_grouped_expression"..., iov_len=131}, {iov_base="\n", iov_len=1}], 2) = 132
[pid 24872] writev(14, [{iov_base="/home/jelte/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rubocop-1.23.0/lib/rubocop/cop/lint/percent_string_array.rb", iov_len=118}, {iov_base="\n", iov_len=1}], 2) = 119
[pid 24872] writev(14, [{iov_base="/home/jelte/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rubocop-1.23.0/lib/rubocop/cop/lint/percent_symbol_array.rb", iov_len=118}, {iov_base="\n", iov_len=1}], 2) = 119
[pid 24872] writev(14, [{iov_base="/home/jelte/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/rubocop-1.23.0/lib/rubocop/cop/lint/raise_exception.rb", iov_len=113}, {iov_base="\n", iov_len=1}], 2) = -1 EAGAIN (Resource temporarily unavailable)
[pid 24872] getpid() = 24872
[pid 24872] ppoll([{fd=14, events=POLLOUT}, {fd=7, events=POLLIN}], 2, NULL, NULL, 8 <unfinished ...>
[pid 24859] <... futex resumed> ) = -1 ETIMEDOUT (Connection timed out)
[pid 24859] select(0, NULL, NULL, NULL, {tv_sec=0, tv_usec=20}) = 0 (Timeout)
[pid 24859] futex(0x605f38, FUTEX_WAIT, 0, {tv_sec=60, tv_nsec=0}
</code></pre>
<p>The exact file at which the process receives the EAGAIN and is stuck is consistent across runs with the same Ruby version (at least on my machine). For 3.1.0 it's <code>raise_exception.rb</code> and for 3.0.3 it's <code>redundant_dir_glob_sort.rb</code></p>
<p>For reference this is the link to the repo of <code>zeus</code>: <a href="https://github.com/burke/zeus" class="external">https://github.com/burke/zeus</a></p>
<a name="How-to-reproduce"></a>
<h1 >How to reproduce<a href="#How-to-reproduce" class="wiki-anchor">¶</a></h1>
<p>See this example repo for minimal steps on how to reproduce this: <a href="https://github.com/JelteF/ruby-zeus-bug" class="external">https://github.com/JelteF/ruby-zeus-bug</a></p>
<a name="Expectation"></a>
<h1 >Expectation<a href="#Expectation" class="wiki-anchor">¶</a></h1>
<p>For Ruby to not get stuck after receiving <code>EAGAIN</code> on the <code>writev</code> call.</p> Ruby master - Bug #18473 (Open): Raw data in Socket::Option#inspect on Amazon Linux 2 https://bugs.ruby-lang.org/issues/184732022-01-11T14:13:29Zdriv3r (Leszek Zalewski)
<p>Hello,</p>
<p>I found a weird issue when running attached script. Locally on Ubuntu running kernel 5.11, on CI (GitHub Actions) and through docker image (ruby:3.1.0-alpine3.15), the response is as it should be with all data parsed correctly:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1">#<Socket::Option: INET TCP INFO state=LISTEN ca_state=Open retransmits=0 probes=0 backoff=0 options=0 rto=0.000000s ato=0.000000s snd_mss=0 rcv_mss=0 unacked=0 sacked=1024 lost=0 retrans=0 fackets=0 last_data_sent=0.000s last_ack_sent=0.000s last_data_recv=0.000s last_ack_recv=0.000s pmtu=0 rcv_ssthresh=0 rtt=0.000000s rttvar=0.000000s snd_ssthresh=0 snd_cwnd=10 advmss=0 reordering=3 rcv_rtt=0.000000s rcv_space=0 total_retrans=0 (128 bytes too long)></span>
</code></pre>
<p>The issue happens when running exactly the same docker image on AWS Fargate, where instead of expected output above, we get</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"#<Socket::Option: INET TCP INFO </span><span class="se">\"\\</span><span class="s2">n</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x80</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">n</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x03</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">xFF</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\\</span><span class="s2">x00</span><span class="se">\"</span><span class="s2">>"</span>
</code></pre>
<p>After further testing even simple EC2 with Amazon Linux 2 @4.14 kernel gives same output, 5.10 works fine.</p>
<p>Steps to reproduce:</p>
<ul>
<li>boot up EC2 instance with Amazon Linux v2 @ kernel 4.14 (no idea how to run it locally, I might assist if needed)</li>
<li>install docker
<pre><code class="bash syntaxhl" data-language="bash"><span class="nb">sudo </span>yum <span class="nb">install </span>docker
<span class="nb">sudo </span>systemctl start docker.service
<span class="nb">sudo </span>docker run <span class="nt">-it</span> ruby:3.1.0-alpine3.15
</code></pre>
</li>
<li>execute the attached script</li>
</ul> Ruby master - Bug #18455 (Open): `IO#close` has poor performance and difficult to understand sema...https://bugs.ruby-lang.org/issues/184552022-01-01T07:13:08Zioquatix (Samuel Williams)samuel@oriontransfer.net
<p><code>IO#close</code> should be responsible for closing the file descriptor referred to by the IO instance. When dealing with buffered IO, one can also expect this to flush the internal buffers if possible.</p>
<p>Currently, all blocking IO operations release the GVL and perform the blocking system call using <code>rb_thread_io_blocking_region</code>. The current implementation takes a file descriptor and adds an entry to the VM global <code>waiting_fds</code> list. When the operation is completed, the entry is removed from <code>waiting_fds</code>.</p>
<p>When calling <code>IO#close</code>, this list is traversed and any threads performing blocking operations with a matching file descriptor are interrupted. The performance of this is O(number of blocking IO operations) which in practice the performance of <code>IO#close</code> can take milliseconds with 10,000 threads performing blocking IO. This performance is unacceptable.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1">#!/usr/bin/env ruby</span>
<span class="nb">require</span> <span class="s1">'benchmark'</span>
<span class="k">class</span> <span class="nc">Reading</span>
<span class="k">def</span> <span class="nf">initialize</span>
<span class="vi">@r</span><span class="p">,</span> <span class="vi">@w</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">pipe</span>
<span class="vi">@thread</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="vi">@r</span><span class="p">.</span><span class="nf">read</span>
<span class="k">rescue</span> <span class="no">IOError</span>
<span class="c1"># Ignore.</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="kp">attr</span> <span class="ss">:r</span>
<span class="kp">attr</span> <span class="ss">:w</span>
<span class="kp">attr</span> <span class="ss">:thread</span>
<span class="k">def</span> <span class="nf">join</span>
<span class="vi">@thread</span><span class="p">.</span><span class="nf">join</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">measure</span><span class="p">(</span><span class="n">count</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
<span class="n">readings</span> <span class="o">=</span> <span class="n">count</span><span class="p">.</span><span class="nf">times</span><span class="p">.</span><span class="nf">map</span> <span class="k">do</span>
<span class="no">Reading</span><span class="p">.</span><span class="nf">new</span>
<span class="k">end</span>
<span class="nb">sleep</span> <span class="mi">10</span>
<span class="n">duration</span> <span class="o">=</span> <span class="no">Benchmark</span><span class="p">.</span><span class="nf">measure</span> <span class="k">do</span>
<span class="n">readings</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">reading</span><span class="o">|</span>
<span class="n">reading</span><span class="p">.</span><span class="nf">r</span><span class="p">.</span><span class="nf">close</span>
<span class="n">reading</span><span class="p">.</span><span class="nf">w</span><span class="p">.</span><span class="nf">close</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">average</span> <span class="o">=</span> <span class="p">(</span><span class="n">duration</span><span class="p">.</span><span class="nf">total</span> <span class="o">/</span> <span class="n">count</span><span class="p">)</span> <span class="o">*</span> <span class="mf">1000.0</span>
<span class="n">pp</span> <span class="ss">count: </span><span class="n">count</span><span class="p">,</span> <span class="ss">average: </span><span class="nb">sprintf</span><span class="p">(</span><span class="s2">"%0.2fms"</span><span class="p">,</span> <span class="n">average</span><span class="p">)</span>
<span class="n">readings</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">measure</span><span class="p">(</span> <span class="mi">10</span><span class="p">)</span>
<span class="n">measure</span><span class="p">(</span> <span class="mi">100</span><span class="p">)</span>
<span class="n">measure</span><span class="p">(</span> <span class="mi">1000</span><span class="p">)</span>
<span class="n">measure</span><span class="p">(</span><span class="mi">10000</span><span class="p">)</span>
</code></pre>
<p>In addition, the semantics of this operation are confusing at best. While Ruby programs are dealing with IO instances, the VM is dealing with file descriptors, in effect performing some internal de-duplication of IO state. In practice, this leads to strange behaviour:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1">#!/usr/bin/env ruby</span>
<span class="n">r</span><span class="p">,</span> <span class="n">w</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">pipe</span>
<span class="n">r2</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">for_fd</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="nf">to_i</span><span class="p">)</span>
<span class="n">pp</span> <span class="ss">r: </span><span class="n">r</span><span class="p">,</span> <span class="ss">r2: </span><span class="n">r2</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="n">r2</span><span class="p">.</span><span class="nf">read</span> <span class="k">rescue</span> <span class="kp">nil</span>
<span class="n">r2</span><span class="p">.</span><span class="nf">read</span> <span class="c1"># EBADF</span>
<span class="k">end</span>
<span class="nb">sleep</span> <span class="mf">0.5</span>
<span class="n">r</span><span class="p">.</span><span class="nf">close</span>
<span class="n">t</span><span class="p">.</span><span class="nf">join</span> <span class="k">rescue</span> <span class="kp">nil</span>
<span class="n">pp</span> <span class="ss">r: </span><span class="n">r</span><span class="p">,</span> <span class="ss">r2: </span><span class="n">r2</span>
<span class="c1"># r is closed, r2 is valid but will raise EBADF on any operation.</span>
</code></pre>
<p>In addition, this confusing behaviour extends to Ractor and state is leaked between the two:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">r</span><span class="p">,</span> <span class="n">w</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">pipe</span>
<span class="n">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">r</span><span class="p">.</span><span class="nf">to_i</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">fd</span><span class="o">|</span>
<span class="n">r2</span> <span class="o">=</span> <span class="no">IO</span><span class="p">.</span><span class="nf">for_fd</span><span class="p">(</span><span class="n">fd</span><span class="p">)</span>
<span class="n">r2</span><span class="p">.</span><span class="nf">read</span>
<span class="c1"># r2.read # EBADF</span>
<span class="k">end</span>
<span class="nb">sleep</span> <span class="mf">0.5</span>
<span class="n">r</span><span class="p">.</span><span class="nf">close</span>
<span class="n">pp</span> <span class="ss">take: </span><span class="n">ractor</span><span class="p">.</span><span class="nf">take</span>
</code></pre>
<p>I propose the following changes to simplify the semantics and improve performance:</p>
<ul>
<li>Move the semantics of <code>waiting_fds</code> from per-fd to per-IO. This means that <code>IO#close</code> only interrupts blocking operations performed on the same IO instance rather than ANY IO which refers to the same file descriptor. I think this behaviour is easier to understand and still protects against the vast majority of incorrect usage.</li>
<li>Move the details of <code>struct rb_io_t</code> to <code>internal/io.h</code> so that the implementation details are not part of the public interface.</li>
</ul>
<a name="Benchmarks"></a>
<h2 >Benchmarks<a href="#Benchmarks" class="wiki-anchor">¶</a></h2>
<p>Before:</p>
<pre><code>{:count=>10, :average=>"0.19ms"}
{:count=>100, :average=>"0.11ms"}
{:count=>1000, :average=>"0.18ms"}
{:count=>10000, :average=>"1.16ms"}
</code></pre>
<p>After:</p>
<pre><code>{:count=>10, :average=>"0.20ms"}
{:count=>100, :average=>"0.11ms"}
{:count=>1000, :average=>"0.15ms"}
{:count=>10000, :average=>"0.68ms"}
</code></pre>
<p>After investigating this further I found that the <code>rb_thread_io_blocking_region</code> using <code>ubf_select</code> can be incredibly slow, proportional to the number of threads. I don't know whether it's advisable but:</p>
<pre><code class="c syntaxhl" data-language="c"> <span class="n">BLOCKING_REGION</span><span class="p">(</span><span class="n">blocking_node</span><span class="p">.</span><span class="kr">thread</span><span class="p">,</span> <span class="p">{</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="n">data1</span><span class="p">);</span>
<span class="n">saved_errno</span> <span class="o">=</span> <span class="n">errno</span><span class="p">;</span>
<span class="p">},</span> <span class="nb">NULL</span> <span class="cm">/* ubf_select */</span><span class="p">,</span> <span class="n">blocking_node</span><span class="p">.</span><span class="kr">thread</span><span class="p">,</span> <span class="n">FALSE</span><span class="p">);</span>
</code></pre>
<p>Disabling the UBF function and relying on <code>read(fd, ...)</code>/<code>write(fd, ...)</code> blocking operations to fail when <code>close(fd)</code> is invoked might be sufficient? This needs more investigation but after making this change, we have constant-time IO#close.</p>
<pre><code>{:count=>10, :average=>"0.13ms"}
{:count=>100, :average=>"0.06ms"}
{:count=>1000, :average=>"0.04ms"}
{:count=>10000, :average=>"0.09ms"}
</code></pre>
<p>Which is ideally what we want.</p> Ruby master - Bug #18444 (Open): Trapped TSTP causes a locking deadlock in 3.0.3 onwardhttps://bugs.ruby-lang.org/issues/184442021-12-28T16:01:45Zwhy-el (Mohamed Wael Khobalatte)
<p>A curious case:</p>
<p><code>ruby -e 'Signal.trap("TSTP") { puts "Received a terminal stop signal, but i will sleep instead."; sleep 10 }; loop {puts 1}'</code></p>
<p>this fails with <code>deadlock; recursive locking (ThreadError)</code> when I send the SIGTSTP via my terminal. This is on Mac OS Monterey (M1). It only happens in 3.0.3 and onward (I tried 3.1.0-preview1 as well, fails there too), when I try 3.0.2, the signal is handled properly.</p> Ruby master - Bug #18412 (Open): Segfault in test_ractor.rbhttps://bugs.ruby-lang.org/issues/184122021-12-16T09:18:39Zvo.x (Vit Ondruch)v.ondruch@tiscali.cz
<p>During build of Ruby 3.0.3 for Fedora, I sometimes bump into this issue:</p>
<pre><code>... snip ...
test_attr.rb ..
test_autoload.rb ........
test_block.rb ..........................................................
test_class.rb ................................................
test_env.rb ..
test_eval.rb .....................................
test_exception.rb ..................................
test_fiber.rb .....
test_finalizer.rb .
test_flip.rb .
test_flow.rb ..............................................................
test_fork.rb ....
test_gc.rb ..
test_insns.rb ...............................................................................................................................................................................................................................................................................................................................................................................................
test_io.rb .........
test_jump.rb .............................
test_literal.rb ............................................................................................................................................................
test_literal_suffix.rb ................................................
test_load.rb ..
test_marshal.rb .
test_massign.rb ..................................
test_method.rb ...............................................................................................................................................................................................................................
test_objectspace.rb ......
test_proc.rb .....................................
test_ractor.rb .........................................................................................Fstderr output is not empty
<internal:ractor>:627: [BUG] Segmentation fault at 0x0000000000000038
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [powerpc64le-linux]
-- Control frame information -----------------------------------------------
c:0005 p:0003 s:0020 e:000019 METHOD <internal:ractor>:627
c:0004 p:0032 s:0013 e:000012 BLOCK bootstraptest.tmp.rb:6 [FINISH]
c:0003 p:---- s:0010 e:000009 CFUNC :loop
c:0002 p:0005 s:0006 e:000005 BLOCK bootstraptest.tmp.rb:4 [FINISH]
c:0001 p:---- s:0003 e:000002 (none) [FINISH]
-- Ruby level backtrace information ----------------------------------------
bootstraptest.tmp.rb:4:in `block (2 levels) in <main>'
bootstraptest.tmp.rb:4:in `loop'
bootstraptest.tmp.rb:6:in `block (3 levels) in <main>'
<internal:ractor>:627:in `yield'
-- C level backtrace information -------------------------------------------
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(rb_print_backtrace+0x24) [0x7fffb1dd3604] vm_dump.c:758
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(rb_vm_bugreport.constprop.0+0x5c0) [0x7fffb1df1780] vm_dump.c:998
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(rb_bug_for_fatal_signal+0xa4) [0x7fffb1bbdc74] error.c:786
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(sigsegv+0x68) [0x7fffb1d2a4a8] signal.c:963
[0x7fffb1f80464]
[0x7fffb191ad68]
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(rb_native_mutex_lock+0x18) [0x7fffb1d6f558] thread_pthread.c:397
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(ractor_select+0x480) [0x7fffb1cda060] ractor.c:61
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(builtin_inline_class_627.lto_priv.0+0x50) [0x7fffb1cdaa30] ractor.c:1286
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(builtin_invoker0.lto_priv.0+0x24) [0x7fffb1db5624] vm_insnhelper.c:5445
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(vm_exec_core.lto_priv.0+0x254c) [0x7fffb1dbfe6c] insns.def:1493
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(rb_vm_exec+0x130) [0x7fffb1ddc7e0] vm.c:2172
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(loop_i+0x2e4) [0x7fffb1dc7bd4] vm.c:1263
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(rb_vrescue2+0xec) [0x7fffb1bbc6cc] eval.c:1019
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(rb_rescue2+0x3c) [0x7fffb1bbc8bc] eval.c:996
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(rb_f_loop.lto_priv.0+0x58) [0x7fffb1dc87c8] vm_eval.c:1483
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(ractor_safe_call_cfunc_0.lto_priv.0+0x24) [0x7fffb1da7904] vm_insnhelper.c:2748
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(vm_call_cfunc_with_frame+0x150) [0x7fffb1db2650] vm_insnhelper.c:2931
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(vm_sendish.lto_priv.0+0x3dc) [0x7fffb1db7b0c] vm_insnhelper.c:4532
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(vm_exec_core.lto_priv.0+0x1890) [0x7fffb1dbf1b0] insns.def:770
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(rb_vm_exec+0x130) [0x7fffb1ddc7e0] vm.c:2172
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(vm_invoke_proc.lto_priv.0+0x2c0) [0x7fffb1dcfc90] vm.c:1263
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(thread_do_start_proc.lto_priv.0+0x5ac) [0x7fffb1d7852c] vm.c:1499
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(thread_start_func_2.constprop.0.isra.0+0x958) [0x7fffb1dfacf8] thread.c:759
/builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3(thread_start_func_1+0x180) [0x7fffb1d70070] thread_pthread.c:994
[0x7fffb1916264]
[0x7fffb19c5f30]
-- Other runtime information -----------------------------------------------
* Loaded script: bootstraptest.tmp.rb
* Loaded features:
0 enumerator.so
1 thread.rb
2 rational.so
3 complex.so
4 ruby2_keywords.rb
5 /builddir/build/BUILD/ruby-3.0.3/.ext/powerpc64le-linux/enc/encdb.so
6 /builddir/build/BUILD/ruby-3.0.3/.ext/powerpc64le-linux/enc/trans/transdb.so
7 /builddir/build/BUILD/ruby-3.0.3/abrt.rb
* Process memory map:
102330000-102340000 r--p 00000000 fc:06 1076662947 /builddir/build/BUILD/ruby-3.0.3/ruby
102340000-102350000 r-xp 00010000 fc:06 1076662947 /builddir/build/BUILD/ruby-3.0.3/ruby
102350000-102360000 r--p 00020000 fc:06 1076662947 /builddir/build/BUILD/ruby-3.0.3/ruby
102360000-102370000 r--p 00020000 fc:06 1076662947 /builddir/build/BUILD/ruby-3.0.3/ruby
102370000-102380000 rw-p 00030000 fc:06 1076662947 /builddir/build/BUILD/ruby-3.0.3/ruby
134320000-134530000 rw-p 00000000 00:00 0 [heap]
7fff88000000-7fff88bd0000 rw-p 00000000 00:00 0
7fff88bd0000-7fff8c000000 ---p 00000000 00:00 0
7fff8c000000-7fff8cd90000 rw-p 00000000 00:00 0
7fff8cd90000-7fff90000000 ---p 00000000 00:00 0
7fff90000000-7fff901e0000 rw-p 00000000 00:00 0
7fff901e0000-7fff94000000 ---p 00000000 00:00 0
7fff94000000-7fff94be0000 rw-p 00000000 00:00 0
7fff94be0000-7fff98000000 ---p 00000000 00:00 0
7fff98000000-7fff99320000 rw-p 00000000 00:00 0
7fff99320000-7fff9c000000 ---p 00000000 00:00 0
7fff9c000000-7fff9cc40000 rw-p 00000000 00:00 0
7fff9cc40000-7fffa0000000 ---p 00000000 00:00 0
7fffa0000000-7fffa0d60000 rw-p 00000000 00:00 0
7fffa0d60000-7fffa4000000 ---p 00000000 00:00 0
7fffa7ed0000-7fffa7ee0000 ---p 00000000 00:00 0
7fffa7ee0000-7fffa8000000 rw-p 00000000 00:00 0
7fffa8000000-7fffa91a0000 rw-p 00000000 00:00 0
7fffa91a0000-7fffac000000 ---p 00000000 00:00 0
7fffada60000-7fffadaa0000 r--s 00000000 fc:06 1076662947 /builddir/build/BUILD/ruby-3.0.3/ruby
7fffadaa0000-7fffadab0000 r--p 00000000 fc:06 1614754146 /usr/lib64/libgcc_s-11-20211203.so.1
7fffadab0000-7fffadac0000 r-xp 00010000 fc:06 1614754146 /usr/lib64/libgcc_s-11-20211203.so.1
7fffadac0000-7fffadad0000 r--p 00020000 fc:06 1614754146 /usr/lib64/libgcc_s-11-20211203.so.1
7fffadad0000-7fffadae0000 r--p 00020000 fc:06 1614754146 /usr/lib64/libgcc_s-11-20211203.so.1
7fffadae0000-7fffadaf0000 rw-p 00030000 fc:06 1614754146 /usr/lib64/libgcc_s-11-20211203.so.1
7fffadaf0000-7fffadb00000 ---p 00000000 00:00 0
7fffadb00000-7fffadc20000 rw-p 00000000 00:00 0
7fffadc20000-7fffadc30000 ---p 00000000 00:00 0
7fffadc30000-7fffadd50000 rw-p 00000000 00:00 0
7fffadd50000-7fffadd60000 ---p 00000000 00:00 0
7fffadd60000-7fffade80000 rw-p 00000000 00:00 0
7fffade80000-7fffade90000 ---p 00000000 00:00 0
7fffade90000-7fffadfb0000 rw-p 00000000 00:00 0
7fffadfb0000-7fffadfc0000 ---p 00000000 00:00 0
7fffadfc0000-7fffae0e0000 rw-p 00000000 00:00 0
7fffae0e0000-7fffae0f0000 ---p 00000000 00:00 0
7fffae0f0000-7fffae210000 rw-p 00000000 00:00 0
7fffae210000-7fffae220000 ---p 00000000 00:00 0
7fffae220000-7fffae340000 rw-p 00000000 00:00 0
7fffae340000-7fffae350000 r--p 00000000 fc:06 1616770133 /builddir/build/BUILD/ruby-3.0.3/.ext/powerpc64le-linux/enc/trans/transdb.so
7fffae350000-7fffae360000 r-xp 00010000 fc:06 1616770133 /builddir/build/BUILD/ruby-3.0.3/.ext/powerpc64le-linux/enc/trans/transdb.so
7fffae360000-7fffae370000 r--p 00020000 fc:06 1616770133 /builddir/build/BUILD/ruby-3.0.3/.ext/powerpc64le-linux/enc/trans/transdb.so
7fffae370000-7fffae380000 r--p 00020000 fc:06 1616770133 /builddir/build/BUILD/ruby-3.0.3/.ext/powerpc64le-linux/enc/trans/transdb.so
7fffae380000-7fffae390000 rw-p 00000000 00:00 0
7fffae390000-7fffae3a0000 r--p 00000000 fc:06 1076646137 /builddir/build/BUILD/ruby-3.0.3/.ext/powerpc64le-linux/enc/encdb.so
7fffae3a0000-7fffae3b0000 r-xp 00010000 fc:06 1076646137 /builddir/build/BUILD/ruby-3.0.3/.ext/powerpc64le-linux/enc/encdb.so
7fffae3b0000-7fffae3c0000 r--p 00020000 fc:06 1076646137 /builddir/build/BUILD/ruby-3.0.3/.ext/powerpc64le-linux/enc/encdb.so
7fffae3c0000-7fffae3d0000 r--p 00020000 fc:06 1076646137 /builddir/build/BUILD/ruby-3.0.3/.ext/powerpc64le-linux/enc/encdb.so
7fffae3d0000-7fffae3e0000 rw-p 00000000 00:00 0
7fffae3e0000-7fffae3f0000 ---p 00000000 00:00 0
7fffae3f0000-7fffae460000 rw-p 00000000 00:00 0
7fffae460000-7fffae470000 ---p 00000000 00:00 0
7fffae470000-7fffae4e0000 rw-p 00000000 00:00 0
7fffae4e0000-7fffae4f0000 ---p 00000000 00:00 0
7fffae4f0000-7fffae560000 rw-p 00000000 00:00 0
7fffae560000-7fffae570000 ---p 00000000 00:00 0
7fffae570000-7fffae5e0000 rw-p 00000000 00:00 0
7fffae5e0000-7fffae5f0000 ---p 00000000 00:00 0
7fffae5f0000-7fffae660000 rw-p 00000000 00:00 0
7fffae660000-7fffae670000 ---p 00000000 00:00 0
7fffae670000-7fffae6e0000 rw-p 00000000 00:00 0
7fffae6e0000-7fffae6f0000 ---p 00000000 00:00 0
7fffae6f0000-7fffae760000 rw-p 00000000 00:00 0
7fffae760000-7fffae770000 ---p 00000000 00:00 0
7fffae770000-7fffae7e0000 rw-p 00000000 00:00 0
7fffae7e0000-7fffae7f0000 ---p 00000000 00:00 0
7fffae7f0000-7fffae860000 rw-p 00000000 00:00 0
7fffae860000-7fffae870000 ---p 00000000 00:00 0
7fffae870000-7fffae8e0000 rw-p 00000000 00:00 0
7fffae8e0000-7fffae8f0000 ---p 00000000 00:00 0
7fffae8f0000-7fffae960000 rw-p 00000000 00:00 0
7fffae960000-7fffae970000 ---p 00000000 00:00 0
7fffae970000-7fffae9e0000 rw-p 00000000 00:00 0
7fffae9e0000-7fffae9f0000 ---p 00000000 00:00 0
7fffae9f0000-7fffaea60000 rw-p 00000000 00:00 0
7fffaea60000-7fffaea70000 ---p 00000000 00:00 0
7fffaea70000-7fffaeae0000 rw-p 00000000 00:00 0
7fffaeae0000-7fffaeaf0000 ---p 00000000 00:00 0
7fffaeaf0000-7fffaeb60000 rw-p 00000000 00:00 0
7fffaeb60000-7fffaeb70000 ---p 00000000 00:00 0
7fffaeb70000-7fffaebe0000 rw-p 00000000 00:00 0
7fffaebe0000-7fffaebf0000 ---p 00000000 00:00 0
7fffaebf0000-7fffaec60000 rw-p 00000000 00:00 0
7fffaec60000-7fffaec70000 ---p 00000000 00:00 0
7fffaec70000-7fffaece0000 rw-p 00000000 00:00 0
7fffaece0000-7fffaecf0000 ---p 00000000 00:00 0
7fffaecf0000-7fffaed60000 rw-p 00000000 00:00 0
7fffaed60000-7fffaed70000 ---p 00000000 00:00 0
7fffaed70000-7fffaede0000 rw-p 00000000 00:00 0
7fffaede0000-7fffaedf0000 ---p 00000000 00:00 0
7fffaedf0000-7fffaee60000 rw-p 00000000 00:00 0
7fffaee60000-7fffaee70000 ---p 00000000 00:00 0
7fffaee70000-7fffaeee0000 rw-p 00000000 00:00 0
7fffaeee0000-7fffaeef0000 ---p 00000000 00:00 0
7fffaeef0000-7fffaef60000 rw-p 00000000 00:00 0
7fffaef60000-7fffaef70000 ---p 00000000 00:00 0
7fffaef70000-7fffaefe0000 rw-p 00000000 00:00 0
7fffaefe0000-7fffaeff0000 ---p 00000000 00:00 0
7fffaeff0000-7fffaf060000 rw-p 00000000 00:00 0
7fffaf060000-7fffaf070000 ---p 00000000 00:00 0
7fffaf070000-7fffaf0e0000 rw-p 00000000 00:00 0
7fffaf0e0000-7fffaf0f0000 ---p 00000000 00:00 0
7fffaf0f0000-7fffaf160000 rw-p 00000000 00:00 0
7fffaf160000-7fffaf170000 ---p 00000000 00:00 0
7fffaf170000-7fffaf1e0000 rw-p 00000000 00:00 0
7fffaf1e0000-7fffaf1f0000 ---p 00000000 00:00 0
7fffaf1f0000-7fffaf260000 rw-p 00000000 00:00 0
7fffaf260000-7fffaf270000 ---p 00000000 00:00 0
7fffaf270000-7fffaf2e0000 rw-p 00000000 00:00 0
7fffaf2e0000-7fffaf2f0000 ---p 00000000 00:00 0
7fffaf2f0000-7fffaf360000 rw-p 00000000 00:00 0
7fffaf360000-7fffaf370000 ---p 00000000 00:00 0
7fffaf370000-7fffb1570000 rw-p 00000000 00:00 0
7fffb1570000-7fffb1590000 r--p 00000000 fc:06 1615030600 /usr/lib64/libm.so.6
7fffb1590000-7fffb1650000 r-xp 00020000 fc:06 1615030600 /usr/lib64/libm.so.6
7fffb1650000-7fffb16b0000 r--p 000e0000 fc:06 1615030600 /usr/lib64/libm.so.6
7fffb16b0000-7fffb16c0000 r--p 00130000 fc:06 1615030600 /usr/lib64/libm.so.6
7fffb16c0000-7fffb16d0000 rw-p 00140000 fc:06 1615030600 /usr/lib64/libm.so.6
7fffb16d0000-7fffb16e0000 r--p 00000000 fc:06 1615031006 /usr/lib64/libcrypt.so.2.0.0
7fffb16e0000-7fffb1700000 r-xp 00010000 fc:06 1615031006 /usr/lib64/libcrypt.so.2.0.0
7fffb1700000-7fffb1720000 r--p 00030000 fc:06 1615031006 /usr/lib64/libcrypt.so.2.0.0
7fffb1720000-7fffb1730000 r--p 00040000 fc:06 1615031006 /usr/lib64/libcrypt.so.2.0.0
7fffb1730000-7fffb1740000 rw-p 00000000 00:00 0
7fffb1740000-7fffb1750000 r--p 00000000 fc:06 1615031014 /usr/lib64/libgmp.so.10.4.1
7fffb1750000-7fffb17d0000 r-xp 00010000 fc:06 1615031014 /usr/lib64/libgmp.so.10.4.1
7fffb17d0000-7fffb17f0000 r--p 00090000 fc:06 1615031014 /usr/lib64/libgmp.so.10.4.1
7fffb17f0000-7fffb1800000 r--p 000a0000 fc:06 1615031014 /usr/lib64/libgmp.so.10.4.1
7fffb1800000-7fffb1810000 rw-p 000b0000 fc:06 1615031014 /usr/lib64/libgmp.so.10.4.1
7fffb1810000-7fffb1830000 r-xp 00000000 fc:06 1615030899 /usr/lib64/libz.so.1.2.11
7fffb1830000-7fffb1840000 r--p 00010000 fc:06 1615030899 /usr/lib64/libz.so.1.2.11
7fffb1840000-7fffb1850000 rw-p 00020000 fc:06 1615030899 /usr/lib64/libz.so.1.2.11
7fffb1850000-7fffb1890000 r--p 00000000 fc:06 1615030597 /usr/lib64/libc.so.6
7fffb1890000-7fffb1a40000 r-xp 00040000 fc:06 1615030597 /usr/lib64/libc.so.6
7fffb1a40000-7fffb1ab0000 r--p 001f0000 fc:06 1615030597 /usr/lib64/libc.so.6
7fffb1ab0000-7fffb1ac0000 r--p 00250000 fc:06 1615030597 /usr/lib64/libc.so.6
7fffb1ac0000-7fffb1ad0000 rw-p 00260000 fc:06 1615030597 /usr/lib64/libc.so.6
7fffb1ae0000-7fffb1b20000 r--p 00000000 fc:06 1077936030 /builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3
7fffb1b20000-7fffb1e10000 r-xp 00040000 fc:06 1077936030 /builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3
7fffb1e10000-7fffb1f20000 r--p 00330000 fc:06 1077936030 /builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3
7fffb1f20000-7fffb1f30000 ---p 00440000 fc:06 1077936030 /builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3
7fffb1f30000-7fffb1f40000 r--p 00440000 fc:06 1077936030 /builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3
7fffb1f40000-7fffb1f50000 rw-p 00450000 fc:06 1077936030 /builddir/build/BUILD/ruby-3.0.3/libruby.so.3.0.3
7fffb1f50000-7fffb1f60000 rw-p 00000000 00:00 0
7fffb1f60000-7fffb1f80000 r--p 00000000 00:00 0 [vvar]
7fffb1f80000-7fffb1f90000 r-xp 00000000 00:00 0 [vdso]
7fffb1f90000-7fffb1fa0000 r--p 00000000 fc:06 1615030592 /usr/lib64/ld64.so.2
7fffb1fa0000-7fffb1ff0000 r-xp 00010000 fc:06 1615030592 /usr/lib64/ld64.so.2
7fffb1ff0000-7fffb2000000 r--p 00060000 fc:06 1615030592 /usr/lib64/ld64.so.2
7fffb2000000-7fffb2010000 r--p 00060000 fc:06 1615030592 /usr/lib64/ld64.so.2
7fffb2010000-7fffb2020000 rw-p 00070000 fc:06 1615030592 /usr/lib64/ld64.so.2
7fffd3830000-7fffd4030000 rw-p 00000000 00:00 0 [stack]
test_string.rb .
test_struct.rb .
test_syntax.rb ............................................................................................................................................................
test_thread.rb .................................................
Fiber count: 10000 (skipping)
#1282 test_ractor.rb:1405:in `<top (required)>':
workers = (0...8).map do
Ractor.new do
loop do
10_000.times.map { Object.new }
Ractor.yield Time.now
end
end
end
1_000.times { idle_worker, tmp_reporter = Ractor.select(*workers) }
"ok"
#=> "" (expected "ok")
FAIL 1/1489 tests failed
make: *** [uncommon.mk:767: yes-btest-ruby] Error 1
... snip ...
</code></pre>
<p>It reminds me <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Segmentation fault when yielding values from Ractors during GC sweeping (Closed)" href="https://bugs.ruby-lang.org/issues/18117">#18117</a>, but that should be fixed, right?</p> Ruby master - Bug #18396 (Open): An unexpected "hash value omission" syntax error when without pa...https://bugs.ruby-lang.org/issues/183962021-12-08T03:25:13Zkoic (Koichi ITO)koic.ito@gmail.com
<a name="Summary"></a>
<h2 >Summary<a href="#Summary" class="wiki-anchor">¶</a></h2>
<p>I encountered an unexpected "hash value omission" syntax error when parentheses call expression follows:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="sx">% cat </span><span class="n">example</span><span class="p">.</span><span class="nf">rb</span>
<span class="n">foo</span> <span class="ss">key:
</span><span class="n">foo</span> <span class="n">arg</span>
</code></pre>
<pre><code class="console syntaxhl" data-language="console"><span class="go">% ruby -cv /tmp/b.rb
ruby 3.1.0dev (2021-12-07T23:18:11Z master 4a3e7984bf) [x86_64-darwin19]
example.rb:2: syntax error, unexpected local variable or method, expecting `do' or '{' or '('
foo arg
</span></code></pre>
<a name="Additional-Information"></a>
<h2 >Additional Information<a href="#Additional-Information" class="wiki-anchor">¶</a></h2>
<p>The following is a traditional usage.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># No errors.</span>
<span class="n">foo</span> <span class="ss">key: </span><span class="n">key</span>
<span class="n">foo</span> <span class="n">arg</span>
</code></pre>
<p>A syntax error is unexpectedly raised when hash value omission argument without parentheses is followed by a method call without parentheses.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># No errors is expected, but syntax error is raised.</span>
<span class="n">foo</span> <span class="ss">key:
</span><span class="n">foo</span> <span class="n">arg</span>
</code></pre>
<p>No error occurs if any of the calls have parentheses.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># No errors.</span>
<span class="n">foo</span><span class="p">(</span><span class="n">key</span><span class="p">:)</span>
<span class="n">foo</span> <span class="n">arg</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># Also no errors.</span>
<span class="n">foo</span> <span class="ss">key:
</span><span class="n">foo</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
</code></pre>
<p>No error occurs when calling alone.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># No errors.</span>
<span class="n">foo</span> <span class="ss">key:
</span></code></pre>
<p>I encountered this error while trying to apply hash value omission to RSpec code of a real-world application (proprietary) .<br>
But this is a new Ruby 3.1 syntax and may not be supported yet. Thank you.</p> Ruby master - Bug #18359 (Open): [Windows MinGW] warning Please include winsock2.h before windows.hhttps://bugs.ruby-lang.org/issues/183592021-11-23T17:05:03ZMSP-Greg (Greg L)
<p>Compile warning from <code>include/ruby/win32.h</code>? Appears with both MINGW64 & UCRT64 builds.</p>
<pre><code>In file included from D:/ruby-mingw/include/ruby-3.1.0/ruby/win32.h:41,
from D:/ruby-mingw/include/ruby-3.1.0/ruby/internal/dosish.h:38,
from D:/ruby-mingw/include/ruby-3.1.0/ruby/defines.h:78,
from D:/ruby-mingw/include/ruby-3.1.0/ruby/ruby.h:25,
from D:/ruby-mingw/include/ruby-3.1.0/ruby.h:38,
from ../../../../ext/nokogiri/nokogiri.h:68,
from ../../../../ext/nokogiri/gumbo.c:30:
C:/msys64/mingw64/x86_64-w64-mingw32/include/winsock2.h:15:2: warning: #warning Please include winsock2.h before windows.h [-Wcpp]
15 | #warning Please include winsock2.h before windows.h
| ^~~~~~~
</code></pre> 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 #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 #18132 (Open): TODO: fix ccan/list thread safetyhttps://bugs.ruby-lang.org/issues/181322021-08-25T07:19:47Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<p>This library does not consider multi-threading at all.<br>
Callers must consider it instead.<br>
AFAIK, VM list has a problem, and others may.</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 #18080 (Open): Syntax error on one-line pattern matchinghttps://bugs.ruby-lang.org/issues/180802021-08-17T05:54:42Zko1 (Koichi Sasada)
<p>One line pattern matching with a method return value with parameters which are not surrounded by parenthesis raises syntax error.<br>
I think it is not intentional, but nobu said it's hard to support because of parse.y limitation.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">p</span> <span class="k">do</span>
<span class="k">end</span> <span class="o">=></span> <span class="n">a</span>
<span class="nb">p</span> <span class="n">a</span> <span class="c1">#=> nil</span>
<span class="nb">p</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span>
<span class="k">end</span> <span class="o">=></span> <span class="n">a</span>
<span class="nb">p</span> <span class="n">a</span> <span class="c1">#=> 1</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="k">do</span>
<span class="k">end</span> <span class="o">=></span> <span class="n">a</span>
<span class="c1">#=> </span>
<span class="c1"># syntax error, unexpected =>, expecting end-of-input</span>
<span class="c1"># end => a</span>
<span class="c1"># ^~</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="k">do</span>
<span class="k">end</span> <span class="k">in</span> <span class="n">a</span>
<span class="c1">#=> </span>
<span class="c1"># syntax error, unexpected `in', expecting end-of-input</span>
<span class="c1"># end in a</span>
<span class="c1"># ^~</span>
</code></pre> Ruby master - Bug #18061 (Open): Execshield test: libruby.so.N.N.N: FAIL: property-note test bec...https://bugs.ruby-lang.org/issues/180612021-08-04T13:37:35Zjaruga (Jun Aruga)
<p>I found an issue in our company's internal test called "execshield" by a security tool annobin - annocheck command [1][2].</p>
<pre><code>Hardened: libruby.so.2.7.4: FAIL: property-note test because no .note.gnu.property section found
</code></pre>
<p>Here is the reproducer on the upstream latest master, commit is 5f2987d6c2ae9ace3178ac3e1bbb4ac7079101eb,</p>
<pre><code>$ autoconf
$ ./configure --enable-shared
$ make
$ ls libruby.so.3.1.0
libruby.so.3.1.0*
</code></pre>
<p>If you are using Red Hat based Linux distro, it's easy to install by the RPM package like this.</p>
<pre><code>$ sudo dnf -y install annobin-annocheck
</code></pre>
<pre><code>$ sudo yum -y install annobin-annocheck
</code></pre>
<p>Then</p>
<pre><code>$ annocheck libruby.so.3.1.0
</code></pre>
<p>If you are using other Linux distros such as Ubuntu, you can use it by a container I prepared.</p>
<p>Prepare the following <code>Dockerfile</code>.</p>
<pre><code>$ cat Dockerfile
FROM docker.io/fedora:34
RUN cat /etc/fedora-release
RUN dnf -y install annobin-annocheck
WORKDIR /work
</code></pre>
<p>Then build the container image with the <code>Dockerfile</code> and run the annocheck command for the <code>libruby.so.3.1.0</code> on your host environment. The <code>-v</code> is an option for bind mount between host and container environment.</p>
<pre><code>$ docker build --rm -t fedora-annocheck .
$ docker run --rm -t -v $(pwd):/work fedora-annocheck annocheck /work/libruby.so.3.1.0
annocheck: Version 9.79.
Hardened: libruby.so.3.1.0: FAIL: bind-now test because not linked with -Wl,-z,now
Hardened: libruby.so.3.1.0: FAIL: notes test because gaps were detected in the annobin coverage
Hardened: libruby.so.3.1.0: FAIL: cf-protection test because no .note.gnu.property section = no control flow information
Hardened: libruby.so.3.1.0: FAIL: property-note test because no .note.gnu.property section found
Hardened: Rerun annocheck with --verbose to see more information on the tests.
</code></pre>
<p>The message <code>Hardened: libruby.so.3.1.0: FAIL: property-note test because no .note.gnu.property section found</code> is what I found in our internal test. For other FAIL messages, maybe it can be fixed by changing how to build.</p>
<p>Asking a colleague, I was told that the <code>coroutine/*/Context.S</code> files such as <a href="https://github.com/ruby/ruby/blob/master/coroutine/x86/Context.S" class="external">coroutine/x86/Context.S</a> cause the failure. Do you have any idea how to fix this? Thanks.</p>
<ul>
<li>[1] <a href="https://sourceware.org/annobin/" class="external">https://sourceware.org/annobin/</a>
</li>
<li>[2] You can see <code>man annocheck</code> or <a href="https://www.mankier.com/1/annocheck" class="external">https://www.mankier.com/1/annocheck</a> .</li>
</ul> 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 #18009 (Open): Regexps \w and \W with /i option and /u option produce inconsist...https://bugs.ruby-lang.org/issues/180092021-06-28T09:09:37Zjirkamarsik (Jirka Marsik)
<p>This is a follow up to <a href="https://bugs.ruby-lang.org/issues/4044" class="external">issue 4044</a>. Its fix (<a href="https://github.com/k-takata/Onigmo/issues/4" class="external">https://github.com/k-takata/Onigmo/issues/4</a>) handled the cases that were reported in the original issue, but there are other cases, which were omitted and now produce inconsistent results.</p>
<p>If the <code>\w</code> character set is used inside a nested negated character class, it will not be picked up by the part of the character class analyzer that's responsible for limiting the case-folding of certain character sets (like <code>\w</code> and <code>\W</code>) across the ASCII boundary. We then end up with the situation where <code>/[^\w]/iu</code> and <code>/[[^\w]]/iu</code> match different sets of characters.</p>
<pre><code>irb(main):001:0> ("a".."z").to_a.join.scan(/\W/iu)
=> []
irb(main):002:0> ("a".."z").to_a.join.scan(/[^\w]/iu)
=> []
irb(main):003:0> ("a".."z").to_a.join.scan(/[[^\w]]/iu)
=> ["k", "s"]
</code></pre>
<p>This can also be demonstrated using the inverted matcher:</p>
<pre><code>irb(main):004:0> ("a".."z").to_a.join.scan(/\w/iu).length
=> 26
irb(main):005:0> ("a".."z").to_a.join.scan(/[^[^\w]]/iu).length
=> 24
</code></pre>
<p>A similar issue also arises when using character class intersection. The idea behind the pattern compiler's analysis is that characters are allowed to case-fold across the ASCII boundary only if they are included in the character class by some other means than just being included in <code>\w</code> (or in one of several other character sets which have special treatment). Therefore, in the below, <code>/[\w]/iu</code> will not match the Kelvin sign <code>\u212a</code>, because that would mean crossing the ASCII boundary from <code>k</code> to <code>\u212a</code>. However, <code>/[kx]/iu</code> will match the Kelvin sign, because the <code>k</code> was not contributed by <code>\w</code> and therefore is not subject to the ASCII boundary restriction (we have to use <code>/[kx]/iu</code> instead of <code>/[k]/iu</code> in our examples, or else the pattern analyzer would replace <code>[k]</code> with <code>k</code> and follow a different code path).</p>
<pre><code>irb(main):006:0> /[\w]/iu.match("\u212a")
=> nil
irb(main):007:0> /[kx]/iu.match("\u212a")
=> #<MatchData "K">
</code></pre>
<p>The problem then is when we perform an intersection of these two character sets. Since <code>[kx]</code> is a subset of <code>\w</code>, we would expect their intersection to behave the same as <code>[kx]</code>, but that is not the case.</p>
<pre><code>irb(main):008:0> /[\w&&kx]/i.match("\u212a")
=> nil
</code></pre>
<p>The underlying issue in these cases is the manner in which the <code>ascCc</code> character set is computed during the parsing of character classes. The <code>ascCc</code> character set should contain all characters of the character class except those which were contributed by <code>\w</code> and similar character sets. This is done in a way that these character sets are essentially ignored in the calculation of <code>ascCc</code>, which works well for set union and top-most negation (which is handled explicitly), but it doesn't handle nested set negation and set intersection.</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 #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 #17925 (Open): Pattern matching syntax using semicolon one-linehttps://bugs.ruby-lang.org/issues/179252021-05-29T15:26:37Zkoic (Koichi ITO)koic.ito@gmail.com
<a name="Summary"></a>
<h2 >Summary<a href="#Summary" class="wiki-anchor">¶</a></h2>
<p>There are the following differences between <code>case ... when</code> and<code> case ... in</code>. Is this an expected behavior?</p>
<pre><code class="console syntaxhl" data-language="console"><span class="go">% ruby -v
ruby 3.1.0dev (2021-05-28T16:34:27Z master e56ba6231f) [x86_64-darwin19]
</span><span class="gp">% ruby -ce 'case expression when 42;</span><span class="w"> </span>end<span class="s1">'
</span><span class="go">Syntax OK
</span><span class="gp">% ruby -ce 'case expression in 42;</span><span class="w"> </span>end<span class="s1">'
</span><span class="go">-e:1: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
-e:1: syntax error, unexpected `end', expecting `when'
</span><span class="gp">case expression in 42;</span><span class="w"> </span>end
</code></pre>
<p>So, I have two concerns.</p>
<ul>
<li>Since the pattern matching syntax is different from <code>case ... when</code>, can't user write semicolon one-line <code>case ... in</code> in the same semicolon one-line as <code>case ... when</code>?</li>
<li>Does <code>case expression in 42; end</code> display an experimental warning of one-line pattern matching. Right?</li>
</ul>
<p>This is reproduced in Ruby 3.1.0-dev and Ruby 3.0.1.</p>
<a name="Additional-Information"></a>
<h2 >Additional Information<a href="#Additional-Information" class="wiki-anchor">¶</a></h2>
<p>NOTE 1: I understand that only syntax that doesn't use <code>case</code> and <code>end</code> is experimental one-line pattern matching syntax.</p>
<pre><code>% ruby -ce 'expression in 42'
-e:1: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!
Syntax OK
</code></pre>
<p>NOTE 2: The syntax is OK if a semicolon is used between <code>expression</code> and <code>in</code>. But <code>case ... when</code> is a valid syntax to omit.</p>
<pre><code>% ruby -e ruby -ce 'case expression; in 42; end'
Syntax OK
</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 #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 #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 #16829 (Open): Exceptions raised from within an enumerated method lose part of ...https://bugs.ruby-lang.org/issues/168292020-05-04T21:15:14Zdoliveirakn (Kyle d'Oliveira)
<p>Consider the following code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Test</span>
<span class="kp">include</span> <span class="no">Enumerable</span>
<span class="k">def</span> <span class="nf">each</span><span class="p">(</span><span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">raise</span> <span class="s2">"Boom"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">execution_method_a</span>
<span class="no">Test</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">to_enum</span><span class="p">(</span><span class="ss">:each</span><span class="p">).</span><span class="nf">next</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">execution_method_b</span>
<span class="no">Test</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span>
<span class="c1"># Never gets run</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">begin</span>
<span class="n">execution_method_a</span>
<span class="k">rescue</span> <span class="no">RuntimeError</span> <span class="o">=></span> <span class="n">e</span>
<span class="nb">puts</span> <span class="s2">"Using to_enum and next"</span>
<span class="nb">puts</span> <span class="n">e</span><span class="p">.</span><span class="nf">message</span>
<span class="nb">puts</span> <span class="n">e</span><span class="p">.</span><span class="nf">backtrace</span>
<span class="k">end</span>
<span class="k">begin</span>
<span class="n">execution_method_b</span>
<span class="k">rescue</span> <span class="no">RuntimeError</span> <span class="o">=></span> <span class="n">e</span>
<span class="nb">puts</span> <span class="s2">"Calling a block directly"</span>
<span class="nb">puts</span> <span class="n">e</span><span class="p">.</span><span class="nf">message</span>
<span class="nb">puts</span> <span class="n">e</span><span class="p">.</span><span class="nf">backtrace</span>
<span class="k">end</span>
</code></pre>
<p>When this file (located at lib/script.rb) is run the result is:</p>
<pre><code>Using to_enum and next
Boom
lib/script.rb:5:in `each'
lib/script.rb:1:in `each'
Calling a block directly
Boom
lib/script.rb:5:in `each'
lib/script.rb:14:in `execution_method_b'
lib/script.rb:29:in `<main>'
</code></pre>
<p>This is a little unusual. Effectively, if we create an enumerator and use <code>next</code> to iterate through the results, the backtrace is modified to the point where the calling method(s) are entirely lose. Notice when the <code>each</code> method is used directly and an exception is thrown, we see <code>execution_method_b</code> present in the stacktrace, but if we use <code>next</code> we do not see <code>execution_method_a</code> present at all.</p>
<p>This means that if there is some code that uses the enumerator/next approach deep within a callstack, the exception that comes out does not have any crucial information of where the call originated from.</p> 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 #16145 (Open): regexp match error if mixing /i, character classes, and utf8https://bugs.ruby-lang.org/issues/161452019-09-05T19:40:03Zzenspider (Ryan Davis)
<p>(reported on behalf of <a href="mailto:mage@mage.gold" class="email">mage@mage.gold</a> -- there appears to be an error in registration or login):</p>
<p>See: ruby-talk @ X-Mail-Count: 440336</p>
<p>2.6.3 :049 > 'SHOP' =~ /[xo]/i<br>
=> 2<br>
2.6.3 :050 > 'CAFÉ' =~ /[é]/i<br>
=> 3<br>
2.6.3 :051 > 'CAFÉ' =~ /[xé]/i<br>
=> nil<br>
2.6.3 :052 > 'CAFÉ' =~ /[xÉ]/i<br>
=> 3</p>
<p>Expected result:<br>
2.6.3 :051 > 'CAFÉ' =~ /[xé]/i<br>
=> 3</p>
<p>I tested it on random regex online pages.</p>
<p>It does not match on <a href="https://regex101.com/" class="external">https://regex101.com/</a></p>
<p>It matches on:</p>
<p><a href="https://regexr.com/" class="external">https://regexr.com/</a><br>
<a href="https://www.regextester.com/" class="external">https://www.regextester.com/</a><br>
<a href="https://www.freeformatter.com/regex-tester.html" class="external">https://www.freeformatter.com/regex-tester.html</a></p>
<p>(Ignore case turned on).</p>
<p>The reason I suppose it’s more like a bug than a feature is the fact that /[é]/i matches 'CAFÉ'. If the //i didn’t work for UTF-8 characters then the /[é]/i wouldn’t match it either. For example, [é] does not match 'CAFÉ' on <a href="https://regex101.com/" class="external">https://regex101.com/</a></p>
<p>I could not find a page or a system that behaves the same way as Ruby does. For example, it matches in PostgreSQL 10 (under FreeBSD 12) too:</p>
<a name="select-CAFÉ-xé"></a>
<h1 >select 'CAFÉ'~ '[xé]';<a href="#select-CAFÉ-xé" class="wiki-anchor">¶</a></h1>
<a name="column"></a>
<h2 >?column?<a href="#column" class="wiki-anchor">¶</a></h2>
<p>f<br>
(1 row)</p>
<a name="select-CAFÉ-xé-2"></a>
<h1 >select 'CAFÉ' ~* '[xé]';<a href="#select-CAFÉ-xé-2" class="wiki-anchor">¶</a></h1>
<a name="column-2"></a>
<h2 >?column?<a href="#column-2" class="wiki-anchor">¶</a></h2>
<p>t<br>
(1 row)</p>
<p>Tested it in IRB on macOS and FreeBSD.</p>
<p>$ uname -a && ruby -v && locale<br>
Darwin xxx 18.7.0 Darwin Kernel Version 18.7.0: Thu Jun 20 18:42:21 PDT 2019; root:xnu-4903.270.47~4/RELEASE_X86_64 x86_64<br>
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]<br>
LANG="en_US.UTF-8"<br>
LC_COLLATE="en_US.UTF-8"<br>
LC_CTYPE="en_US.UTF-8"<br>
LC_MESSAGES="en_US.UTF-8"<br>
LC_MONETARY="en_US.UTF-8"<br>
LC_NUMERIC="en_US.UTF-8"<br>
LC_TIME="en_US.UTF-8"<br>
LC_ALL="en_US.UTF-8"</p>
<p>$ uname -a && ruby -v && locale<br>
FreeBSD xxx 12.0-RELEASE-p9 FreeBSD 12.0-RELEASE-p9 GENERIC amd64<br>
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-freebsd12.0]<br>
LANG=en_US.UTF-8<br>
LC_CTYPE="en_US.UTF-8"<br>
LC_COLLATE="en_US.UTF-8"<br>
LC_TIME="en_US.UTF-8"<br>
LC_NUMERIC="en_US.UTF-8"<br>
LC_MONETARY="en_US.UTF-8"<br>
LC_MESSAGES="en_US.UTF-8"<br>
LC_ALL=en_US.UTF-8</p>
<p>I installed Ruby with RVM.</p> 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 #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 #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 #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 #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 #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 #14582 (Open): Unable to use `method__entry` and `method_return` tracing probes...https://bugs.ruby-lang.org/issues/145822018-03-07T06:23:00Zguilhermereiscampos (Guilherme Reis Campos)guilhermekbsa@gmail.com
<p>Hi,</p>
<p>I am trying to use dtrace/systemtap probes and not being able to use it after the 2.5. The 2.4 version works fine. I was hoping this was fixed on 2.6-preview, but apparently not (just downloaded dev and tested).</p>
<p>I tried on OSX using dtrace and also on ubuntu (vagrant).</p>
<pre><code># test.rb
class Foo
def bar
100.times { "Bar" }
end
end
foo = Foo.new
foo.bar
# test.stp
probe process("/home/vagrant/.rbenv/versions/2.4.0/bin/ruby").mark("method__entry") # you will need to change this to your ruby path of your version.
{
printf("%s => %s.%s in %s:%d\n", thread_indent(1), kernel_string($arg1),kernel_string($arg2),kernel_string($arg3),$arg4);
}
probe process("/home/vagrant/.rbenv/versions/2.4.0/bin/ruby").mark("method__return")
{
printf("%s <= %s.%s in %s:%d\n", thread_indent(-1), kernel_string($arg1),kernel_string($arg2),kernel_string($arg3),$arg4);
}
</code></pre>
<p>dtrace was something similar to it.</p>
<p>I was expecting to see this output:</p>
<pre><code># lots of calls
# ....
# then:
4090 ruby(9667): <= Gem::Specification.unresolved_deps in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/rubygems/specification.rb:1298
4095 ruby(9667): => MonitorMixin.mon_exit in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/monitor.rb:197
4100 ruby(9667): => MonitorMixin.mon_check_owner in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/monitor.rb:247
4104 ruby(9667): <= MonitorMixin.mon_check_owner in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/monitor.rb:251
4109 ruby(9667): <= MonitorMixin.mon_exit in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/monitor.rb:204
4283 ruby(9667): <= Kernel.require in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55
4303 ruby(9667): <= Kernel.require in /home/vagrant/.rbenv/versions/2.4.0/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55
0 ruby(9667): => Foo.bar in test.rb:3
16 ruby(9667): <= Foo.bar in test.rb:5
</code></pre>
<p>(The output above is 2.4)</p>
<p>my ruby (all versions that I tested) was install with rb-env:</p>
<pre><code>RUBY_CONFIGURE_OPTS='--enable-dtrace --disable-install-doc' rbenv install 2.5.0
</code></pre>
<p>I am happy to provide details if required. I'd also be happy to fix it if I have guidance.</p>
<p>Thanks,</p> Ruby master - Bug #14480 (Open): miniruby crashing when compiled with -O2 or -O1 on aarch64https://bugs.ruby-lang.org/issues/144802018-02-16T08:54:55Zvo.x (Vit Ondruch)v.ondruch@tiscali.cz
<p>Recently, it is not possible to build Ruby 2.5.0 on aarch64 on Fedora Rawhide, because miniruby fails during build:</p>
<pre><code>... snip ...
./miniruby -I./lib -I. -I.ext/common -n \
-e 'BEGIN{version=ARGV.shift;mis=ARGV.dup}' \
-e 'END{abort "UNICODE version mismatch: #{mis}" unless mis.empty?}' \
-e '(mis.delete(ARGF.path); ARGF.close) if /ONIG_UNICODE_VERSION_STRING +"#{Regexp.quote(version)}"/o' \
10.0.0 ./enc/unicode/10.0.0/casefold.h ./enc/unicode/10.0.0/name2ctype.h
generating encdb.h
./miniruby -I./lib -I. -I.ext/common ./tool/generic_erb.rb -c -o encdb.h ./template/encdb.h.tmpl ./enc enc
generating prelude.c
./miniruby -I./lib -I. -I.ext/common ./tool/generic_erb.rb -I. -c -o prelude.c \
./template/prelude.c.tmpl ./prelude.rb ./gem_prelude.rb ./abrt_prelude.rb
*** stack smashing detected ***: <unknown> terminated
encdb.h updated
... snip ...
</code></pre>
<p>This might by Ruby or gcc issue. Not sure yet. However, there is already lengthy analysis available in Fedora's Bugzilla <a href="https://bugzilla.redhat.com/show_bug.cgi?id=1545239" class="external">1</a>. Would be anybody able to help to resolve this issue?</p> Ruby master - Bug #14364 (Open): Regexp last match variable in procshttps://bugs.ruby-lang.org/issues/143642018-01-16T17:23:09Zaardvark179 (Duncan MacGregor)
<p>While working on TruffleRuby's regexp variables implementation I found the following behaviour when comparing our behaviour with MRI 2.3.5 and 2.5.0.</p>
<p>Some core methods such as <code>String#scan</code> take an optional block argument, and if this is a literal block then each time it is yielded to the <code>$~</code> variable will have been set. However, if the block is a proc that was not defined in the caller's scope then <code>$~</code> does not appear to get set or is inaccessible.</p>
<p>The following test script demonstrates the problem.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">ScanChecker</span>
<span class="k">def</span> <span class="nf">block</span>
<span class="no">Proc</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="nb">puts</span> <span class="s2">"$~ is </span><span class="si">#{</span><span class="vg">$~</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s1">'Checking with literal block.'</span>
<span class="s1">'hello'</span><span class="p">.</span><span class="nf">scan</span><span class="p">(</span><span class="sr">/l/</span><span class="p">)</span> <span class="k">do</span>
<span class="nb">puts</span> <span class="s2">"$~ is </span><span class="si">#{</span><span class="vg">$~</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s1">'Checking with a Proc from same scope'</span>
<span class="n">my_proc</span> <span class="o">=</span> <span class="no">Proc</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="nb">puts</span> <span class="s2">"$~ is </span><span class="si">#{</span><span class="vg">$~</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="s1">'hello'</span><span class="p">.</span><span class="nf">scan</span><span class="p">(</span><span class="sr">/l/</span><span class="p">,</span> <span class="o">&</span><span class="n">my_proc</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s1">'Checking with a Proc.'</span>
<span class="n">checker</span> <span class="o">=</span> <span class="no">ScanChecker</span><span class="p">.</span><span class="nf">new</span>
<span class="s1">'hello'</span><span class="p">.</span><span class="nf">scan</span><span class="p">(</span><span class="sr">/l/</span><span class="p">,</span> <span class="o">&</span><span class="n">checker</span><span class="p">.</span><span class="nf">block</span><span class="p">)</span>
</code></pre>
<p>I would have expected the <code>$~</code> to be set in all cases, but I'm not sure if that is the intended behaviour.</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 #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 #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 #9760 (Open): mkmf does not allow for linking against custom libraries when a s...https://bugs.ruby-lang.org/issues/97602014-04-19T22:15:47Zzanegray (Andrew DeMaria)ademariad@gmail.com
<p>Hi,</p>
<p>Hopefully the title is not confusing, but the short story is that mkmf outputs a makefile that first searches the default lib path before searching any user provided lib paths. This is not an issue until one tries to link against an included library whose version is different than a preexisting system library.</p>
<p>The issue cropped up while trying to install the rugged gem (libgit2 wrapper) and a full dialog on the issue can be found on github <a href="https://github.com/libgit2/rugged/issues/351" class="external">https://github.com/libgit2/rugged/issues/351</a>.</p>
<p>I was able to fix the issue with the attached patch (<a href="https://github.com/muff1nman/ruby/commit/a0c8bc32cfc11e61c5b9703bff243934c6509210" class="external">https://github.com/muff1nman/ruby/commit/a0c8bc32cfc11e61c5b9703bff243934c6509210</a>)</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 #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>