示例#1
0
void print_memory_info(Process *p)
{
    if (p != NULL) {
        erts_printf("======================================\n");
        erts_printf("|| Memory info for %-12T ||\n",p->common.id);
        erts_printf("======================================\n");
        erts_printf("+- local heap ----%s-%s-%s-%s-+\n",
                    dashes,dashes,dashes,dashes);
        erts_printf("| Young | 0x%0*lx - (0x%0*lx) - 0x%0*lx - 0x%0*lx |\n",
                    PTR_SIZE, (unsigned long)HEAP_START(p),
                    PTR_SIZE, (unsigned long)HIGH_WATER(p),
                    PTR_SIZE, (unsigned long)HEAP_TOP(p),
                    PTR_SIZE, (unsigned long)HEAP_END(p));
        if (OLD_HEAP(p) != NULL)
            erts_printf("| Old   | 0x%0*lx - 0x%0*lx - 0x%0*lx   %*s     |\n",
                        PTR_SIZE, (unsigned long)OLD_HEAP(p),
                        PTR_SIZE, (unsigned long)OLD_HTOP(p),
                        PTR_SIZE, (unsigned long)OLD_HEND(p),
                        PTR_SIZE, "");
    } else {
        erts_printf("=================\n");
        erts_printf("|| Memory info ||\n");
        erts_printf("=================\n");
    }
    erts_printf("+-----------------%s-%s-%s-%s-+\n",dashes,dashes,dashes,dashes);
}
示例#2
0
文件: hipe_bif1.c 项目: 0x00evil/otp
BIF_RETTYPE hipe_bifs_gc_info_0(BIF_ALIST_0)
{
#ifdef __BENCHMARK__
#ifndef BM_COUNTERS
    Uint minor_gc = 0;
    Uint major_gc = 0;
#endif
#ifndef BM_HEAP_SIZES
    Uint max_used_heap	    = 0;
    Uint max_allocated_heap = 0;
#endif
    Eterm *hp;
    Uint used_heap = (BIF_P->htop - BIF_P->heap) +
		     (OLD_HTOP(BIF_P) - OLD_HEAP(BIF_P)) +
		     MBUF_SIZE(BIF_P);

    Uint alloc_heap = (BIF_P->hend - BIF_P->heap) +
		      (OLD_HEND(BIF_P) - OLD_HEAP(BIF_P)) +
		      MBUF_SIZE(BIF_P);

    hp = HAlloc(BIF_P, 7);
    BIF_RET(TUPLE6(hp,
		   make_small((Uint)minor_gc),
		   make_small((Uint)major_gc),
		   make_small((Uint)used_heap),
		   make_small((Uint)alloc_heap),
		   make_small(max_used_heap),
		   make_small(max_allocated_heap)));
#else
    BIF_RET(am_false);
#endif
}
示例#3
0
文件: erl_gc.c 项目: margnus1/otp
static int
within2(Eterm *ptr, Process *p, Eterm *real_htop)
{
    ErlHeapFragment* bp = MBUF(p);
    ErlMessage* mp = p->msg.first;
    Eterm *htop = real_htop ? real_htop : HEAP_TOP(p);

    if (OLD_HEAP(p) && (OLD_HEAP(p) <= ptr && ptr < OLD_HEND(p))) {
        return 1;
    }
    if (HEAP_START(p) <= ptr && ptr < htop) {
        return 1;
    }
    while (bp != NULL) {
        if (bp->mem <= ptr && ptr < bp->mem + bp->used_size) {
            return 1;
        }
        bp = bp->next;
    }
    while (mp) {
	if (mp->data.attached) {
	    ErlHeapFragment *hfp;
	    if (is_value(ERL_MESSAGE_TERM(mp)))
		hfp = mp->data.heap_frag;
	    else if (is_not_nil(ERL_MESSAGE_TOKEN(mp)))
		hfp = erts_dist_ext_trailer(mp->data.dist_ext);
	    else
		hfp = NULL;
	    if (hfp && hfp->mem <= ptr && ptr < hfp->mem + hfp->used_size)
		return 1;
	}
        mp = mp->next;
    }
    return 0;
}
示例#4
0
/*
 * erts_check_heap and erts_check_memory will run through the heap
 * silently if everything is ok.  If there are strange (untagged) data
 * in the heap or wild pointers, the system will be halted with an
 * error message.
 */
void erts_check_heap(Process *p)
{
    ErlHeapFragment* bp = MBUF(p);

    erts_check_memory(p,HEAP_START(p),HEAP_TOP(p));
    if (OLD_HEAP(p) != NULL) {
        erts_check_memory(p,OLD_HEAP(p),OLD_HTOP(p));
    }

    while (bp) {
	erts_check_memory(p,bp->mem,bp->mem + bp->used_size);
        bp = bp->next;
    }
}
示例#5
0
文件: break.c 项目: easemob/otp
static void
print_garb_info(int to, void *to_arg, Process* p)
{
    /* ERTS_SMP: A scheduler is probably concurrently doing gc... */
#ifndef ERTS_SMP
    erts_print(to, to_arg, "New heap start: %bpX\n", p->heap);
    erts_print(to, to_arg, "New heap top: %bpX\n", p->htop);
    erts_print(to, to_arg, "Stack top: %bpX\n", p->stop);
    erts_print(to, to_arg, "Stack end: %bpX\n", p->hend);
    erts_print(to, to_arg, "Old heap start: %bpX\n", OLD_HEAP(p));
    erts_print(to, to_arg, "Old heap top: %bpX\n", OLD_HTOP(p));
    erts_print(to, to_arg, "Old heap end: %bpX\n", OLD_HEND(p));
#endif
}
示例#6
0
static void print_process_memory(Process *p)
{
    ErlHeapFragment* bp = MBUF(p);

    erts_printf("==============================\n");
    erts_printf("|| Memory info for %T ||\n",p->common.id);
    erts_printf("==============================\n");

    erts_printf("-- %-*s ---%s-%s-%s-%s--\n",
                PTR_SIZE, "PCB", dashes, dashes, dashes, dashes);

    if (p->msg.first != NULL) {
        ErtsMessage* mp;
        erts_printf("  Message Queue:\n");
        mp = p->msg.first;
        while (mp != NULL) {
            erts_printf("| 0x%0*lx | 0x%0*lx |\n",PTR_SIZE,
                        ERL_MESSAGE_TERM(mp),PTR_SIZE,ERL_MESSAGE_TOKEN(mp));
            mp = mp->next;
        }
    }

    if (p->dictionary != NULL) {
        int n = ERTS_PD_SIZE(p->dictionary);
        Eterm *ptr = ERTS_PD_START(p->dictionary);
        erts_printf("  Dictionary: ");
        while (n--) erts_printf("0x%0*lx ",PTR_SIZE,(unsigned long)ptr++);
        erts_printf("\n");
    }

    if (p->arity > 0) {
        int n = p->arity;
        Eterm *ptr = p->arg_reg;
        erts_printf("  Argument Registers: ");
        while (n--) erts_printf("0x%0*lx ",PTR_SIZE,(unsigned long)*ptr++);
        erts_printf("\n");
    }

    erts_printf("  Trace Token: 0x%0*lx\n",PTR_SIZE,p->seq_trace_token);
    erts_printf("  Group Leader: 0x%0*lx\n",PTR_SIZE,p->group_leader);
    erts_printf("  Fvalue: 0x%0*lx\n",PTR_SIZE,p->fvalue);
    erts_printf("  Ftrace: 0x%0*lx\n",PTR_SIZE,p->ftrace);

    erts_printf("+- %-*s -+ 0x%0*lx 0x%0*lx %s-%s-+\n",
                PTR_SIZE, "Stack",
                PTR_SIZE, (unsigned long)STACK_TOP(p),
                PTR_SIZE, (unsigned long)STACK_START(p),
                dashes, dashes);
    print_untagged_memory(STACK_TOP(p),STACK_START(p));

    erts_printf("+- %-*s -+ 0x%0*lx 0x%0*lx 0x%0*lx 0x%0*lx +\n",
                PTR_SIZE, "Heap",
                PTR_SIZE, (unsigned long)HEAP_START(p),
                PTR_SIZE, (unsigned long)HIGH_WATER(p),
                PTR_SIZE, (unsigned long)HEAP_TOP(p),
                PTR_SIZE, (unsigned long)HEAP_END(p));
    print_untagged_memory(HEAP_START(p),HEAP_TOP(p));

    if (OLD_HEAP(p)) {
        erts_printf("+- %-*s -+ 0x%0*lx 0x%0*lx 0x%0*lx %s-+\n",
                    PTR_SIZE, "Old Heap",
                    PTR_SIZE, (unsigned long)OLD_HEAP(p),
                    PTR_SIZE, (unsigned long)OLD_HTOP(p),
                    PTR_SIZE, (unsigned long)OLD_HEND(p),
                    dashes);
        print_untagged_memory(OLD_HEAP(p),OLD_HTOP(p));
    }

    if (bp)
        erts_printf("+- %-*s -+-%s-%s-%s-%s-+\n",
                    PTR_SIZE, "heap fragments",
                    dashes, dashes, dashes, dashes);
    while (bp) {
	print_untagged_memory(bp->mem,bp->mem + bp->used_size);
        bp = bp->next;
    }
}
示例#7
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);
}