Exemple #1
0
static void
kill_ports_driver_unloaded(DE_Handle *dh)
{
    int ix, max = erts_ptab_max(&erts_port);

    for (ix = 0; ix < max; ix++) {
	erts_aint32_t state;
	Port* prt = erts_pix2port(ix);
	if (!prt)
	    continue;

	ERTS_THR_DATA_DEPENDENCY_READ_MEMORY_BARRIER;

	state = erts_atomic32_read_nob(&prt->state);
	if (state & FREE_PORT_FLAGS)
	    continue;

	erts_port_lock(prt);

	state = erts_atomic32_read_nob(&prt->state);
	if (!(state & ERTS_PORT_SFLGS_DEAD) && prt->drv_ptr->handle == dh)
	    driver_failure_atom(ERTS_Port2ErlDrvPort(prt), "driver_unloaded");

	erts_port_release(prt);
    }
}
Exemple #2
0
void
erts_deep_process_dump(fmtfn_t to, void *to_arg)
{
    int i, max = erts_ptab_max(&erts_proc);

    all_binaries = NULL;
    init_literal_areas();
    erts_init_persistent_dumping();

    for (i = 0; i < max; i++) {
	Process *p = erts_pix2proc(i);
	if (p && p->i != ENULL) {
	    erts_aint32_t state = erts_atomic32_read_acqb(&p->state);
	    if (state & ERTS_PSFLG_EXITING)
                continue;
            if (state & ERTS_PSFLG_GC) {
                ErtsSchedulerData *sdp = erts_get_scheduler_data();
                if (!sdp || p != sdp->current_process)
                    continue;

                /* We want to dump the garbing process that caused the dump */
            }

            dump_process_info(to, to_arg, p);
       }
    }

    dump_persistent_terms(to, to_arg);
    dump_literals(to, to_arg);
    dump_binaries(to, to_arg, all_binaries);
}
Exemple #3
0
static void 
bin_check(void)
{
    Process  *rp;
    struct erl_off_heap_header* hdr;
    int i, printed = 0, max = erts_ptab_max(&erts_proc);

    for (i=0; i < max; i++) {
	rp = erts_pix2proc(i);
	if (!rp)
	    continue;
	for (hdr = rp->off_heap.first; hdr; hdr = hdr->next) {
	    if (hdr->thing_word == HEADER_PROC_BIN) {
		ProcBin *bp = (ProcBin*) hdr;
		if (!printed) {
		    erts_printf("Process %T holding binary data \n", rp->common.id);
		    printed = 1;
		}
		erts_printf("%p orig_size: %bpd, norefs = %bpd\n",
			    bp->val, 
			    bp->val->orig_size, 
			    erts_smp_atomic_read_nob(&bp->val->refc));
	    }
	}
	if (printed) {
	    erts_printf("--------------------------------------\n");
	    printed = 0;
	}
    }
    /* db_bin_check() has to be rewritten for the AVL trees... */
    /*db_bin_check();*/ 
}
Exemple #4
0
static void
process_killer(void)
{
    int i, j, max = erts_ptab_max(&erts_proc);
    Process* rp;

    erts_printf("\n\nProcess Information\n\n");
    erts_printf("--------------------------------------------------\n");
    for (i = max-1; i >= 0; i--) {
	rp = erts_pix2proc(i);
	if (rp && rp->i != ENULL) {
	    int br;
	    print_process_info(ERTS_PRINT_STDOUT, NULL, rp);
	    erts_printf("(k)ill (n)ext (r)eturn:\n");
	    while(1) {
		if ((j = sys_get_key(0)) <= 0)
		    erts_exit(0, "");
		switch(j) {
		case 'k': {
		    ErtsProcLocks rp_locks = ERTS_PROC_LOCKS_XSIG_SEND;
		    erts_aint32_t state;
		    erts_proc_inc_refc(rp);
		    erts_smp_proc_lock(rp, rp_locks);
		    state = erts_smp_atomic32_read_acqb(&rp->state);
		    if (state & (ERTS_PSFLG_FREE
				 | ERTS_PSFLG_EXITING
				 | ERTS_PSFLG_ACTIVE
				 | ERTS_PSFLG_ACTIVE_SYS
				 | ERTS_PSFLG_IN_RUNQ
				 | ERTS_PSFLG_RUNNING
				 | ERTS_PSFLG_RUNNING_SYS
				 | ERTS_PSFLG_DIRTY_RUNNING
				 | ERTS_PSFLG_DIRTY_RUNNING_SYS)) {
			erts_printf("Can only kill WAITING processes this way\n");
		    }
		    else {
			(void) erts_send_exit_signal(NULL,
						     NIL,
						     rp,
						     &rp_locks,
						     am_kill,
						     NIL,
						     NULL,
						     0);
		    }
		    erts_smp_proc_unlock(rp, rp_locks);
		    erts_proc_dec_refc(rp);
		}
		case 'n': br = 1; break;
		case 'r': return;
		default: return;
		}
		if (br == 1) break;
	    }
	}
    }
}
Exemple #5
0
static void
port_info(int to, void *to_arg)
{
    int i, max = erts_ptab_max(&erts_port);
    for (i = 0; i < max; i++) {
	Port *p = erts_pix2port(i);
	if (p)
	    print_port_info(p, to, to_arg);
    }
}
Exemple #6
0
void
process_info(int to, void *to_arg)
{
    int i, max = erts_ptab_max(&erts_proc);
    for (i = 0; i < max; i++) {
	Process *p = erts_pix2proc(i);
	if (p && p->i != ENULL) {
	    /* 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)
		print_process_info(to, to_arg, p);
	}
    }

    port_info(to, to_arg);
}
Exemple #7
0
void
erts_deep_process_dump(int to, void *to_arg)
{
    int i, max = erts_ptab_max(&erts_proc);

    all_binaries = NULL;
    
    for (i = 0; i < max; i++) {
	Process *p = erts_pix2proc(i);
	if (p && p->i != ENULL) {
	    erts_aint32_t state = erts_smp_atomic32_read_acqb(&p->state);
	    if (!(state & (ERTS_PSFLG_EXITING|ERTS_PSFLG_GC)))
		dump_process_info(to, to_arg, p);
       }
    }

    dump_binaries(to, to_arg, all_binaries);
}
Exemple #8
0
void erts_lcnt_enable_proc_lock_count(int enable)
{
    int i, max = erts_ptab_max(&erts_proc);

    for (i = 0; i < max; ++i) {
	Process* p = erts_pix2proc(i);
	if (p) {
	    if (enable) {
		if (!ERTS_LCNT_LOCK_TYPE(&(p->lock.lcnt_main))) {
		    erts_lcnt_proc_lock_init(p);
		}
	    } else {
		if (ERTS_LCNT_LOCK_TYPE(&(p->lock.lcnt_main))) {
		    erts_lcnt_proc_lock_destroy(p);
		}
	    }
	}
    }
}
static void
setup_reference_table(void)
{
    ErlHeapFragment *hfp;
    DistEntry *dep;
    HashInfo hi;
    int i, max;
    DeclareTmpHeapNoproc(heap,3);

    inserted_bins = NULL;

    hash_get_info(&hi, &erts_node_table);
    referred_nodes = erts_alloc(ERTS_ALC_T_NC_TMP,
				hi.objs*sizeof(ReferredNode));
    no_referred_nodes = 0;
    hash_foreach(&erts_node_table, init_referred_node, NULL);
    ASSERT(no_referred_nodes == hi.objs);

    hash_get_info(&hi, &erts_dist_table);
    referred_dists = erts_alloc(ERTS_ALC_T_NC_TMP,
				hi.objs*sizeof(ReferredDist));
    no_referred_dists = 0;
    hash_foreach(&erts_dist_table, init_referred_dist, NULL);
    ASSERT(no_referred_dists == hi.objs);

    /* Go through the hole system, and build a table of all references
       to ErlNode and DistEntry structures */

    erts_debug_callback_timer_foreach(try_delete_node,
				      insert_delayed_delete_node,
				      NULL);
    erts_debug_callback_timer_foreach(try_delete_dist_entry,
				      insert_delayed_delete_dist_entry,
				      NULL);

    UseTmpHeapNoproc(3);
    insert_node(erts_this_node,
		SYSTEM_REF,
		TUPLE2(&heap[0], AM_system, am_undefined));

    UnUseTmpHeapNoproc(3);

    max = erts_ptab_max(&erts_proc);
    /* Insert all processes */
    for (i = 0; i < max; i++) {
	Process *proc = erts_pix2proc(i);
	if (proc) {
	    int mli;
	    ErtsMessage *msg_list[] = {
		proc->msg.first,
#ifdef ERTS_SMP
		proc->msg_inq.first,
#endif
		proc->msg_frag};

	    /* Insert Heap */
	    insert_offheap(&(proc->off_heap),
			   HEAP_REF,
			   proc->common.id);
	    /* Insert heap fragments buffers */
	    for(hfp = proc->mbuf; hfp; hfp = hfp->next)
		insert_offheap(&(hfp->off_heap),
			       HEAP_REF,
			       proc->common.id);

	    /* Insert msg buffers */
	    for (mli = 0; mli < sizeof(msg_list)/sizeof(msg_list[0]); mli++) {
		ErtsMessage *msg;
		for (msg = msg_list[mli]; msg; msg = msg->next) {
		    ErlHeapFragment *heap_frag = NULL;
		    if (msg->data.attached) {
			if (msg->data.attached == ERTS_MSG_COMBINED_HFRAG)
			    heap_frag = &msg->hfrag;
			else if (is_value(ERL_MESSAGE_TERM(msg)))
			    heap_frag = msg->data.heap_frag;
			else {
			    if (msg->data.dist_ext->dep)
				insert_dist_entry(msg->data.dist_ext->dep,
						  HEAP_REF, proc->common.id, 0);
			    if (is_not_nil(ERL_MESSAGE_TOKEN(msg)))
				heap_frag = erts_dist_ext_trailer(msg->data.dist_ext);
			}
		    }
		    while (heap_frag) {
			insert_offheap(&(heap_frag->off_heap),
				       HEAP_REF,
				       proc->common.id);
			heap_frag = heap_frag->next;
		    }
		}
	    }
	    /* Insert links */
	    if (ERTS_P_LINKS(proc))
		insert_links(ERTS_P_LINKS(proc), proc->common.id);
	    if (ERTS_P_MONITORS(proc))
		insert_monitors(ERTS_P_MONITORS(proc), proc->common.id);
	    /* Insert controller */
	    {
		DistEntry *dep = ERTS_PROC_GET_DIST_ENTRY(proc);
		if (dep)
		    insert_dist_entry(dep, CTRL_REF, proc->common.id, 0);
	    }
	}
    }
    
#ifdef ERTS_SMP
    erts_foreach_sys_msg_in_q(insert_sys_msg);
#endif

    /* Insert all ports */
    max = erts_ptab_max(&erts_port);
    for (i = 0; i < max; i++) {
	ErlOffHeap *ohp;
	erts_aint32_t state;
	Port *prt;

	prt = erts_pix2port(i);
	if (!prt)
	    continue;

	state = erts_atomic32_read_nob(&prt->state);
	if (state & ERTS_PORT_SFLGS_DEAD)
	    continue;

	/* Insert links */
	if (ERTS_P_LINKS(prt))
	    insert_links(ERTS_P_LINKS(prt), prt->common.id);
	/* Insert monitors */
	if (ERTS_P_MONITORS(prt))
	    insert_monitors(ERTS_P_MONITORS(prt), prt->common.id);
	/* Insert port data */
	ohp = erts_port_data_offheap(prt);
	if (ohp)
	    insert_offheap(ohp, HEAP_REF, prt->common.id);
	/* Insert controller */
	if (prt->dist_entry)
	    insert_dist_entry(prt->dist_entry,
			      CTRL_REF,
			      prt->common.id,
			      0);
    }

    { /* Add binaries stored elsewhere ... */
	ErlOffHeap oh;
	ProcBin pb[2];
	int i = 0;
	Binary *default_match_spec;
	Binary *default_meta_match_spec;

	oh.first = NULL;
	/* Only the ProcBin members thing_word, val and next will be inspected
	   (by insert_offheap()) */
#undef  ADD_BINARY
#define ADD_BINARY(Bin)				 	     \
	if ((Bin)) {					     \
	    pb[i].thing_word = REFC_BINARY_SUBTAG;           \
	    pb[i].val = (Bin);				     \
	    pb[i].next = oh.first;		             \
	    oh.first = (struct erl_off_heap_header*) &pb[i]; \
	    i++;				             \
	}

	erts_get_default_trace_pattern(NULL,
				       &default_match_spec,
				       &default_meta_match_spec,
				       NULL,
				       NULL);

	ADD_BINARY(default_match_spec);
	ADD_BINARY(default_meta_match_spec);

	insert_offheap(&oh, BIN_REF, AM_match_spec);
#undef  ADD_BINARY
    }

    /* Insert all dist links */

    for(dep = erts_visible_dist_entries; dep; dep = dep->next) {
	if(dep->nlinks)
	    insert_links2(dep->nlinks, dep->sysname);
	if(dep->node_links)
	    insert_links(dep->node_links, dep->sysname);
	if(dep->monitors)
	    insert_monitors(dep->monitors, dep->sysname);
    }

    for(dep = erts_hidden_dist_entries; dep; dep = dep->next) {
	if(dep->nlinks)
	    insert_links2(dep->nlinks, dep->sysname);
	if(dep->node_links)
	    insert_links(dep->node_links, dep->sysname);
	if(dep->monitors)
	    insert_monitors(dep->monitors, dep->sysname);
    }

    /* Not connected dist entries should not have any links,
       but inspect them anyway */
    for(dep = erts_not_connected_dist_entries; dep; dep = dep->next) {
	if(dep->nlinks)
	    insert_links2(dep->nlinks, dep->sysname);
	if(dep->node_links)
	    insert_links(dep->node_links, dep->sysname);
	if(dep->monitors)
	    insert_monitors(dep->monitors, dep->sysname);
    }

    /* Insert all ets tables */
    erts_db_foreach_table(insert_ets_table, NULL);

    /* Insert all bif timers */
    erts_debug_bif_timer_foreach(insert_bif_timer, NULL);

    /* Insert node table (references to dist) */
    hash_foreach(&erts_node_table, insert_erl_node, NULL);
}