From c0ca8209570b42bfbb029eb7e9ae8750a43fb739 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Mon, 18 Mar 2019 13:33:30 +0100 Subject: erts: Add crash dumping of EXITING and FREE processes --- erts/emulator/beam/break.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'erts/emulator/beam/break.c') diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c index 27bf2187c2..303ab9d9b7 100644 --- a/erts/emulator/beam/break.c +++ b/erts/emulator/beam/break.c @@ -39,6 +39,7 @@ #include "erl_hl_timer.h" #include "erl_thr_progress.h" #include "erl_proc_sig_queue.h" +#include "dist.h" /* Forward declarations -- should really appear somewhere else */ static void process_killer(void); @@ -81,11 +82,32 @@ process_info(fmtfn_t to, void *to_arg) /* Do not include processes with no heap, * they are most likely just created and has invalid data */ - if (!ERTS_PROC_IS_EXITING(p) && p->heap != NULL) + if (p->heap != NULL) print_process_info(to, to_arg, p, 0); } } + /* Look for FREE processes in the run-queues and dist entries. + These have been removed from the ptab but we still want them + in the crash dump for debugging. */ + + /* First loop through all run-queues */ + for (i = 0; i < erts_no_schedulers + ERTS_NUM_DIRTY_RUNQS; i++) { + ErtsRunQueue *rq = ERTS_RUNQ_IX(i); + int j; + for (j = 0; j < ERTS_NO_PROC_PRIO_QUEUES; j++) { + Process *p = rq->procs.prio[j].first; + while (p) { + if (ERTS_PSFLG_FREE & erts_atomic32_read_acqb(&p->state)) + print_process_info(to, to_arg, p, 0); + p = p->next; + } + } + } + + /* Then check all dist entries */ + erts_dist_print_procs_suspended_on_de(to, to_arg); + port_info(to, to_arg); } @@ -206,6 +228,7 @@ print_process_info(fmtfn_t to, void *to_arg, Process *p, ErtsProcLocks orig_lock { int garbing = 0; int running = 0; + int exiting = 0; Sint len; struct saved_calls *scb; erts_aint32_t state; @@ -226,6 +249,9 @@ print_process_info(fmtfn_t to, void *to_arg, Process *p, ErtsProcLocks orig_lock | ERTS_PSFLG_DIRTY_RUNNING)) running = 1; + if (state & ERTS_PSFLG_EXITING) + exiting = 1; + if (!(locks & ERTS_PROC_LOCK_MAIN)) { locks |= ERTS_PROC_LOCK_MAIN; if (ERTS_IS_CRASH_DUMPING && running) { @@ -246,7 +272,7 @@ print_process_info(fmtfn_t to, void *to_arg, Process *p, ErtsProcLocks orig_lock * If the process is registered as a global process, display the * registered name */ - if (p->common.u.alive.reg) + if (!ERTS_PROC_IS_EXITING(p) && p->common.u.alive.reg) erts_print(to, to_arg, "Name: %T\n", p->common.u.alive.reg->name); /* @@ -332,7 +358,7 @@ print_process_info(fmtfn_t to, void *to_arg, Process *p, ErtsProcLocks orig_lock } /* display the links only if there are any*/ - if (ERTS_P_LINKS(p) || ERTS_P_MONITORS(p) || ERTS_P_LT_MONITORS(p)) { + if (!exiting && (ERTS_P_LINKS(p) || ERTS_P_MONITORS(p) || ERTS_P_LT_MONITORS(p))) { PrintMonitorContext context = {1, to, to_arg}; erts_print(to, to_arg,"Link list: ["); erts_link_tree_foreach(ERTS_P_LINKS(p), doit_print_link, &context); -- cgit v1.2.3