262
262
heap_dump(int to, void *to_arg, Eterm x)
264
DeclareTmpHeapNoproc(last,1);
265
Eterm last = OUR_NIL;
268
268
if (is_immed(x) || is_CP(x)) {
273
if (x == OUR_NIL) { /* We are done. */
276
next = (Eterm *) EXPAND_POINTER(x);
277
} else if (is_list(x)) {
279
if (ptr[0] != OUR_NIL) {
280
erts_print(to, to_arg, ADDR_FMT ":l", ptr);
281
dump_element(to, to_arg, ptr[0]);
282
erts_putc(to, to_arg, '|');
283
dump_element(to, to_arg, ptr[1]);
284
erts_putc(to, to_arg, '\n');
285
if (is_immed(ptr[1])) {
286
ptr[1] = make_small(0);
274
while (x != OUR_NIL) {
276
next = (Eterm *) EXPAND_POINTER(x);
277
} else if (is_list(x)) {
279
if (ptr[0] != OUR_NIL) {
280
erts_print(to, to_arg, ADDR_FMT ":l", ptr);
281
dump_element(to, to_arg, ptr[0]);
282
erts_putc(to, to_arg, '|');
283
dump_element(to, to_arg, ptr[1]);
284
erts_putc(to, to_arg, '\n');
285
if (is_immed(ptr[1])) {
286
ptr[1] = make_small(0);
289
ptr[0] = (Eterm) COMPRESS_POINTER(next);
289
ptr[0] = (Eterm) COMPRESS_POINTER(next);
293
} else if (is_boxed(x)) {
298
if (hdr != OUR_NIL) { /* If not visited */
299
erts_print(to, to_arg, ADDR_FMT ":", ptr);
300
if (is_arity_value(hdr)) {
302
Uint arity = arityval(hdr);
304
erts_print(to, to_arg, "t" WORD_FMT ":", arity);
305
for (i = 1; i <= arity; i++) {
306
dump_element(to, to_arg, ptr[i]);
307
if (is_immed(ptr[i])) {
308
ptr[i] = make_small(0);
311
erts_putc(to, to_arg, ',');
314
erts_putc(to, to_arg, '\n');
293
} else if (is_boxed(x)) {
298
if (hdr != OUR_NIL) { /* If not visited */
299
erts_print(to, to_arg, ADDR_FMT ":", ptr);
300
if (is_arity_value(hdr)) {
302
Uint arity = arityval(hdr);
304
erts_print(to, to_arg, "t" WORD_FMT ":", arity);
305
for (i = 1; i <= arity; i++) {
306
dump_element(to, to_arg, ptr[i]);
307
if (is_immed(ptr[i])) {
308
ptr[i] = make_small(0);
311
erts_putc(to, to_arg, ',');
314
erts_putc(to, to_arg, '\n');
319
ptr[0] = (Eterm) COMPRESS_POINTER(next);
320
next = ptr + arity - 1;
323
} else if (hdr == HEADER_FLONUM) {
328
GET_DOUBLE_DATA((ptr+1), f);
329
i = sys_double_to_chars(f.fd, (char*) sbuf);
330
sys_memset(sbuf+i, 0, 31-i);
331
erts_print(to, to_arg, "F%X:%s\n", i, sbuf);
333
} else if (_is_bignum_header(hdr)) {
334
erts_print(to, to_arg, "B%T\n", x);
336
} else if (is_binary_header(hdr)) {
337
Uint tag = thing_subtag(hdr);
338
Uint size = binary_size(x);
341
if (tag == HEAP_BINARY_SUBTAG) {
344
erts_print(to, to_arg, "Yh%X:", size);
346
for (i = 0; i < size; i++) {
347
erts_print(to, to_arg, "%02X", p[i]);
349
} else if (tag == REFC_BINARY_SUBTAG) {
350
ProcBin* pb = (ProcBin *) binary_val(x);
351
Binary* val = pb->val;
353
if (erts_smp_atomic_xchg_nob(&val->refc, 0) != 0) {
354
val->flags = (UWord) all_binaries;
357
erts_print(to, to_arg, "Yc%X:%X:%X", val,
358
pb->bytes - (byte *)val->orig_bytes,
360
} else if (tag == SUB_BINARY_SUBTAG) {
361
ErlSubBin* Sb = (ErlSubBin *) binary_val(x);
362
Eterm* real_bin = binary_val(Sb->orig);
365
if (thing_subtag(*real_bin) == REFC_BINARY_SUBTAG) {
366
ProcBin* pb = (ProcBin *) real_bin;
368
} else { /* Heap binary */
371
erts_print(to, to_arg, "Ys%X:%X:%X", val, Sb->offs, size);
373
erts_putc(to, to_arg, '\n');
375
} else if (is_external_pid_header(hdr)) {
376
erts_print(to, to_arg, "P%T\n", x);
378
} else if (is_external_port_header(hdr)) {
379
erts_print(to, to_arg, "p<%beu.%beu>\n",
380
port_channel_no(x), port_number(x));
319
ptr[0] = (Eterm) COMPRESS_POINTER(next);
320
next = ptr + arity - 1;
323
} else if (hdr == HEADER_FLONUM) {
328
GET_DOUBLE_DATA((ptr+1), f);
329
i = sys_double_to_chars(f.fd, (char*) sbuf);
330
sys_memset(sbuf+i, 0, 31-i);
331
erts_print(to, to_arg, "F%X:%s\n", i, sbuf);
333
} else if (_is_bignum_header(hdr)) {
334
erts_print(to, to_arg, "B%T\n", x);
336
} else if (is_binary_header(hdr)) {
337
Uint tag = thing_subtag(hdr);
338
Uint size = binary_size(x);
341
if (tag == HEAP_BINARY_SUBTAG) {
344
erts_print(to, to_arg, "Yh%X:", size);
346
for (i = 0; i < size; i++) {
347
erts_print(to, to_arg, "%02X", p[i]);
349
} else if (tag == REFC_BINARY_SUBTAG) {
350
ProcBin* pb = (ProcBin *) binary_val(x);
351
Binary* val = pb->val;
353
if (erts_smp_atomic_xchg(&val->refc, 0) != 0) {
354
val->flags = (UWord) all_binaries;
357
erts_print(to, to_arg, "Yc%X:%X:%X", val,
358
pb->bytes - (byte *)val->orig_bytes,
360
} else if (tag == SUB_BINARY_SUBTAG) {
361
ErlSubBin* Sb = (ErlSubBin *) binary_val(x);
362
Eterm* real_bin = binary_val(Sb->orig);
365
if (thing_subtag(*real_bin) == REFC_BINARY_SUBTAG) {
366
ProcBin* pb = (ProcBin *) real_bin;
368
} else { /* Heap binary */
371
erts_print(to, to_arg, "Ys%X:%X:%X", val, Sb->offs, size);
373
erts_putc(to, to_arg, '\n');
375
} else if (is_external_pid_header(hdr)) {
376
erts_print(to, to_arg, "P%T\n", x);
378
} else if (is_external_port_header(hdr)) {
379
erts_print(to, to_arg, "p<%bpu.%bpu>\n",
380
port_channel_no(x), port_number(x));
384
* All other we dump in the external term format.
386
dump_externally(to, to_arg, x);
387
erts_putc(to, to_arg, '\n');
384
* All other we dump in the external term format.
386
dump_externally(to, to_arg, x);
387
erts_putc(to, to_arg, '\n');
396
UnUseTmpHeapNoproc(1);