/
githubmirror
/
julia
Обзор
Документация
Войти
/
githubmirror
/
julia
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/testenv.jl
114 строк
4 KB
Cody Tapscott
test: `SIGQUIT` (grand)child processes if hang encountered (#62542)
28 июл 2026, 14:49
Не верифицирован
28 июл 2026, 14:49
521d7ec
Код
Авторство
О чём код?
# This file is a part of Julia. License is MIT: https://julialang.org/license # This includes a few helper variables and functions that provide information about the # test environment (command line flags, current module, etc). # This file can be included multiple times in the same module if necessary, # which can happen with unisolated test runs. if !@isdefined(testenv_defined) const testenv_defined = true if haskey(ENV, "JULIA_TEST_EXEFLAGS") const test_exeflags = `$(Base.shell_split(ENV["JULIA_TEST_EXEFLAGS"]))` else const test_exeflags = Base.julia_cmd() filter!(test_exeflags.exec) do c return !(startswith(c, "--depwarn") || startswith(c, "--check-bounds")) end push!(test_exeflags.exec, "--check-bounds=yes") push!(test_exeflags.exec, "--startup-file=no") push!(test_exeflags.exec, "--depwarn=error") end if haskey(ENV, "JULIA_TEST_EXTRA_EXEFLAGS") append!(test_exeflags.exec, Base.shell_split(ENV["JULIA_TEST_EXTRA_EXEFLAGS"])) end if haskey(ENV, "JULIA_TEST_EXENAME") popfirst!(test_exeflags.exec) const test_exename = `$(Base.shell_split(ENV["JULIA_TEST_EXENAME"]))` else const test_exename = popfirst!(test_exeflags.exec) end if haskey(ENV, "JULIA_RR") const rr_exename = `$(Base.shell_split(ENV["JULIA_RR"]))` else const rr_exename = `` end const test_relocated_depot = haskey(ENV, "RELOCATEDEPOT") # OS pids of the workers spawned by `addprocs_with_testenv`, recorded at # spawn time (while the worker is guaranteed healthy) so that the teardown # hook in runtests.jl can signal workers that have hung in the meantime. const worker_ospids = Dict{Int, Int}() # Best-effort enumeration of the direct children of `pid`. function child_pids(pid::Integer) children = Int[] try # On Linux, read /proc. Elsewhere, ask pgrep. if Sys.islinux() for tid in readdir("/proc/$pid/task") append!(children, parse.(Int, split(read("/proc/$pid/task/$tid/children", String)))) end else # `pgrep -P` exits non-zero when there are no matches append!(children, parse.(Int, split(read(ignorestatus(`pgrep -P $pid`), String)))) end catch # the process may have exited already; return what we have end return children end # Best-effort enumeration of the live descendants (children, grandchildren, ...) # of `pid`, ordered parents-before-children. function descendant_pids(pid::Integer) pids = Int[] queue = Int[pid] while !isempty(queue) children = child_pids(popfirst!(queue)) append!(pids, children) append!(queue, children) end return pids end function addprocs_with_testenv(X; rr_allowed=true, kwargs...) exename = rr_allowed ? `$rr_exename $test_exename` : test_exename if X isa Integer heap_size=round(Int,(Sys.total_memory()/(1024^2)/(X+1))) push!(test_exeflags.exec, "--heap-size-hint=$(heap_size)M") end procs = addprocs(X; exename=exename, exeflags=test_exeflags, kwargs...) for w in procs worker_ospids[w] = remotecall_fetch(getpid, w) end return procs end function rmprocs_with_testenv(pids...; kwargs...) result = rmprocs(pids...; kwargs...) for p in pids, q in (p isa Integer ? (p,) : p) delete!(worker_ospids, q) end return result end const curmod = @__MODULE__ const curmod_name = fullname(curmod) const curmod_str = curmod === Main ? "Main" : join(curmod_name, ".") const curmod_prefix = curmod === Main ? "" : "$(["$m." for m in curmod_name]...)" # platforms that support cfunction with closures # (requires LLVM back-end support for trampoline intrinsics) const cfunction_closure = Sys.ARCH === :x86_64 || Sys.ARCH === :i686 macro async_logerr(expr) :(@async try $(esc(expr)) catch err @error("An async task failed", exception=(err, catch_backtrace())) end) end end