[ruby-core:85771] [Ruby trunk Bug#14542] syswrite spuriously empties the given string

Date: 2018-02-23 11:41:58 UTC
List: ruby-core #85771
Issue #14542 has been updated by sylvain.joyeux (Sylvain Joyeux).


> For 2.4.3, can you try removing the rb_str_tmp_frozen_release call in the rb_io_syswrite function in io.c?

With difficulty ... the only place I manage to reproduce semi-reliably is on Travis. This does happen outside Travis, but rarely. It happens that the test suite triggers it on Travis pretty often for whatever reason.

> Just to cover all bases, are you somehow sharing @write_buffer between multiple threads?

It shouldn't, but there *are* multiple threads in the system. I'll check it out just to be sure.

> Or do you have any signal handler where @write_buffer may be clobbered?

No signal handler.

----------------------------------------
Bug #14542: syswrite spuriously empties the given string
https://bugs.ruby-lang.org/issues/14542#change-70618

* Author: sylvain.joyeux (Sylvain Joyeux)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: 2.3.6, 2.4.3
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
I'm doing a bit of buffer management to write on a socket. The main method looks like this:

~~~ ruby
@write_buffer.concat(new_bytes) if new_bytes
written_bytes = io.syswrite(@write_buffer)
@write_buffer = @write_buffer[written_bytes..-1]
!@write_buffer.empty?
~~~

However, in some cases, I get a nil `@write_buffer`. I've added some debugging info:

~~~ ruby
@write_buffer.concat(new_bytes) if new_bytes
size_before_syswrite = @write_buffer.size
written_bytes = io.syswrite(@write_buffer)
size_after_syswrite = @write_buffer.size
updated_write_buffer = @write_buffer[written_bytes..-1]
if !updated_write_buffer
  STDERR.puts "NIL WRITE BUFFER, size_before_syswrite=#{size_before_syswrite} size_after_syswrite=#{size_after_syswrite} written_bytes=#{written_bytes}"
end
@write_buffer = updated_write_buffer
!@write_buffer.empty?
~~~

in all cases, I got the following output:

~~~
NIL WRITE BUFFER, size_before_syswrite=3106 size_after_syswrite=0 written_bytes=3106
~~~

However, I could not reproduce the problem with toy setups. syswrite's string handling is beyond the little I know of MRI's internals ;-)



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread

Prev Next