Make TestLogger thread-safe (introduce a lock) (#54497)
Fixes https://github.com/JuliaLang/julia/issues/54439.
- Lock around concurrent accesses to .logs, .message_limits, and
.shouldlog_args.
- Copy the vector out of the logger at the end, to shield against
dangling Tasks.
Before:
```julia
julia> Threads.nthreads()
8
julia> function foo(n)
@info "Doing foo with n=$n"
@sync for i=1:n
Threads.@spawn @info "Iteration $i"
end
42
end
foo (generic function with 1 method)
julia> for _ in 1:1000
@test_logs (:info,"Doing foo with n=10000") match_mode=:any foo(10_000)
end
julia+RAI(56155,0x1f5157ac0) malloc: double free for ptr 0x128248000
julia+RAI(56155,0x1f5157ac0) malloc: *** set a breakpoint in malloc_error_break to debug
[56155] signal (6): Abort trap: 6
in expression starting at REPL[8]:1
signal (6) thread (1) __pthread_kill at /usr/lib/system/libsystem_kernel.dylib (unknown line)
Allocations: 54370881 (Pool: 54363911; Big: 6970); GC: 119
[1] 56154 abort julia -tauto
```
After:
```julia
julia> Threads.nthreads()
8
julia> function foo(n)
@info "Doing foo with n=$n"
@sync for i=1:n
Threads.@spawn @info "Iteration $i"
end
42
end
foo (generic function with 1 method)
julia> for _ in 1:1000
@test_logs (:info,"Doing foo with n=10000") match_mode=:any foo(10_000)
end
```
(no crash) :)