The following program creates a segfault or interpreter crash extremly
fast - but seemingly only on my computer:

  rpolzer@katsuragi ruby $ ruby putpixel.rb 1>/dev/null
  putpixel.rb:17: [BUG] Segmentation fault
  ruby 1.6.8 (2002-12-24) [i686-linux-gnu]
  Aborted
  rpolzer@katsuragi ruby $ ruby putpixel.rb 1>/dev/null
  putpixel.rb:22:in `write': method call on terminated object (NotImplementedError)
          from putpixel.rb:22:in `print'
          from putpixel.rb:22:in `setbg'
          from putpixel.rb:26:in `setfgbg'
          from putpixel.rb:53:in `printcolors'
          from putpixel.rb:71:in `redraw_range'
          from putpixel.rb:68:in `each'
          from putpixel.rb:68:in `redraw_range'
          from putpixel.rb:66:in `each'
          from putpixel.rb:66:in `redraw_range'
          from putpixel.rb:82:in `put'
          from putpixel.rb:102
          from putpixel.rb:99:in `loop'
          from putpixel.rb:99

Any idea what could be causing the problem?



class Screen
  def initialize(w, h, f)
    @w = w
    @h = 2 * h
    @f = f
    @a = Array.new(@h).collect!() do
      Array.new(@w, 0)
    end
    @last_fg = -1
    @last_bg = -1
    @f.print "\e[11m"
  end
  attr_reader :w
  attr_reader :h
  def setfg(f)
    return if @last_fg == f
    @f.print "\033[3#{f}m"
    @last_fg = f
  end
  def setbg(b)
    return if @last_bg == b
    @f.print "\033[4#{b}m" # <----------
    @last_bg = b
  end
  def setfgbg(f, b)
    return setbg(b) if @last_fg == f
    return setfg(f) if @last_bg == b
    @f.print "\033[3#{f};4#{b}m"
    @last_fg = f
    @last_bg = b
  end
  def printcolors(a, b)
    if a == b then
      if @last_fg == a then
        @f.print "\333"
      elsif @last_fg == b then
        @f.print "\040"
      elsif rand(2) == 0 then
        setfg(a)
        @f.print "\333"
      else
        setbg(a)
        @f.print "\040"
      end
    else
      fb = 0
      fb += 2 if a == @last_fg
      fb += 2 if b == @last_bg
      fb -= 2 if b == @last_fg
      fb -= 2 if a == @last_bg
      fb += 1 - 2 * rand(2)
      if fb > 0 then
        setfgbg(a, b)
        @f.print "\337"
      else
        setfgbg(b, a)
        @f.print "\334"
      end
    end
  end
  def redraw_range(x, y, w, h)
    firstline = y / 2
    lastline = (y + h - 1)/2
    firstcol = x
    lastcol = x + w - 1
    (firstline..lastline).each() do |row|
      @f.print "\e[#{row + 1};#{firstcol + 1}H"
      (firstcol..lastcol).each() do |col|
        color_1 = @a[2*row][col]
        color_2 = @a[2*row+1][col]
        printcolors color_1, color_2
      end
    end
  end
  def redraw()
    @f.print "\e[2J"
    redraw_range(0, 0, @w, @h)
  end
  def put(x, y, c)
    raise "x too small" if x < 0
    @a[y][x] = c % 8
    redraw_range(x, y, 1, 1)
  end
  def get(x, y)
    @a[y][x]
  end
  def destruct()
    @f.print "\e[10m"
  end
end

s = Screen.new(80, 24, $stdout)
x = 0
y = 0
dx = 1
dy = 1

loop do
  x = rand(s.w)
  y = rand(s.h)
  c = rand(8)
  s.put(x, y, c)
end