Project

General

Profile

Actions

Bug #14542

closed

syswrite spuriously empties the given string

Added by sylvain.joyeux (Sylvain Joyeux) about 6 years ago. Updated over 5 years ago.

Status:
Third Party's Issue
Assignee:
-
Target version:
-
ruby -v:
2.3.6, 2.4.3
[ruby-core:85755]

Description

I'm doing a bit of buffer management to write on a socket. The main method looks like this:

@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:

@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 ;-)

Updated by normalperson (Eric Wong) about 6 years ago

wrote:

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

  • Target version:
  • ruby -v: 2.3.6, 2.4.3

Hitting this in 2.4.3 might be my fault, but I'm not sure about
Ruby 2.3.6 since my garbage reduction fixes aren't in that.

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

I'm doing a bit of buffer management to write on a socket. The main method looks like this:

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

Just to cover all bases, are you somehow sharing @write_buffer
between multiple threads? Or do you have any signal handler
where @write_buffer may be clobbered?

I'll try to be around this weekend to do some deeper
investigation.

Updated by sylvain.joyeux (Sylvain Joyeux) about 6 years ago

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.

Updated by sylvain.joyeux (Sylvain Joyeux) about 6 years ago

It seems so far that it is indeed a multithreading problem on my side, possibly specific to the test suite. My apologies for the noise, and thanks a lot to Eric for his help.

I don't find a way to close this ...

Updated by sylvain.joyeux (Sylvain Joyeux) over 5 years ago

Could someone close this report ? It's been solved as 'not a bug in Ruby'

Actions #5

Updated by Eregon (Benoit Daloze) over 5 years ago

  • Status changed from Open to Third Party's Issue
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0