IOBuffer becomes not writable after `run`

Hi! When upgrading from Julia v1.7 to Julia v1.8, I noticed this change of behavior when using run passing an IOBuffer as stdout kwarg.

On Julia v1.7, I could pass the same instance of the IOBuffer to consecutive run calls, as follows:

julia> VERSION
v"1.7.2"

julia> io = IOBuffer()
IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)

julia> run(pipeline(`ls`, stdout=io))
Process(`ls`, ProcessExited(0))

julia> iswritable(io)
true

julia> run(pipeline(`ls`, stdout=io))
Process(`ls`, ProcessExited(0))

Upgrading to Julia v1.8, the IOBuffer becomes not writable after the first call to run, which yields an error if I use it on another run call.

julia> VERSION
v"1.8.4"

julia> io = IOBuffer()
IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=Inf, ptr=1, mark=-1)

julia> run(pipeline(`ls`, stdout=io))
Process(`ls`, ProcessExited(0))

julia> iswritable(io)
false

julia> run(pipeline(`ls`, stdout=io))
┌ Warning: Process I/O error
│   exception =
│    ArgumentError: ensureroom failed, IOBuffer is not writeable
│    Stacktrace:
│     [1] ensureroom_slowpath(io::IOBuffer, nshort::UInt64)
│       @ Base ./iobuffer.jl:303
│     [2] ensureroom
│       @ ./iobuffer.jl:325 [inlined]
│     [3] unsafe_write(to::IOBuffer, p::Ptr{UInt8}, nb::UInt64)
│       @ Base ./iobuffer.jl:424
│     [4] unsafe_write
│       @ ./io.jl:683 [inlined]
│     [5] write
│       @ ./io.jl:706 [inlined]
│     [6] write(to::IOBuffer, from::Base.PipeEndpoint)
│       @ Base ./io.jl:753
│     [7] (::Base.var"#729#730"{IOBuffer, Bool, Base.PipeEndpoint, IOBuffer, Base.PipeEndpoint})()
│       @ Base ./task.jl:484
└ @ Base process.jl:302
Process(`ls`, ProcessExited(0))

Is there a way to use the same IOBuffer instance as stdout on consecutive run calls on Julia v1.8?

1 Like

Just setting io.writable = true in between the successive run calls works, though it seems like a bit of a hack.

1 Like

That makes a data race, which may go very very badly for you—as in randomly occasionally corrupt your whole computer kinds of ways (which is why this now does not function as before)

2 Likes