diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index f47e5bcb17592b..f0b82938803d16 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -377,6 +377,7 @@ XX(jl_prepend_cwd) \ XX(jl_printf) \ XX(jl_print_backtrace) \ + XX(jl_print_task_backtraces) \ XX(jl_process_events) \ XX(jl_profile_clear_data) \ XX(jl_profile_delay_nsec) \ diff --git a/src/stackwalk.c b/src/stackwalk.c index a6ca5f3d73493a..3a29e005ade047 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -1108,6 +1108,39 @@ JL_DLLEXPORT void jl_print_backtrace(void) JL_NOTSAFEPOINT jlbacktrace(); } +JL_DLLEXPORT void jl_print_task_backtraces(void) +{ + for (size_t i = 0; i < jl_n_threads; i++) { + jl_ptls_t ptls2 = jl_all_tls_states[i]; + arraylist_t *live_tasks = &ptls2->heap.live_tasks; + size_t n = live_tasks->len; + jl_safe_printf("==== Thread %d created %zu live tasks\n", + ptls2->tid + 1, n + 1); + jl_safe_printf(" ---- Root task (%p)\n", ptls2->root_task); + jl_safe_printf(" (sticky: %d, started: %d, state: %d, tid: %d)\n", + ptls2->root_task->sticky, ptls2->root_task->started, + jl_atomic_load_relaxed(&ptls2->root_task->_state), + jl_atomic_load_relaxed(&ptls2->root_task->tid) + 1); + jlbacktracet(ptls2->root_task); + + void **lst = live_tasks->items; + for (size_t j = 0; j < live_tasks->len; j++) { + jl_task_t *t = (jl_task_t *)lst[j]; + jl_safe_printf(" ---- Task %lu (%p)\n", j + 1, t); + jl_safe_printf(" (sticky: %d, started: %d, state: %d, tid: %d)\n", + t->sticky, t->started, jl_atomic_load_relaxed(&t->_state), + jl_atomic_load_relaxed(&t->tid) + 1); + if (t->stkbuf != NULL) + jlbacktracet(t); + else + jl_safe_printf(" no stack\n"); + jl_safe_printf(" ---- End task %lu\n", j + 1); + } + jl_safe_printf("==== End thread %d\n", ptls2->tid + 1); + } + jl_safe_printf("==== Done\n"); +} + #ifdef __cplusplus } #endif