Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DIGITS buffer may be reused while in-use #29885

Closed
PeterJacko opened this issue Nov 1, 2018 · 12 comments · Fixed by #29907
Closed

DIGITS buffer may be reused while in-use #29885

PeterJacko opened this issue Nov 1, 2018 · 12 comments · Fixed by #29907
Labels
domain:io Involving the I/O subsystem: libuv, read, write, etc. kind:bug Indicates an unexpected problem or unintended behavior

Comments

@PeterJacko
Copy link

Here is a minimal example (using the foo function as defined in https://docs.julialang.org/en/v1/manual/functions/index.html). REPL gives a wrong result almost every time I run it (sometimes the first, sometimes the second return value is wrong there)! I don't think that it is an issue with a particular function, as I had observed the same behaviour with another function as well. For functions with a single output/return it seems to consistently give a correct result.

The correct return should be (4.4, 4.59).

julia> function foo(a,b)

                  a+b, a*b

                         end
foo (generic function with 1 method)

julia> ( return_1 , return_2 ) = foo( 1.7 , 2.7 )
(4.8, 4.59)

julia> ( return_1 , return_2 ) = foo( 1.7 , 2.7 )
(4.4, 4.59)

julia> ( return_1 , return_2 ) = foo( 1.7 , 2.7 )
(4.4, 4.82)

julia> return_2
4.59


julia> versioninfo()
Julia Version 1.0.1
Commit 0d713926f8 (2018-09-29 19:05 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-6600U CPU @ 2.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, skylake)
Environment:
  JULIA_EDITOR = "C:\JuliaPro-1.0.1.1\app-1.29.0\atom.exe" -a
  JULIA_NUM_THREADS = 2
  JULIA_PKG_SERVER = https://pkg.juliacomputing.com/
  JULIA_PKG_TOKEN_PATH = C:\Users\Peter\.julia\token.toml
@fredrikekre
Copy link
Member

Are you using the Juno REPL? I vaguely recall that Juno sometimes showd bogus output in the REPL, cc @pfitzseb

@PeterJacko
Copy link
Author

yes, I have JuliaPro with the default Atom/Juno editor.

@KristofferC
Copy link
Sponsor Member

Please report to https://github.com/JunoLab/Juno.jl (unless you can reproduce this in the normal REPL).

@pfitzseb
Copy link
Member

pfitzseb commented Nov 1, 2018

Yeah, I can (kind of) repro this. It's a super weird bug which might even be caused by Base, but not sure.

With JunoLab/Atom.jl@4598ce3 I can't repro this anymore, so fingers crossed.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Nov 1, 2018

There's a race condition in the design of the Grisu output: we re-use the same buffer (DIGITS), even though that buffer might already be in use (missing a lock). We can simulate this failure pretty easily:

julia> p = Pipe()
Pipe(RawFD(0xffffffff) init => RawFD(0xffffffff) init, 0 bytes waiting)

julia> Base.link_pipe!(p, reader_supports_async=true, writer_supports_async=true)
Pipe(RawFD(0x00000013) open => RawFD(0x00000011) open, 0 bytes waiting)

julia> t1 = @async write(p, zeros(UInt8, 2^18))
Task (runnable) @0x00007f54b1e08eb0

julia> t1
Task (runnable) @0x00007f54b1e08eb0

julia> t2 = @async (print(p, 12.345); close(p.in))
Task (runnable) @0x00007f54b2c17820

julia> t2
Task (runnable) @0x00007f54b2c17820

julia> 9.8
9.8

julia> read(p, 2^18);

julia> read(p, String)
"98.345"

@vtjnash vtjnash reopened this Nov 1, 2018
@vtjnash vtjnash changed the title REPL shows wrong values for functions with several outputs DIGITS buffer may be reused while in-use Nov 1, 2018
@vtjnash vtjnash added kind:bug Indicates an unexpected problem or unintended behavior domain:io Involving the I/O subsystem: libuv, read, write, etc. backport pending 1.0 labels Nov 1, 2018
@pfitzseb
Copy link
Member

pfitzseb commented Nov 1, 2018

Is there some way to work around this on our side? Just wrapping some random code in an @async and hoping the race condition doesn't trigger seems iffy...

@Keno
Copy link
Member

Keno commented Nov 1, 2018

we should just make the DIGITS buffer task local

@vtjnash
Copy link
Sponsor Member

vtjnash commented Nov 1, 2018

Is there some way to work around this on our side?

In places where you control the output, you can add an explicit call to string(X) to the output (or equivalently use a temporary PipeBuffer) and pass that temporary object to do the final blocking write(io, s) output call in one step (where s is either a PipeBuffer object or a String).

@PeterJacko
Copy link
Author

Yeah, I can (kind of) repro this. It's a super weird bug which might even be caused by Base, but not sure.

With JunoLab/Atom.jl@4598ce3 I can't repro this anymore, so fingers crossed.

Indeed Juno developers said there was an issue with syncing of the Workspace Pane, see
JunoLab/Juno.jl#185

@pfitzseb
Copy link
Member

pfitzseb commented Nov 2, 2018

The underlying issue is still in Base, and the workaround in that commit seems to make the race condition less likely to trigger. So this issue definitely isn't fixed for good on the Juno side.

@StefanKarpinski
Copy link
Sponsor Member

It will be an issue for multithreaded I/O, however, which is coming soon.

@JeffBezanson
Copy link
Sponsor Member

Threads won't make much difference here since the buffers are already thread-local.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:io Involving the I/O subsystem: libuv, read, write, etc. kind:bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants