[#20392] [BigDecimal] proposal to change specification — "Tadashi Saito" <shiba@...2.accsnet.ne.jp>

斎藤と申します。

25 messages 2003/06/20
[#20407] Re: [BigDecimal] proposal to change specification — "Shigeo Kobayashi" <shigeo@...> 2003/06/22

小林です。

[#20447] [BigDecimal] renaming proposal — "Tadashi Saito" <shiba@...2.accsnet.ne.jp>

斎藤です。

47 messages 2003/06/24
[#20621] Re: [BigDecimal] renaming proposal — "Shigeo Kobayashi" <shigeo@...> 2003/07/11

小林@MAILチェック中です。

[#20628] Re: [BigDecimal] renaming proposal — "Shigeo Kobayashi" <shigeo@...> 2003/07/11

小林です。

[ruby-dev:20351] socket.writeでBUG

From: "so" <dan@...2.so-net.ne.jp>
Date: 2003-06-16 08:28:30 UTC
List: ruby-dev #20351
はじめまして、山本円と申します。

socketを使っているとBUGが起こることがあるようです。

ハッキリしないのですが、
socketすでに切断され、Bad file descriptorな状態
になっているときsocket.writeをしようとすると、
たまに例外でなくBUGが起こることがあるという感じです。
スレッドも絡んでいるような気がします。

BUGのメッセージは以下のとおりです。


testserver.rb:19: [BUG] Segmentation fault
ruby 1.8.0 (2003-06-14) [i686-linux]


rubyは1.6.8でも起こるようです。
OSはredhat7.3、同8、同9で確認しました。

僕では原因は特定できませんので、
再現スクリプトを添付します。
以下のプログラムだと、サーバー側のプログラムでBUGが起きます。
サーバーとクライアントは別PCのがいいようです。

■testserver.rb
 サーバー側プログラム(port 1100決め打ち)

使い方
ruby testserver.rb

■clientloop.rb
 testclient.rbを作っては殺し作っては殺すプログラム

使い方
clientloop.rb 192.168.1.1 1100

■testclient.rb
 clientloop.rbから使われるクライアント側プログラム socketをやたらに作る

Attachments (3)

testclient.rb (429 Bytes, text/x-ruby)
require 'socket'
require 'timeout'

if ARGV.size != 2
  p "ARGV.size != 2"
  exit
end

host = ARGV[0]
port = ARGV[1]

`echo '#{Process.pid}' > sb.pid`

1000000.times{
  (1 .. 110).each{|i|
    Thread.start{
      sock = nil

      sock = TCPSocket.open(host, port.to_i)
      (1 .. 50).each do
        sock.print("012345\n")
        timeout(time_out){
          line = sock.gets
        }
      end

      sock.close
    }
  }
}
clientloop.rb (228 Bytes, text/x-ruby)
if ARGV.size != 2
  p "ARGV.size != 2"
  exit
end

host = ARGV[0]
port = ARGV[1]


1000000.times{
  Thread.start{
    `ruby testclient.rb #{host} #{port}`
  }
  sleep(0.3)
  p  pid = `cat sb.pid`
  pid.chomp!
  `kill #{pid}`
}
testserver.rb (1.34 KB, text/x-ruby)
$DEBUG = true

require 'socket'

class SockWrapper
  @replyQueue
  @socket
  @recieveThread

  def initialize(host, port, socket)
    @socket = socket
    @replyQueue = []

    recieveThread()
  end


  def push(str)
    @socket.write(str + "\n")
  end

  def shift()
    return @replyQueue.shift
  end

  def close()
    @socket.close
  end

  def alive?
    return @socket.closed? == false
  end

  def recieveThread()
    @recieveThread = Thread.start{
      begin
        while str = @socket.gets 
          @replyQueue.push(str)
        end
      rescue Exception
      ensure
        close
      end
    }
  end
end


class TestServer
  def initialize
    makeServerConnect()
    while true
      threadLoop()
    end
  end
  
  def port
    1100
  end

  def makeServerConnect()
    @gs = TCPServer.open(port)

    addr = @gs.addr
    addr.shift
    printf("server is on %s\n", addr.join(":"))
  end
  :private

  def threadLoop()
    Thread.start(@gs.accept) do |socket|       # save to dynamic variable
#      print(socket, " is accepted\n")
      
      @conn = SockWrapper.new(nil, nil, socket)

      while @conn.alive?
        getStr = @conn.shift

        next unless getStr
        begin
          @conn.push("1234")
        rescue Exception
        end
      end

#      print(socket, " is gone\n")
    end
  end
end

if $0 == __FILE__
  TestServer.new
end

In This Thread

Prev Next