Skip to content

Commit

Permalink
pass exitcode to atexit hooks (#47498)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonbyrne committed Nov 9, 2022
1 parent 83592cf commit dd62fac
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 5 deletions.
20 changes: 16 additions & 4 deletions base/initdefs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,16 @@ const atexit_hooks = Callable[
"""
atexit(f)
Register a zero-argument function `f()` to be called at process exit. `atexit()` hooks are
called in last in first out (LIFO) order and run before object finalizers.
Register a zero- or one-argument function `f()` to be called at process exit.
`atexit()` hooks are called in last in first out (LIFO) order and run before
object finalizers.
If `f` has a method defined for one integer argument, it will be called as
`f(n::Int32)`, where `n` is the current exit code, otherwise it will be called
as `f()`.
!!! compat "Julia 1.9"
The one-argument form requires Julia 1.9
Exit hooks are allowed to call `exit(n)`, in which case Julia will exit with
exit code `n` (instead of the original exit code). If more than one exit hook
Expand All @@ -365,11 +373,15 @@ LIFO order, "last called" is equivalent to "first registered".)
"""
atexit(f::Function) = (pushfirst!(atexit_hooks, f); nothing)

function _atexit()
function _atexit(exitcode::Cint)
while !isempty(atexit_hooks)
f = popfirst!(atexit_hooks)
try
f()
if hasmethod(f, (Cint,))
f(exitcode)
else
f()
end
catch ex
showerror(stderr, ex)
Base.show_backtrace(stderr, catch_backtrace())
Expand Down
7 changes: 6 additions & 1 deletion src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,15 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode)
if (jl_base_module) {
jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("_atexit"));
if (f != NULL) {
jl_value_t **fargs;
JL_GC_PUSHARGS(fargs, 2);
fargs[0] = f;
fargs[1] = jl_box_int32(exitcode);
JL_TRY {
assert(ct);
size_t last_age = ct->world_age;
ct->world_age = jl_get_world_counter();
jl_apply(&f, 1);
jl_apply(fargs, 2);
ct->world_age = last_age;
}
JL_CATCH {
Expand All @@ -282,6 +286,7 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode)
jl_printf((JL_STREAM*)STDERR_FILENO, "\n");
jlbacktrace(); // written to STDERR_FILENO
}
JL_GC_POP();
}
}

Expand Down
22 changes: 22 additions & 0 deletions test/atexit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ using Test
exit(22)
""" => 0,
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"""
atexit(exitcode -> exitcode > 10 && exit(0))
exit(22)
""" => 0,
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
)
for julia_expr in keys(julia_expr_list)
cmd_eval = _atexit_tests_gen_cmd_eval(julia_expr)
Expand Down Expand Up @@ -87,6 +92,11 @@ using Test
""" => 13,
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"""
atexit(exitcode -> exit(exitcode+3))
exit(22)
""" => 25,
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"""
atexit(() -> ("No error"))
atexit(() -> exit(5))
exit(22)
Expand Down Expand Up @@ -135,6 +145,18 @@ using Test
exit(22)
""" => 4,
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"""
atexit(() -> exit(21))
atexit(exitcode -> exit(exitcode+3))
exit(22)
""" => 21,
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"""
atexit(exitcode -> exit(exitcode+3))
atexit(() -> exit(21))
exit(22)
""" => 24,
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
)
for julia_expr in keys(julia_expr_list)
cmd_eval = _atexit_tests_gen_cmd_eval(julia_expr)
Expand Down

0 comments on commit dd62fac

Please sign in to comment.