diff options
Diffstat (limited to 'erts/emulator/beam/beam_debug.c')
-rw-r--r-- | erts/emulator/beam/beam_debug.c | 154 |
1 files changed, 97 insertions, 57 deletions
diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c index 4242a4161e..23b267d5cd 100644 --- a/erts/emulator/beam/beam_debug.c +++ b/erts/emulator/beam/beam_debug.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1998-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1998-2010. All Rights Reserved. + * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. - * + * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. - * + * * %CopyrightEnd% */ @@ -43,12 +43,13 @@ #else # define HEXF "%08bpX" #endif +#define TermWords(t) (((t) / (sizeof(BeamInstr)/sizeof(Eterm))) + !!((t) % (sizeof(BeamInstr)/sizeof(Eterm)))) void dbg_bt(Process* p, Eterm* sp); -void dbg_where(Eterm* addr, Eterm x0, Eterm* reg); +void dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg); static void print_big(int to, void *to_arg, Eterm* addr); -static int print_op(int to, void *to_arg, int op, int size, Eterm* addr); +static int print_op(int to, void *to_arg, int op, int size, BeamInstr* addr); Eterm erts_debug_same_2(Process* p, Eterm term1, Eterm term2) { @@ -124,6 +125,38 @@ erts_debug_breakpoint_2(Process* p, Eterm MFA, Eterm bool) BIF_ERROR(p, BADARG); } +#if 0 /* XXX:PaN - not used */ +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 (instr == (BeamInstr) BeamOp(i) && opc[i].name[0] != '\0') { + code_ptr += print_op(ERTS_PRINT_DSBUF, (void *) dsbufp, + i, opc[i].sz-1, code_ptr+1) + 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); +} +#endif + Eterm erts_debug_disassemble_1(Process* p, Eterm addr) { @@ -132,16 +165,16 @@ erts_debug_disassemble_1(Process* p, Eterm addr) Eterm* tp; Eterm bin; Eterm mfa; - Eterm* funcinfo = NULL; /* Initialized to eliminate warning. */ - Uint* code_base; - Uint* code_ptr = NULL; /* Initialized to eliminate warning. */ - Uint instr; - Uint uaddr; + BeamInstr* funcinfo = NULL; /* Initialized to eliminate warning. */ + BeamInstr* code_base; + BeamInstr* code_ptr = NULL; /* Initialized to eliminate warning. */ + BeamInstr instr; + BeamInstr uaddr; Uint hsz; int i; - if (term_to_Uint(addr, &uaddr)) { - code_ptr = (Uint *) uaddr; + if (term_to_UWord(addr, &uaddr)) { + code_ptr = (BeamInstr *) uaddr; if ((funcinfo = find_function_from_pc(code_ptr)) == NULL) { BIF_RET(am_false); } @@ -180,14 +213,14 @@ erts_debug_disassemble_1(Process* p, Eterm addr) * But this code_ptr will point to the start of the Export, * not the function's func_info instruction. BOOM !? */ - code_ptr = ((Eterm *) ep->address) - 5; + code_ptr = ((BeamInstr *) ep->address) - 5; funcinfo = code_ptr+2; } else if (modp == NULL || (code_base = modp->code) == NULL) { BIF_RET(am_undef); } else { n = code_base[MI_NUM_FUNCTIONS]; for (i = 0; i < n; i++) { - code_ptr = (Uint *) code_base[MI_FUNCTIONS+i]; + code_ptr = (BeamInstr *) code_base[MI_FUNCTIONS+i]; if (code_ptr[3] == name && code_ptr[4] == arity) { funcinfo = code_ptr+2; break; @@ -203,9 +236,9 @@ erts_debug_disassemble_1(Process* p, Eterm addr) dsbufp = erts_create_tmp_dsbuf(0); erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr); - instr = (Uint) code_ptr[0]; + instr = (BeamInstr) code_ptr[0]; for (i = 0; i < NUM_SPECIFIC_OPS; i++) { - if (instr == (Uint) BeamOp(i) && opc[i].name[0] != '\0') { + if (instr == (BeamInstr) BeamOp(i) && opc[i].name[0] != '\0') { code_ptr += print_op(ERTS_PRINT_DSBUF, (void *) dsbufp, i, opc[i].sz-1, code_ptr+1) + 1; break; @@ -219,12 +252,12 @@ erts_debug_disassemble_1(Process* p, Eterm addr) bin = new_binary(p, (byte *) dsbufp->str, (int) dsbufp->str_len); erts_destroy_tmp_dsbuf(dsbufp); hsz = 4+4; - (void) erts_bld_uint(NULL, &hsz, (Uint) code_ptr); + (void) erts_bld_uword(NULL, &hsz, (BeamInstr) code_ptr); hp = HAlloc(p, hsz); - addr = erts_bld_uint(&hp, NULL, (Uint) code_ptr); + addr = erts_bld_uword(&hp, NULL, (BeamInstr) code_ptr); ASSERT(is_atom(funcinfo[0])); ASSERT(is_atom(funcinfo[1])); - mfa = TUPLE3(hp, funcinfo[0], funcinfo[1], make_small(funcinfo[2])); + mfa = TUPLE3(hp, (Eterm) funcinfo[0], (Eterm) funcinfo[1], make_small((Eterm) funcinfo[2])); hp += 4; return TUPLE3(hp, addr, bin, mfa); } @@ -236,20 +269,20 @@ dbg_bt(Process* p, Eterm* sp) while (sp < stack) { if (is_CP(*sp)) { - Eterm* addr = find_function_from_pc(cp_val(*sp)); + BeamInstr* addr = find_function_from_pc(cp_val(*sp)); if (addr) erts_fprintf(stderr, HEXF ": %T:%T/%bpu\n", - addr, addr[0], addr[1], addr[2]); + addr, (Eterm) addr[0], (Eterm) addr[1], (Uint) addr[2]); } sp++; } } void -dbg_where(Eterm* addr, Eterm x0, Eterm* reg) +dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg) { - Eterm* f = find_function_from_pc(addr); + BeamInstr* f = find_function_from_pc(addr); if (f == NULL) { erts_fprintf(stderr, "???\n"); @@ -259,7 +292,7 @@ dbg_where(Eterm* addr, Eterm x0, Eterm* reg) addr = f; arity = addr[2]; - erts_fprintf(stderr, HEXF ": %T:%T(", addr, addr[0], addr[1]); + erts_fprintf(stderr, HEXF ": %T:%T(", addr, (Eterm) addr[0], (Eterm) addr[1]); for (i = 0; i < arity; i++) erts_fprintf(stderr, i ? ", %T" : "%T", i ? reg[i] : x0); erts_fprintf(stderr, ")\n"); @@ -267,18 +300,18 @@ dbg_where(Eterm* addr, Eterm x0, Eterm* reg) } static int -print_op(int to, void *to_arg, int op, int size, Eterm* addr) +print_op(int to, void *to_arg, int op, int size, BeamInstr* addr) { int i; - Uint tag; + BeamInstr tag; char* sign; char* start_prog; /* Start of program for packer. */ char* prog; /* Current position in packer program. */ - Uint stack[8]; /* Stack for packer. */ - Uint* sp = stack; /* Points to next free position. */ - Uint packed = 0; /* Accumulator for packed operations. */ - Uint args[8]; /* Arguments for this instruction. */ - Uint* ap; /* Pointer to arguments. */ + BeamInstr stack[8]; /* Stack for packer. */ + BeamInstr* sp = stack; /* Points to next free position. */ + BeamInstr packed = 0; /* Accumulator for packed operations. */ + BeamInstr args[8]; /* Arguments for this instruction. */ + BeamInstr* ap; /* Pointer to arguments. */ start_prog = opc[op].pack; @@ -288,7 +321,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) * Avoid copying because instructions containing bignum operands * are bigger than actually declared. */ - ap = (Uint *) addr; + ap = (BeamInstr *) addr; } else { /* * Copy all arguments to a local buffer for the unpacking. @@ -324,8 +357,8 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) packed >>= BEAM_TIGHT_SHIFT; break; case '6': /* Shift 16 steps */ - *ap++ = packed & 0xffff; - packed >>= 16; + *ap++ = packed & BEAM_LOOSE_MASK; + packed >>= BEAM_LOOSE_SHIFT; break; case 'p': *sp++ = *--ap; @@ -390,11 +423,11 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) case 'i': /* Tagged integer */ case 'c': /* Tagged constant */ case 'q': /* Tagged literal */ - erts_print(to, to_arg, "%T", *ap); + erts_print(to, to_arg, "%T", (Eterm) *ap); ap++; break; case 'A': - erts_print(to, to_arg, "%d", arityval(ap[0])); + erts_print(to, to_arg, "%d", arityval( (Eterm) ap[0])); ap++; break; case 'd': /* Destination (x(0), x(N), y(N)) */ @@ -421,30 +454,36 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) ap++; break; case 'f': /* Destination label */ - erts_print(to, to_arg, "f(%X)", *ap); - ap++; + { + BeamInstr* f = find_function_from_pc((BeamInstr *)*ap); + if (f+3 != (BeamInstr *) *ap) { + erts_print(to, to_arg, "f(" HEXF ")", *ap); + } else { + erts_print(to, to_arg, "%T:%T/%bpu", (Eterm) f[0], (Eterm) f[1], (Eterm) f[2]); + } + ap++; + } break; case 'p': /* Pointer (to label) */ { - Eterm* f = find_function_from_pc((Eterm *)*ap); - - if (f+3 != (Eterm *) *ap) { - erts_print(to, to_arg, "p(%X)", *ap); + BeamInstr* f = find_function_from_pc((BeamInstr *)*ap); + if (f+3 != (BeamInstr *) *ap) { + erts_print(to, to_arg, "p(" HEXF ")", *ap); } else { - erts_print(to, to_arg, "%T:%T/%bpu", f[0], f[1], f[2]); + erts_print(to, to_arg, "%T:%T/%bpu", (Eterm) f[0], (Eterm) f[1], (Eterm) f[2]); } ap++; } break; case 'j': /* Pointer (to label) */ - erts_print(to, to_arg, "j(%X)", *ap); + erts_print(to, to_arg, "j(" HEXF ")", *ap); ap++; break; case 'e': /* Export entry */ { Export* ex = (Export *) *ap; erts_print(to, to_arg, - "%T:%T/%bpu", ex->code[0], ex->code[1], ex->code[2]); + "%T:%T/%bpu", (Eterm) ex->code[0], (Eterm) ex->code[1], (Uint) ex->code[2]); ap++; } break; @@ -467,7 +506,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) ap++; break; case 'P': /* Byte offset into tuple (see beam_load.c) */ - erts_print(to, to_arg, "%d", (*ap / sizeof(Eterm*)) - 1); + erts_print(to, to_arg, "%d", (*ap / sizeof(Eterm)) - 1); ap++; break; case 'l': /* fr(N) */ @@ -494,7 +533,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) int n = ap[-1]; while (n > 0) { - erts_print(to, to_arg, "%T f(%X) ", ap[0], ap[1]); + erts_print(to, to_arg, "%T f(" HEXF ") ", (Eterm) ap[0], ap[1]); ap += 2; size += 2; n--; @@ -505,7 +544,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) { int n; for (n = ap[-2]; n > 0; n--) { - erts_print(to, to_arg, "f(%X) ", ap[0]); + erts_print(to, to_arg, "f(" HEXF ") ", ap[0]); ap++; size++; } @@ -513,11 +552,12 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr) break; case op_i_select_big_sf: while (ap[0]) { - int arity = thing_arityval(ap[0]); - print_big(to, to_arg, ap); - size += arity+1; - ap += arity+1; - erts_print(to, to_arg, " f(%X) ", ap[0]); + Eterm *bigp = (Eterm *) ap; + int arity = thing_arityval(*bigp); + print_big(to, to_arg, bigp); + size += TermWords(arity+1); + ap += TermWords(arity+1); + erts_print(to, to_arg, " f(" HEXF ") ", ap[0]); ap++; size++; } @@ -541,8 +581,8 @@ print_big(int to, void *to_arg, Eterm* addr) erts_print(to, to_arg, "-#integer(%d) = {", i); else erts_print(to, to_arg, "#integer(%d) = {", i); - erts_print(to, to_arg, "%d", BIG_DIGIT(addr, 0)); + erts_print(to, to_arg, "0x%x", BIG_DIGIT(addr, 0)); for (k = 1; k < i; k++) - erts_print(to, to_arg, ",%d", BIG_DIGIT(addr, k)); + erts_print(to, to_arg, ",0x%x", BIG_DIGIT(addr, k)); erts_print(to, to_arg, "}"); } |