Beispiel #1
0
static Eterm load_nif_error(Process* p, const char* atom, const char* format, ...)
{
    erts_dsprintf_buf_t* dsbufp = erts_create_tmp_dsbuf(0);
    Eterm ret;
    Eterm* hp;
    Eterm** hpp = NULL;
    Uint sz = 0;
    Uint* szp = &sz;
    va_list arglist;   

    va_start(arglist, format);
    erts_vdsprintf(dsbufp, format, arglist);
    va_end(arglist);
    
    for (;;) {
	Eterm txt = erts_bld_string_n(hpp, &sz, dsbufp->str, dsbufp->str_len);
	ret = erts_bld_tuple(hpp, szp, 2, am_error,
			     erts_bld_tuple(hpp, szp, 2, mkatom(atom), txt));
	if (hpp != NULL) {
	    break;
	}
	hp = HAlloc(p,sz);
	hpp = &hp;
	szp = NULL;
    }
    erts_destroy_tmp_dsbuf(dsbufp);
    return ret;
}
Beispiel #2
0
	/* Empty loop body */
    }
    for (i = specified; i < 3; i++) {
	if (tp[i+1] != am_Underscore) {
	    goto error;
	}
    }

    mfa.module = tp[1];
    mfa.function = tp[2];

    if (is_small(tp[3])) {
        mfa.arity = signed_val(tp[3]);
    }

    if (!erts_try_seize_code_write_permission(BIF_P)) {
	ERTS_BIF_YIELD2(bif_export[BIF_erts_debug_breakpoint_2],
			BIF_P, BIF_ARG_1, BIF_ARG_2);
    }
    erts_proc_unlock(p, ERTS_PROC_LOCK_MAIN);
    erts_thr_progress_block();

    erts_bp_match_functions(&f, &mfa, specified);
    if (boolean == am_true) {
	erts_set_debug_break(&f);
	erts_install_breakpoints(&f);
	erts_commit_staged_bp();
    } else {
	erts_clear_debug_break(&f);
	erts_commit_staged_bp();
	erts_uninstall_breakpoints(&f);
    }
    erts_consolidate_bp_data(&f, 1);
    res = make_small(f.matched);
    erts_bp_free_matched_functions(&f);

    erts_thr_progress_unblock();
    erts_proc_lock(p, ERTS_PROC_LOCK_MAIN);
    erts_release_code_write_permission();
    return res;

 error:
    BIF_ERROR(p, BADARG);
}

#if 0 /* Kept for conveninence when hard debugging. */
void debug_dump_code(BeamInstr *I, int num)
{
    BeamInstr *code_ptr = I;
    BeamInstr *end = code_ptr + num;
    erts_dsprintf_buf_t *dsbufp;
    BeamInstr instr;
    int i;

    dsbufp = erts_create_tmp_dsbuf(0);
    while (code_ptr < end) {
	erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr);
	instr = (BeamInstr) code_ptr[0];
	for (i = 0; i < NUM_SPECIFIC_OPS; i++) {
	    if (BeamIsOpCode(instr, i) && opc[i].name[0] != '\0') {
		code_ptr += print_op(ERTS_PRINT_DSBUF, (void *) dsbufp,
				     i, opc[i].sz-1, code_ptr) + 1;
		break;
	    }
	}
	if (i >= NUM_SPECIFIC_OPS) {
	    erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp,
		       "unknown " HEXF "\n", instr);
	    code_ptr++;
	}
    }
    dsbufp->str[dsbufp->str_len] = 0;
    erts_fprintf(stderr,"%s", dsbufp->str);
    erts_destroy_tmp_dsbuf(dsbufp);
}
Beispiel #3
0
BIF_RETTYPE
erts_debug_disassemble_1(BIF_ALIST_1)
{
    Process* p = BIF_P;
    Eterm addr = BIF_ARG_1;
    erts_dsprintf_buf_t *dsbufp;
    Eterm* hp;
    Eterm* tp;
    Eterm bin;
    Eterm mfa;
    ErtsCodeMFA *cmfa = NULL;
    BeamCodeHeader* code_hdr;
    BeamInstr *code_ptr;
    BeamInstr instr;
    BeamInstr uaddr;
    Uint hsz;
    int i;

    if (term_to_UWord(addr, &uaddr)) {
	code_ptr = (BeamInstr *) uaddr;
	if ((cmfa = find_function_from_pc(code_ptr)) == NULL) {
	    BIF_RET(am_false);
	}
    } else if (is_tuple(addr)) {
	ErtsCodeIndex code_ix;
	Module* modp;
	Eterm mod;
	Eterm name;
	Export* ep;
	Sint arity;
	int n;

	tp = tuple_val(addr);
	if (tp[0] != make_arityval(3)) {
	error:
	    BIF_ERROR(p, BADARG);
	}
	mod = tp[1];
	name = tp[2];
	if (!is_atom(mod) || !is_atom(name) || !is_small(tp[3])) {
	    goto error;
	}
	arity = signed_val(tp[3]);
	code_ix = erts_active_code_ix();
	modp = erts_get_module(mod, code_ix);

	/*
	 * Try the export entry first to allow disassembly of special functions
	 * such as erts_debug:apply/4.  Then search for it in the module.
	 */
	if ((ep = erts_find_function(mod, name, arity, code_ix)) != NULL) {
	    /* XXX: add "&& ep->address != ep->code" condition?
	     * Consider a traced function.
	     * Its ep will have ep->address == ep->code.
	     * erts_find_function() will return the non-NULL ep.
	     * Below we'll try to derive a code_ptr from ep->address.
	     * But this code_ptr will point to the start of the Export,
	     * not the function's func_info instruction. BOOM !?
	     */
	    cmfa = erts_code_to_codemfa(ep->addressv[code_ix]);
	} else if (modp == NULL || (code_hdr = modp->curr.code_hdr) == NULL) {
	    BIF_RET(am_undef);
	} else {
	    n = code_hdr->num_functions;
	    for (i = 0; i < n; i++) {
		cmfa = &code_hdr->functions[i]->mfa;
		if (cmfa->function == name && cmfa->arity == arity) {
		    break;
		}
	    }
	    if (i == n) {
		BIF_RET(am_undef);
	    }
	}
        code_ptr = (BeamInstr*)erts_code_to_codeinfo(erts_codemfa_to_code(cmfa));
    } else {
	goto error;
    }

    dsbufp = erts_create_tmp_dsbuf(0);
    erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr);
    instr = (BeamInstr) code_ptr[0];
    for (i = 0; i < NUM_SPECIFIC_OPS; i++) {
	if (BeamIsOpCode(instr, i) && opc[i].name[0] != '\0') {
	    code_ptr += print_op(ERTS_PRINT_DSBUF, (void *) dsbufp,
				 i, opc[i].sz-1, code_ptr) + 1;
	    break;
	}
    }
    if (i >= NUM_SPECIFIC_OPS) {
	erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp,
		   "unknown " HEXF "\n", instr);
	code_ptr++;
    }
    bin = new_binary(p, (byte *) dsbufp->str, dsbufp->str_len);
    erts_destroy_tmp_dsbuf(dsbufp);
    hsz = 4+4;
    (void) erts_bld_uword(NULL, &hsz, (BeamInstr) code_ptr);
    hp = HAlloc(p, hsz);
    addr = erts_bld_uword(&hp, NULL, (BeamInstr) code_ptr);
    ASSERT(is_atom(cmfa->module) || is_nil(cmfa->module));
    ASSERT(is_atom(cmfa->function) || is_nil(cmfa->function));
    mfa = TUPLE3(hp, cmfa->module, cmfa->function,
                 make_small(cmfa->arity));
    hp += 4;
    return TUPLE3(hp, addr, bin, mfa);
}