4
* Copyright Ericsson AB 1998-2009. All Rights Reserved.
4
* Copyright Ericsson AB 1998-2011. All Rights Reserved.
6
6
* The contents of this file are subject to the Erlang Public License,
7
7
* Version 1.1, (the "License"); you may not use this file except in
8
8
* compliance with the License. You should have received a copy of the
9
9
* Erlang Public License along with this software. If not, it can be
10
10
* retrieved online at http://www.erlang.org/.
12
12
* Software distributed under the License is distributed on an "AS IS"
13
13
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
* the License for the specific language governing rights and limitations
15
15
* under the License.
44
44
# define HEXF "%08bpX"
46
#define TermWords(t) (((t) / (sizeof(BeamInstr)/sizeof(Eterm))) + !!((t) % (sizeof(BeamInstr)/sizeof(Eterm))))
47
48
void dbg_bt(Process* p, Eterm* sp);
48
void dbg_where(Eterm* addr, Eterm x0, Eterm* reg);
49
void dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg);
50
static void print_big(int to, void *to_arg, Eterm* addr);
51
static int print_op(int to, void *to_arg, int op, int size, Eterm* addr);
51
static int print_op(int to, void *to_arg, int op, int size, BeamInstr* addr);
53
53
erts_debug_same_2(Process* p, Eterm term1, Eterm term2)
124
124
BIF_ERROR(p, BADARG);
127
#if 0 /* Kept for conveninence when hard debugging. */
128
void debug_dump_code(BeamInstr *I, int num)
130
BeamInstr *code_ptr = I;
131
BeamInstr *end = code_ptr + num;
132
erts_dsprintf_buf_t *dsbufp;
136
dsbufp = erts_create_tmp_dsbuf(0);
137
while (code_ptr < end) {
138
erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr);
139
instr = (BeamInstr) code_ptr[0];
140
for (i = 0; i < NUM_SPECIFIC_OPS; i++) {
141
if (instr == (BeamInstr) BeamOp(i) && opc[i].name[0] != '\0') {
142
code_ptr += print_op(ERTS_PRINT_DSBUF, (void *) dsbufp,
143
i, opc[i].sz-1, code_ptr+1) + 1;
147
if (i >= NUM_SPECIFIC_OPS) {
148
erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp,
149
"unknown " HEXF "\n", instr);
153
dsbufp->str[dsbufp->str_len] = 0;
154
erts_fprintf(stderr,"%s", dsbufp->str);
155
erts_destroy_tmp_dsbuf(dsbufp);
160
erts_debug_instructions_0(BIF_ALIST_0)
163
Uint needed = num_instructions * 2;
167
for (i = 0; i < num_instructions; i++) {
168
needed += 2*strlen(opc[i].name);
170
hp = HAlloc(BIF_P, needed);
171
for (i = num_instructions-1; i >= 0; i--) {
172
Eterm s = erts_bld_string_n(&hp, 0, opc[i].name, strlen(opc[i].name));
173
res = erts_bld_cons(&hp, 0, s, res);
128
179
erts_debug_disassemble_1(Process* p, Eterm addr)
135
Eterm* funcinfo = NULL; /* Initialized to eliminate warning. */
137
Uint* code_ptr = NULL; /* Initialized to eliminate warning. */
186
BeamInstr* funcinfo = NULL; /* Initialized to eliminate warning. */
187
BeamInstr* code_base;
188
BeamInstr* code_ptr = NULL; /* Initialized to eliminate warning. */
143
if (term_to_Uint(addr, &uaddr)) {
144
code_ptr = (Uint *) uaddr;
194
if (term_to_UWord(addr, &uaddr)) {
195
code_ptr = (BeamInstr *) uaddr;
145
196
if ((funcinfo = find_function_from_pc(code_ptr)) == NULL) {
146
197
BIF_RET(am_false);
180
231
* But this code_ptr will point to the start of the Export,
181
232
* not the function's func_info instruction. BOOM !?
183
code_ptr = ((Eterm *) ep->address) - 5;
234
code_ptr = ((BeamInstr *) ep->address) - 5;
184
235
funcinfo = code_ptr+2;
185
236
} else if (modp == NULL || (code_base = modp->code) == NULL) {
186
237
BIF_RET(am_undef);
188
239
n = code_base[MI_NUM_FUNCTIONS];
189
240
for (i = 0; i < n; i++) {
190
code_ptr = (Uint *) code_base[MI_FUNCTIONS+i];
241
code_ptr = (BeamInstr *) code_base[MI_FUNCTIONS+i];
191
242
if (code_ptr[3] == name && code_ptr[4] == arity) {
192
243
funcinfo = code_ptr+2;
204
255
dsbufp = erts_create_tmp_dsbuf(0);
205
256
erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr);
206
instr = (Uint) code_ptr[0];
257
instr = (BeamInstr) code_ptr[0];
207
258
for (i = 0; i < NUM_SPECIFIC_OPS; i++) {
208
if (instr == (Uint) BeamOp(i) && opc[i].name[0] != '\0') {
259
if (instr == (BeamInstr) BeamOp(i) && opc[i].name[0] != '\0') {
209
260
code_ptr += print_op(ERTS_PRINT_DSBUF, (void *) dsbufp,
210
261
i, opc[i].sz-1, code_ptr+1) + 1;
216
267
"unknown " HEXF "\n", instr);
219
bin = new_binary(p, (byte *) dsbufp->str, (int) dsbufp->str_len);
270
bin = new_binary(p, (byte *) dsbufp->str, dsbufp->str_len);
220
271
erts_destroy_tmp_dsbuf(dsbufp);
222
(void) erts_bld_uint(NULL, &hsz, (Uint) code_ptr);
273
(void) erts_bld_uword(NULL, &hsz, (BeamInstr) code_ptr);
223
274
hp = HAlloc(p, hsz);
224
addr = erts_bld_uint(&hp, NULL, (Uint) code_ptr);
275
addr = erts_bld_uword(&hp, NULL, (BeamInstr) code_ptr);
225
276
ASSERT(is_atom(funcinfo[0]));
226
277
ASSERT(is_atom(funcinfo[1]));
227
mfa = TUPLE3(hp, funcinfo[0], funcinfo[1], make_small(funcinfo[2]));
278
mfa = TUPLE3(hp, (Eterm) funcinfo[0], (Eterm) funcinfo[1], make_small((Eterm) funcinfo[2]));
229
280
return TUPLE3(hp, addr, bin, mfa);
237
288
while (sp < stack) {
238
289
if (is_CP(*sp)) {
239
Eterm* addr = find_function_from_pc(cp_val(*sp));
290
BeamInstr* addr = find_function_from_pc(cp_val(*sp));
241
292
erts_fprintf(stderr,
242
293
HEXF ": %T:%T/%bpu\n",
243
addr, addr[0], addr[1], addr[2]);
294
addr, (Eterm) addr[0], (Eterm) addr[1], (Uint) addr[2]);
250
dbg_where(Eterm* addr, Eterm x0, Eterm* reg)
301
dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg)
252
Eterm* f = find_function_from_pc(addr);
303
BeamInstr* f = find_function_from_pc(addr);
255
306
erts_fprintf(stderr, "???\n");
262
erts_fprintf(stderr, HEXF ": %T:%T(", addr, addr[0], addr[1]);
313
erts_fprintf(stderr, HEXF ": %T:%T(", addr, (Eterm) addr[0], (Eterm) addr[1]);
263
314
for (i = 0; i < arity; i++)
264
315
erts_fprintf(stderr, i ? ", %T" : "%T", i ? reg[i] : x0);
265
316
erts_fprintf(stderr, ")\n");
270
print_op(int to, void *to_arg, int op, int size, Eterm* addr)
321
print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
275
326
char* start_prog; /* Start of program for packer. */
276
327
char* prog; /* Current position in packer program. */
277
Uint stack[8]; /* Stack for packer. */
278
Uint* sp = stack; /* Points to next free position. */
279
Uint packed = 0; /* Accumulator for packed operations. */
280
Uint args[8]; /* Arguments for this instruction. */
281
Uint* ap; /* Pointer to arguments. */
328
BeamInstr stack[8]; /* Stack for packer. */
329
BeamInstr* sp = stack; /* Points to next free position. */
330
BeamInstr packed = 0; /* Accumulator for packed operations. */
331
BeamInstr args[8]; /* Arguments for this instruction. */
332
BeamInstr* ap; /* Pointer to arguments. */
333
BeamInstr* unpacked; /* Unpacked arguments */
283
335
start_prog = opc[op].pack;
390
448
case 'i': /* Tagged integer */
391
449
case 'c': /* Tagged constant */
392
450
case 'q': /* Tagged literal */
393
erts_print(to, to_arg, "%T", *ap);
451
erts_print(to, to_arg, "%T", (Eterm) *ap);
397
erts_print(to, to_arg, "%d", arityval(ap[0]));
455
erts_print(to, to_arg, "%d", arityval( (Eterm) ap[0]));
400
458
case 'd': /* Destination (x(0), x(N), y(N)) */
423
481
case 'f': /* Destination label */
424
erts_print(to, to_arg, "f(%X)", *ap);
483
BeamInstr* f = find_function_from_pc((BeamInstr *)*ap);
484
if (f+3 != (BeamInstr *) *ap) {
485
erts_print(to, to_arg, "f(" HEXF ")", *ap);
487
erts_print(to, to_arg, "%T:%T/%bpu", (Eterm) f[0], (Eterm) f[1], (Eterm) f[2]);
427
492
case 'p': /* Pointer (to label) */
429
Eterm* f = find_function_from_pc((Eterm *)*ap);
431
if (f+3 != (Eterm *) *ap) {
432
erts_print(to, to_arg, "p(%X)", *ap);
494
BeamInstr* f = find_function_from_pc((BeamInstr *)*ap);
495
if (f+3 != (BeamInstr *) *ap) {
496
erts_print(to, to_arg, "p(" HEXF ")", *ap);
434
erts_print(to, to_arg, "%T:%T/%bpu", f[0], f[1], f[2]);
498
erts_print(to, to_arg, "%T:%T/%bpu", (Eterm) f[0], (Eterm) f[1], (Eterm) f[2]);
439
503
case 'j': /* Pointer (to label) */
440
erts_print(to, to_arg, "j(%X)", *ap);
504
erts_print(to, to_arg, "j(" HEXF ")", *ap);
443
507
case 'e': /* Export entry */
445
509
Export* ex = (Export *) *ap;
446
510
erts_print(to, to_arg,
447
"%T:%T/%bpu", ex->code[0], ex->code[1], ex->code[2]);
511
"%T:%T/%bpu", (Eterm) ex->code[0], (Eterm) ex->code[1], (Uint) ex->code[2]);
487
552
* Print more information about certain instructions.
490
556
ap = addr + size;
492
case op_i_select_val_sfI:
497
erts_print(to, to_arg, "%T f(%X) ", ap[0], ap[1]);
504
case op_i_jump_on_val_sfII:
558
case op_i_select_val_rfI:
559
case op_i_select_val_xfI:
560
case op_i_select_val_yfI:
565
erts_print(to, to_arg, "%T f(" HEXF ") ", (Eterm) ap[0], ap[1]);
572
case op_i_select_tuple_arity_rfI:
573
case op_i_select_tuple_arity_xfI:
574
case op_i_select_tuple_arity_yfI:
579
Uint arity = arityval(ap[0]);
580
erts_print(to, to_arg, " {%d} f(" HEXF ")", arity, ap[1]);
587
case op_i_jump_on_val_rfII:
588
case op_i_jump_on_val_xfII:
589
case op_i_jump_on_val_yfII:
507
592
for (n = ap[-2]; n > 0; n--) {
508
erts_print(to, to_arg, "f(%X) ", ap[0]);
514
case op_i_select_big_sf:
516
int arity = thing_arityval(ap[0]);
517
print_big(to, to_arg, ap);
520
erts_print(to, to_arg, " f(%X) ", ap[0]);
593
erts_print(to, to_arg, "f(" HEXF ") ", ap[0]);
599
case op_i_jump_on_val_zero_rfI:
600
case op_i_jump_on_val_zero_xfI:
601
case op_i_jump_on_val_zero_yfI:
604
for (n = ap[-1]; n > 0; n--) {
605
erts_print(to, to_arg, "f(" HEXF ") ", ap[0]);
611
case op_i_put_tuple_rI:
612
case op_i_put_tuple_xI:
613
case op_i_put_tuple_yI:
615
int n = unpacked[-1];
618
if (!is_header(ap[0])) {
619
erts_print(to, to_arg, " %T", (Eterm) ap[0]);
621
switch ((ap[0] >> 2) & 0x03) {
623
erts_print(to, to_arg, " x(0)");
626
erts_print(to, to_arg, " x(%d)", ap[0] >> 4);
629
erts_print(to, to_arg, " y(%d)", ap[0] >> 4);
528
638
erts_print(to, to_arg, "\n");
534
print_big(int to, void *to_arg, Eterm* addr)
541
erts_print(to, to_arg, "-#integer(%d) = {", i);
543
erts_print(to, to_arg, "#integer(%d) = {", i);
544
erts_print(to, to_arg, "%d", BIG_DIGIT(addr, 0));
545
for (k = 1; k < i; k++)
546
erts_print(to, to_arg, ",%d", BIG_DIGIT(addr, k));
547
erts_print(to, to_arg, "}");