Giter VIP home page Giter VIP logo

Comments (1)

NHDaly avatar NHDaly commented on May 27, 2024

EDIT: I've edited the original message to the much more compelling example @test_logs example.
Moving the previous description here, as a secondary example:

Any Task spawned during a Test, which logs after Test.collect_test_logs() returns can trigger a data race, where the spawned task logs into the logs vector, while the caller is reading from that vector.

Here is a contrived example that I managed to get to reproduce the issue:

julia> function code_to_test()
           # do the work
           @info "starting"
           start_transaction()
           # ...
           @info "done"
           # Clean up
           end_transaction()
       end
code_to_test (generic function with 1 method)

julia> start_transaction() = nothing
start_transaction (generic function with 1 method)

julia> function end_transaction()
           # spawn a task to do some cleanup in the background, so we can
           # return to the client immediately
           Threads.@spawn begin
               # clean stuff up
               @info "Background Cleanup Task: All done cleaning up!"
               for _ in 1:1000
                   @info "now it's clean, goodbye"
               end
           end
       end
end_transaction (generic function with 1 method)

julia> using Test

julia> for _ in 1:10000
           let (logs,_) = Test.collect_test_logs() do
                   @info "hey"
                   code_to_test()
                   @warn "hi"
               end

               for log in logs
                   @test length(log.message) > 1
               end
           end
       end

ERROR: UndefRefError: access to undefined reference
Stacktrace:
 [1] getindex
   @ ./essentials.jl:13 [inlined]
 [2] iterate(A::Vector{LogRecord}, i::Int64)
   @ Base ./array.jl:945
 [3] top-level scope
   @ REPL[5]:10

This also sometimes segfaults, of course:

[66213] signal (11.2): Segmentation fault: 11
in expression starting at REPL[5]:1
signal (11) thread (1) sig_match_fast at /Users/nathandaly/builds/julia-RAI/src/gf.c:2914 [inlined]
signal (11) thread (1) jl_lookup_generic_ at /Users/nathandaly/builds/julia-RAI/src/gf.c:2994 [inlined]
signal (11) thread (1) ijl_apply_generic at /Users/nathandaly/builds/julia-RAI/src/gf.c:3073

We see this showing up in our CI build farm from time to time.

The solution is almost certainly to make that vector thread-safe, by introducing a lock around it, and then copying the vector out before returning.

from julia.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.