コード例 #1
0
ファイル: erl_process_dump.c プロジェクト: bmk/otp
Uint erts_process_memory(Process *p, int include_sigs_in_transit)
{
    Uint size = 0;
    struct saved_calls *scb;

    size += sizeof(Process);

    if ((erts_atomic32_read_nob(&p->state) & ERTS_PSFLG_EXITING) == 0) {
        erts_link_tree_foreach(ERTS_P_LINKS(p),
                               link_size, (void *) &size);
        erts_monitor_tree_foreach(ERTS_P_MONITORS(p),
                                  monitor_size, (void *) &size);
        erts_monitor_list_foreach(ERTS_P_LT_MONITORS(p),
                                  monitor_size, (void *) &size);
    }
    size += (p->heap_sz + p->mbuf_sz) * sizeof(Eterm);
    if (p->abandoned_heap)
        size += (p->hend - p->heap) * sizeof(Eterm);
    if (p->old_hend && p->old_heap)
        size += (p->old_hend - p->old_heap) * sizeof(Eterm);

    if (!include_sigs_in_transit) {
        /*
         * Size of message queue!
         *
         * Note that this assumes that any part of message
         * queue located in middle queue have been moved
         * into the inner queue prior to this call.
         * process_info() management ensures this is done-
         */
        ErtsMessage *mp;
        for (mp = p->sig_qs.first; mp; mp = mp->next) {
            ASSERT(ERTS_SIG_IS_MSG((ErtsSignal *) mp));
            size += sizeof(ErtsMessage);
            if (mp->data.attached)
                size += erts_msg_attached_data_size(mp) * sizeof(Eterm);
        }
    }
    else {
        /*
         * Size of message queue plus size of all signals
         * in transit to the process!
         */
        erts_proc_lock(p, ERTS_PROC_LOCK_MSGQ);
        erts_proc_sig_fetch(p);
        erts_proc_unlock(p, ERTS_PROC_LOCK_MSGQ);

        ERTS_FOREACH_SIG_PRIVQS(
            p, mp,
            {
                size += sizeof(ErtsMessage);
                if (ERTS_SIG_IS_NON_MSG((ErtsSignal *) mp))
                    size += erts_proc_sig_signal_size((ErtsSignal *) mp);
                else if (mp->data.attached)
                    size += erts_msg_attached_data_size(mp) * sizeof(Eterm);
            });
    }
コード例 #2
0
ファイル: erl_process_dump.c プロジェクト: bernardd/otp
Uint erts_process_memory(Process *p, int incl_msg_inq) {
  ErtsMessage *mp;
  Uint size = 0;
  struct saved_calls *scb;
  size += sizeof(Process);

  if (incl_msg_inq)
      ERTS_MSGQ_MV_INQ2PRIVQ(p);

  erts_doforall_links(ERTS_P_LINKS(p), &erts_one_link_size, &size);
  erts_doforall_monitors(ERTS_P_MONITORS(p), &erts_one_mon_size, &size);
  size += (p->heap_sz + p->mbuf_sz) * sizeof(Eterm);
  if (p->abandoned_heap)
      size += (p->hend - p->heap) * sizeof(Eterm);
  if (p->old_hend && p->old_heap)
    size += (p->old_hend - p->old_heap) * sizeof(Eterm);


  size += p->msg.len * sizeof(ErtsMessage);

  for (mp = p->msg.first; mp; mp = mp->next)
    if (mp->data.attached)
      size += erts_msg_attached_data_size(mp)*sizeof(Eterm);

  if (p->arg_reg != p->def_arg_reg) {
    size += p->arity * sizeof(p->arg_reg[0]);
  }

  if (erts_atomic_read_nob(&p->psd) != (erts_aint_t) NULL)
    size += sizeof(ErtsPSD);

  scb = ERTS_PROC_GET_SAVED_CALLS_BUF(p);
  if (scb) {
    size += (sizeof(struct saved_calls)
	     + (scb->len-1) * sizeof(scb->ct[0]));
  }

  size += erts_dicts_mem_size(p);
  return size;
}
コード例 #3
0
ファイル: break.c プロジェクト: easemob/otp
/* Display info about an individual Erlang process */
void
print_process_info(int to, void *to_arg, Process *p)
{
    time_t approx_started;
    int garbing = 0;
    int running = 0;
    struct saved_calls *scb;
    erts_aint32_t state;

    /* display the PID */
    erts_print(to, to_arg, "=proc:%T\n", p->common.id);

    /* Display the state */
    erts_print(to, to_arg, "State: ");

    state = erts_smp_atomic32_read_acqb(&p->state);
    erts_dump_process_state(to, to_arg, state);
    if (state & ERTS_PSFLG_GC) {
        garbing = 1;
        running = 1;
    } else if (state & ERTS_PSFLG_RUNNING)
        running = 1;

    /*
     * If the process is registered as a global process, display the
     * registered name
     */
    if (p->common.u.alive.reg)
	erts_print(to, to_arg, "Name: %T\n", p->common.u.alive.reg->name);

    /*
     * Display the initial function name
     */
    erts_print(to, to_arg, "Spawned as: %T:%T/%bpu\n",
	       p->u.initial[INITIAL_MOD],
	       p->u.initial[INITIAL_FUN],
	       p->u.initial[INITIAL_ARI]);
    
    if (p->current != NULL) {
	if (running) {
	    erts_print(to, to_arg, "Last scheduled in for: ");
	} else {
	    erts_print(to, to_arg, "Current call: ");
	}
	erts_print(to, to_arg, "%T:%T/%bpu\n",
		   p->current[0],
		   p->current[1],
		   p->current[2]);
    }

    erts_print(to, to_arg, "Spawned by: %T\n", p->parent);
    approx_started = (time_t) p->approx_started;
    erts_print(to, to_arg, "Started: %s", ctime(&approx_started));
    ERTS_SMP_MSGQ_MV_INQ2PRIVQ(p);
    erts_print(to, to_arg, "Message queue length: %d\n", p->msg.len);

    /* display the message queue only if there is anything in it */
    if (!ERTS_IS_CRASH_DUMPING && p->msg.first != NULL && !garbing) {
	ErlMessage* mp;
	erts_print(to, to_arg, "Message queue: [");
	for (mp = p->msg.first; mp; mp = mp->next)
	    erts_print(to, to_arg, mp->next ? "%T," : "%T", ERL_MESSAGE_TERM(mp));
	erts_print(to, to_arg, "]\n");
    }

    {
       int frags = 0;
       ErlHeapFragment *m = p->mbuf;
       while (m != NULL) {
	   frags++;
	   m = m->next;
       }
       erts_print(to, to_arg, "Number of heap fragments: %d\n", frags);
    }
    erts_print(to, to_arg, "Heap fragment data: %beu\n", MBUF_SIZE(p));

    scb = ERTS_PROC_GET_SAVED_CALLS_BUF(p);
    if (scb) {
       int i, j;

       erts_print(to, to_arg, "Last calls:");
       for (i = 0; i < scb->n; i++) {
	     erts_print(to, to_arg, " ");
	     j = scb->cur - i - 1;
	     if (j < 0)
		j += scb->len;
	     if (scb->ct[j] == &exp_send)
		erts_print(to, to_arg, "send");
	     else if (scb->ct[j] == &exp_receive)
		erts_print(to, to_arg, "'receive'");
	     else if (scb->ct[j] == &exp_timeout)
		   erts_print(to, to_arg, "timeout");
	     else
		 erts_print(to, to_arg, "%T:%T/%bpu\n",
			    scb->ct[j]->code[0],
			    scb->ct[j]->code[1],
			    scb->ct[j]->code[2]);
       }
       erts_print(to, to_arg, "\n");
    }

    /* display the links only if there are any*/
    if (ERTS_P_LINKS(p) || ERTS_P_MONITORS(p)) {
	PrintMonitorContext context = {1,to}; 
	erts_print(to, to_arg,"Link list: [");
	erts_doforall_links(ERTS_P_LINKS(p), &doit_print_link, &context);	
	erts_doforall_monitors(ERTS_P_MONITORS(p), &doit_print_monitor, &context);
	erts_print(to, to_arg,"]\n");
    }

    if (!ERTS_IS_CRASH_DUMPING) {

	/* and the dictionary */
	if (p->dictionary != NULL && !garbing) {
	    erts_print(to, to_arg, "Dictionary: ");
	    erts_dictionary_dump(to, to_arg, p->dictionary);
	    erts_print(to, to_arg, "\n");
	}
    }
    
    /* print the number of reductions etc */
    erts_print(to, to_arg, "Reductions: %beu\n", p->reds);

    erts_print(to, to_arg, "Stack+heap: %beu\n", p->heap_sz);
    erts_print(to, to_arg, "OldHeap: %bpu\n",
               (OLD_HEAP(p) == NULL) ? 0 : (OLD_HEND(p) - OLD_HEAP(p)) );
    erts_print(to, to_arg, "Heap unused: %bpu\n", (p->hend - p->htop));
    erts_print(to, to_arg, "OldHeap unused: %bpu\n",
	       (OLD_HEAP(p) == NULL) ? 0 : (OLD_HEND(p) - OLD_HTOP(p)) );
    erts_print(to, to_arg, "Memory: %beu\n", erts_process_memory(p));

    if (garbing) {
	print_garb_info(to, to_arg, p);
    }
    
    if (ERTS_IS_CRASH_DUMPING) {
	erts_program_counter_info(to, to_arg, p);
    } else {
	erts_print(to, to_arg, "Stack dump:\n");
#ifdef ERTS_SMP
	if (!garbing)
#endif
	    erts_stack_dump(to, to_arg, p);
    }

    /* Display all states */
    erts_print(to, to_arg, "Internal State: ");
    erts_dump_extended_process_state(to, to_arg, state);
}
コード例 #4
0
ファイル: erl_node_tables.c プロジェクト: JamesGreenhalgh/otp
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);
}