Project

General

Profile

Actions

Bug #1848

closed

Net::SSH hangs

Added by shyouhei (Shyouhei Urabe) over 14 years ago. Updated almost 13 years ago.

Status:
Closed
Assignee:
-
Target version:
ruby -v:
1.8.7-p135 and later
[ruby-dev:38971]

Description

=begin
Revision r21165 以降、Net::SSHを使う場合(具体的にいうとCapistrano)で、スレッド切り替えがうまくいかないという報告を受けました

また聞きでもうしわけない

https://capistrano.lighthouseapp.com/projects/8716/tickets/79
このへんが関係しているかも。してないかも。

再現方法

["localhost","localhost"].map {|h| Thread.new{Net::SSH.start(h, "foo")}}.each {|t| t.join}

proposed patch against 1.8.7

--- eval.c (revision 24335)
+++ eval.c (working copy)
@@ -11228,7 +11228,7 @@
break;
}
if ((th->status == THREAD_RUNNABLE || th == th_found) && th->stk_ptr) {

  •       if (!next || next->priority < th->priority) {
    
  •       if (!next || next->priority <= th->priority) {
                   th_found->status = THREAD_RUNNABLE;
                   th_found->wait_for = 0;
    

=end

Actions #1

Updated by Tietew (Toru Iwase) over 14 years ago

=begin
Tietew です。

これ、同じ箇所で刺さって困っていたのですが、このパッチで解決しました。
ruby_1_8ブランチです。ruby_1_8_7ブランチは未確認。

$ cap deploy

  • executing `deploy'
  • executing ""
    servers: ["server1.
    ", "server2.*****"]
    (ここで刺さる)

On Fri, 31 Jul 2009 16:00:27 +0900
In article
[[ruby-dev:38971] [Bug #1848] Net::SSH hangs]
Shyouhei Urabe wrote:

Bug #1848: Net::SSH hangs
http://redmine.ruby-lang.org/issues/show/1848

起票者: Shyouhei Urabe
ステータス: Open, 優先度: Normal
カテゴリ: core, Target version: Ruby 1.8.7
ruby -v: 1.8.7-p135 and later

Revision r21165 以降、Net::SSHを使う場合(具体的にいうとCapistrano)で、スレッド切り替えがうまくいかないという報告を受けました

また聞きでもうしわけない

https://capistrano.lighthouseapp.com/projects/8716/tickets/79
このへんが関係しているかも。してないかも。

再現方法

["localhost","localhost"].map {|h| Thread.new{Net::SSH.start(h, "foo")}}.each {|t| t.join}

proposed patch against 1.8.7

--- eval.c (revision 24335)
+++ eval.c (working copy)
@@ -11228,7 +11228,7 @@
break;
}
if ((th->status == THREAD_RUNNABLE || th == th_found) && th->stk_ptr) {

  •       if (!next || next->priority < th->priority) {
    
  •       if (!next || next->priority <= th->priority) {
                   th_found->status = THREAD_RUNNABLE;
                   th_found->wait_for = 0;
    

http://redmine.ruby-lang.org

--
Tietew
Blog: http://www.tietew.jp/
PGP: 26CB 71BB B595 09C4 0153 81C4 773C 963A D51B 8CAA

=end

Actions #2

Updated by shyouhei (Shyouhei Urabe) over 14 years ago

=begin
パッチあててみましたがtest/test_timeout.rbがハングするようになりますね。
そこまでシンプルな話でもなさそう。
=end

Actions #3

Updated by akira (akira yamada) over 14 years ago

=begin
Shyouhei Urabe さんは書きました:

パッチあててみましたがtest/test_timeout.rbがハングするようになりますね。
そこまでシンプルな話でもなさそう。

よくわかってないまま試行錯誤を繰り返すのも
どうかとは思ったのですが、
たとえばこんな感じだとtest_timeout.rbは通るようです。

Index: eval.c

--- eval.c (revision 24384)
+++ eval.c (working copy)
@@ -11378,7 +11378,7 @@
break;
}
if ((th->status == THREAD_RUNNABLE || th == th_found) && th->stk_ptr) {

  •       if (!next || next->priority < th->priority) {
    
  •       if (!next || next->priority < th->priority || th == th_found && next->priority == th->priority) {
               if (th == th_found) {
                   th_found->status = THREAD_RUNNABLE;
                   th_found->wait_for = 0;
    

今回はtest/runner.rbを実行して、パッチあり・なしで違いがでないところまでは確認しました。

--
やまだ

=end

Actions #4

Updated by akira (akira yamada) over 14 years ago

=begin
Tanaka Akira さんは書きました:

Net::SSH の問題は手元では再現しないので、この問題の状況はよ
くわかりません。

以下で、おそらく同じと思われる現象が起きます。
手元では実行ごとに毎回発生していますが、
もしかすると何度か実行すると〜かもしれません。


th = []

2.times do
th << Thread.new do
open("/dev/zero") do |i|
loop do
r, = IO.select([i], [], [], 0)
if r
p i.read(1)
break
end
end
end
end
end

th.each {|t| t.join }

参考になるかどうかわかりませんがdebug printを入れてみました。
先頭が行番号です。

11249 /* Do the select if needed /
11250 fprintf(stderr,"%4d) need_select=%d\n",LINE,need_select); if (need_select) {
11251 /
Convert delay to a timeval */
...
11267 n = select(max+1, &readfds, &writefds, &exceptfds, delay_ptr);
11268 fprintf(stderr,"%4d) n=%d\n",LINE,n); if (n < 0) {
11269 int e = errno;
...
11361 th_found = th;
11362 fprintf(stderr,"%4d) th_found=%d\n",LINE,th); found = 1;
11363 break;
...
11369 th_found = th;
11370 fprintf(stderr,"%4d) th_found=%d\n",LINE,th); found = 1;
11371 break;
...
11386 }
11387 fprintf(stderr,"%4d) th=%d th_found=%d\n",LINE,th,th_found); if ((th->status == THREAD_RUNNABLE || th == th_found) && th->stk_ptr) {
11388 if (!next || next->priority < th->priority) {
11389 fprintf(stderr,"%4d) next=th\n",LINE); next = th;
11390 }

実行結果はこんな感じになります。
(使用したのはruby 1.8.8dev (2009-08-06 revision 24416) [i686-linux]です)

  1. need_select=1
  2. n=1
  3. th_found=142481000
  4. th=142326496 th_found=142481000
  5. next=th
  6. th=142481000 th_found=142481000
  7. need_select=1
  8. n=1
  9. th_found=142490464
  10. th=142481000 th_found=142490464
  11. next=th
  12. th=142326496 th_found=142490464
  13. th=142490464 th_found=142490464
  14. need_select=1
  15. n=1
  16. th_found=142481000
  17. th=142326496 th_found=142481000
  18. next=th
  19. th=142490464 th_found=142481000
  20. th=142481000 th_found=142481000
    ...

1.8.7-p35でも現象が発生します。1.8.7-p{72,134}と1.9.0-p0ではすぐに終了します。

やまだ

=end

Actions #5

Updated by akr (Akira Tanaka) over 14 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
Applied in changeset r24442.
=end

Actions #6

Updated by akira (akira yamada) over 14 years ago

=begin

On 2009/08/07, at 23:47, Tanaka Akira wrote:

以下で、おそらく同じと思われる現象が起きます。
手元では実行ごとに毎回発生していますが、
もしかすると何度か実行すると〜かもしれません。

すばらしい。再現しました。

直せたように思います。

ありがとうございます。
手元でも動作が確認できました。

--
やまだ

=end

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0