Skip to content

Commit fb80f24

Browse files
gbaraldiKristofferC
authored andcommitted
Print task backtraces on sigquit (#59389)
(cherry picked from commit 0635285)
1 parent d2577c6 commit fb80f24

File tree

4 files changed

+43
-5
lines changed

4 files changed

+43
-5
lines changed

src/julia_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,7 @@ JL_DLLEXPORT void jl_raise_debugger(void) JL_NOTSAFEPOINT;
15011501
JL_DLLEXPORT void jl_gdblookup(void* ip) JL_NOTSAFEPOINT;
15021502
void jl_print_native_codeloc(uintptr_t ip) JL_NOTSAFEPOINT;
15031503
void jl_print_bt_entry_codeloc(jl_bt_element_t *bt_data) JL_NOTSAFEPOINT;
1504+
JL_DLLEXPORT void jl_print_task_backtraces(int show_done) JL_NOTSAFEPOINT;
15041505
#ifdef _OS_WINDOWS_
15051506
JL_DLLEXPORT void jl_refresh_dbg_module_list(void);
15061507
#endif

src/signal-handling.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,9 @@ void jl_critical_error(int sig, int si_code, bt_context_t *context, jl_task_t *c
636636
jl_safe_printf("\n[%d] signal %d (%d): %s\n", getpid(), sig, si_code, strsignal(sig));
637637
else
638638
jl_safe_printf("\n[%d] signal %d: %s\n", getpid(), sig, strsignal(sig));
639+
if (sig == SIGQUIT) {
640+
jl_print_task_backtraces(0);
641+
}
639642
}
640643
jl_safe_printf("in expression starting at %s:%d\n", jl_filename, jl_lineno);
641644
if (context && ct) {

src/stackwalk.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,11 +1383,19 @@ JL_DLLEXPORT void jlbacktrace(void) JL_NOTSAFEPOINT
13831383
// Print backtrace for specified task to jl_safe_printf stderr
13841384
JL_DLLEXPORT void jlbacktracet(jl_task_t *t) JL_NOTSAFEPOINT
13851385
{
1386-
jl_task_t *ct = jl_current_task;
1387-
jl_ptls_t ptls = ct->ptls;
1388-
ptls->bt_size = 0;
1389-
jl_bt_element_t *bt_data = ptls->bt_data;
1390-
jl_record_backtrace_result_t r = jl_record_backtrace(t, bt_data, JL_MAX_BT_SIZE, 0);
1386+
jl_bt_element_t *bt_data;
1387+
jl_task_t *ct = jl_get_current_task();
1388+
size_t max_bt_size;
1389+
if (ct && ct->ptls != NULL) {
1390+
jl_ptls_t ptls = ct->ptls;
1391+
ptls->bt_size = 0;
1392+
bt_data = ptls->bt_data;
1393+
max_bt_size = JL_MAX_BT_SIZE;
1394+
} else {
1395+
max_bt_size = 1024; //8kb of stack should be safe
1396+
bt_data = (jl_bt_element_t *)alloca(max_bt_size * sizeof(jl_bt_element_t));
1397+
}
1398+
jl_record_backtrace_result_t r = jl_record_backtrace(t, bt_data, max_bt_size, 0);
13911399
size_t bt_size = r.bt_size;
13921400
size_t i;
13931401
for (i = 0; i < bt_size; i += jl_bt_entry_size(bt_data + i)) {

test/cmdlineargs.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,32 @@ let
6060
@test format_filename("%a%%b") == "a%b"
6161
end
6262

63+
if Sys.isunix()
64+
@testset "SIGQUIT prints task backtraces" begin
65+
script = """
66+
mutable struct RLimit
67+
cur::Int64
68+
max::Int64
69+
end
70+
const RLIMIT_CORE = 4 # from /usr/include/sys/resource.h
71+
ccall(:setrlimit, Cint, (Cint, Ref{RLimit}), RLIMIT_CORE, Ref(RLimit(0, 0)))
72+
write(stdout, "r")
73+
wait()
74+
"""
75+
exename = `$(Base.julia_cmd()) --startup-file=no --color=no`
76+
errp = PipeBuffer()
77+
# disable coredumps for this process
78+
p = open(pipeline(`$exename -e $script`, stderr=errp), "r")
79+
@test read(p, UInt8) == UInt8('r')
80+
Base.kill(p, Base.SIGQUIT)
81+
wait(p)
82+
err_s = readchomp(errp)
83+
@test Base.process_signaled(p) && p.termsignal == Base.SIGQUIT
84+
@test occursin("==== Thread ", err_s)
85+
@test occursin("==== Done", err_s)
86+
end
87+
end
88+
6389
@testset "julia_cmd" begin
6490
julia_basic = Base.julia_cmd()
6591
function get_julia_cmd(arg)

0 commit comments

Comments
 (0)