Skip to content

Commit d89b96b

Browse files
authored
Add jl_print_task_backtraces() (#46845)
Iterates through `jl_all_tls_states` and through all `live_tasks` in `ptls->heap`, printing backtraces.
1 parent 532125d commit d89b96b

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

src/stackwalk.c

+41-3
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ static void JuliaInitializeLongjmpXorKey(void)
722722
}
723723
#endif
724724

725-
JL_UNUSED static uintptr_t ptr_demangle(uintptr_t p)
725+
JL_UNUSED static uintptr_t ptr_demangle(uintptr_t p) JL_NOTSAFEPOINT
726726
{
727727
#if defined(__GLIBC__)
728728
#if defined(_CPU_X86_)
@@ -854,7 +854,7 @@ _os_ptr_munge(uintptr_t ptr)
854854

855855
extern bt_context_t *jl_to_bt_context(void *sigctx);
856856

857-
void jl_rec_backtrace(jl_task_t *t)
857+
void jl_rec_backtrace(jl_task_t *t) JL_NOTSAFEPOINT
858858
{
859859
jl_task_t *ct = jl_current_task;
860860
jl_ptls_t ptls = ct->ptls;
@@ -1104,7 +1104,9 @@ JL_DLLEXPORT void jlbacktrace(void) JL_NOTSAFEPOINT
11041104
jl_print_bt_entry_codeloc(bt_data + i);
11051105
}
11061106
}
1107-
JL_DLLEXPORT void jlbacktracet(jl_task_t *t)
1107+
1108+
// Print backtrace for specified task
1109+
JL_DLLEXPORT void jlbacktracet(jl_task_t *t) JL_NOTSAFEPOINT
11081110
{
11091111
jl_task_t *ct = jl_current_task;
11101112
jl_ptls_t ptls = ct->ptls;
@@ -1121,6 +1123,42 @@ JL_DLLEXPORT void jl_print_backtrace(void) JL_NOTSAFEPOINT
11211123
jlbacktrace();
11221124
}
11231125

1126+
// Print backtraces for all live tasks, for all threads.
1127+
// WARNING: this is dangerous and can crash if used outside of gdb, if
1128+
// all of Julia's threads are not stopped!
1129+
JL_DLLEXPORT void jl_print_task_backtraces(void) JL_NOTSAFEPOINT
1130+
{
1131+
for (size_t i = 0; i < jl_n_threads; i++) {
1132+
jl_ptls_t ptls2 = jl_all_tls_states[i];
1133+
arraylist_t *live_tasks = &ptls2->heap.live_tasks;
1134+
size_t n = live_tasks->len;
1135+
jl_safe_printf("==== Thread %d created %zu live tasks\n",
1136+
ptls2->tid + 1, n + 1);
1137+
jl_safe_printf(" ---- Root task (%p)\n", ptls2->root_task);
1138+
jl_safe_printf(" (sticky: %d, started: %d, state: %d, tid: %d)\n",
1139+
ptls2->root_task->sticky, ptls2->root_task->started,
1140+
jl_atomic_load_relaxed(&ptls2->root_task->_state),
1141+
jl_atomic_load_relaxed(&ptls2->root_task->tid) + 1);
1142+
jlbacktracet(ptls2->root_task);
1143+
1144+
void **lst = live_tasks->items;
1145+
for (size_t j = 0; j < live_tasks->len; j++) {
1146+
jl_task_t *t = (jl_task_t *)lst[j];
1147+
jl_safe_printf(" ---- Task %zu (%p)\n", j + 1, t);
1148+
jl_safe_printf(" (sticky: %d, started: %d, state: %d, tid: %d)\n",
1149+
t->sticky, t->started, jl_atomic_load_relaxed(&t->_state),
1150+
jl_atomic_load_relaxed(&t->tid) + 1);
1151+
if (t->stkbuf != NULL)
1152+
jlbacktracet(t);
1153+
else
1154+
jl_safe_printf(" no stack\n");
1155+
jl_safe_printf(" ---- End task %zu\n", j + 1);
1156+
}
1157+
jl_safe_printf("==== End thread %d\n", ptls2->tid + 1);
1158+
}
1159+
jl_safe_printf("==== Done\n");
1160+
}
1161+
11241162
#ifdef __cplusplus
11251163
}
11261164
#endif

0 commit comments

Comments
 (0)