0.7.13.5
[sbcl/lichteblau.git] / src / runtime / print.c
blob6875c06bf01fdf23c1720024329d85fb2577c1ff
1 /* code for low-level debugging/diagnostic output */
3 /*
4 * This software is part of the SBCL system. See the README file for
5 * more information.
7 * This software is derived from the CMU CL system, which was
8 * written at Carnegie Mellon University and released into the
9 * public domain. The software is in the public domain and is
10 * provided with absolutely no warranty. See the COPYING and CREDITS
11 * files for more information.
15 * FIXME:
16 * Some of the code in here (the various
17 * foo_slots[], at least) is deeply broken, depending on guessing
18 * already out-of-date values instead of getting them from sbcl.h.
21 #include <stdio.h>
23 #include "print.h"
24 #include "runtime.h"
25 #include "sbcl.h"
27 /* This file can be skipped if we're not supporting LDB. */
28 #if defined(LISP_FEATURE_SB_LDB)
30 #include "monitor.h"
31 #include "vars.h"
32 #include "os.h"
33 #include "genesis/static-symbols.h"
34 #include "primitive-objects.h"
36 static int max_lines = 20, cur_lines = 0;
37 static int max_depth = 5, brief_depth = 2, cur_depth = 0;
38 static int max_length = 5;
39 static boolean dont_descend = 0, skip_newline = 0;
40 static int cur_clock = 0;
42 static void print_obj(char *prefix, lispobj obj);
44 #define NEWLINE_OR_RETURN if (continue_p(1)) newline(NULL); else return;
46 char *lowtag_Names[] = {
47 "even fixnum",
48 "instance pointer",
49 "other immediate [0]",
50 "list pointer",
51 "odd fixnum",
52 "function pointer",
53 "other immediate [1]",
54 "other pointer"
57 /* FIXME: Yikes! This table implicitly depends on the values in sbcl.h,
58 * but doesn't actually depend on them, so if they change, it gets
59 * all broken. We should either get rid of it or
60 * rewrite the code so that it's cleanly initialized by gc_init_tables[]
61 * in a way which varies correctly with the values in sbcl.h. */
62 char *subtype_Names[] = {
63 "unused 0",
64 "unused 1",
65 "bignum",
66 "ratio",
67 "single float",
68 "double float",
69 #ifdef LONG_FLOAT_WIDETAG
70 "long float",
71 #endif
72 "complex",
73 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
74 "complex single float",
75 #endif
76 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
77 "complex double float",
78 #endif
79 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
80 "complex long float",
81 #endif
82 "simple-array",
83 "simple-string",
84 "simple-bit-vector",
85 "simple-vector",
86 "(simple-array (unsigned-byte 2) (*))",
87 "(simple-array (unsigned-byte 4) (*))",
88 "(simple-array (unsigned-byte 8) (*))",
89 "(simple-array (unsigned-byte 16) (*))",
90 "(simple-array (unsigned-byte 32) (*))",
91 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
92 "(simple-array (signed-byte 8) (*))",
93 #endif
94 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
95 "(simple-array (signed-byte 16) (*))",
96 #endif
97 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
98 "(simple-array fixnum (*))",
99 #endif
100 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
101 "(simple-array (signed-byte 32) (*))",
102 #endif
103 "(simple-array single-float (*))",
104 "(simple-array double-float (*))",
105 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
106 "(simple-array long-float (*))",
107 #endif
108 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
109 "(simple-array (complex single-float) (*))",
110 #endif
111 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
112 "(simple-array (complex double-float) (*))",
113 #endif
114 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
115 "(simple-array (complex long-float) (*))",
116 #endif
117 "complex-string",
118 "complex-bit-vector",
119 "(array * (*))",
120 "array",
121 "code header",
122 "function header",
123 "closure header",
124 "funcallable-instance header",
125 "unused function header 1",
126 "unused function header 2",
127 "unused function header 3",
128 "closure function header",
129 "return PC header",
130 "value cell header",
131 "symbol header",
132 "character",
133 "SAP",
134 "unbound marker",
135 "weak pointer",
136 "instance header",
137 "fdefn"
140 static void indent(int in)
142 static char *spaces = " ";
144 while (in > 64) {
145 fputs(spaces, stdout);
146 in -= 64;
148 if (in != 0)
149 fputs(spaces + 64 - in, stdout);
152 static boolean continue_p(boolean newline)
154 char buffer[256];
156 if (cur_depth >= max_depth || dont_descend)
157 return 0;
159 if (newline) {
160 if (skip_newline)
161 skip_newline = 0;
162 else
163 putchar('\n');
165 if (cur_lines >= max_lines) {
166 printf("More? [y] ");
167 fflush(stdout);
169 fgets(buffer, sizeof(buffer), stdin);
171 if (buffer[0] == 'n' || buffer[0] == 'N')
172 throw_to_monitor();
173 else
174 cur_lines = 0;
178 return 1;
181 static void newline(char *label)
183 cur_lines++;
184 if (label != NULL)
185 fputs(label, stdout);
186 putchar('\t');
187 indent(cur_depth * 2);
191 static void brief_fixnum(lispobj obj)
193 #ifndef alpha
194 printf("%ld", ((long)obj)>>2);
195 #else
196 printf("%d", ((s32)obj)>>2);
197 #endif
200 static void print_fixnum(lispobj obj)
202 #ifndef alpha
203 printf(": %ld", ((long)obj)>>2);
204 #else
205 printf(": %d", ((s32)obj)>>2);
206 #endif
209 static void brief_otherimm(lispobj obj)
211 int type, c, idx;
212 char buffer[10];
214 type = widetag_of(obj);
215 switch (type) {
216 case BASE_CHAR_WIDETAG:
217 c = (obj>>8)&0xff;
218 switch (c) {
219 case '\0':
220 printf("#\\Null");
221 break;
222 case '\n':
223 printf("#\\Newline");
224 break;
225 case '\b':
226 printf("#\\Backspace");
227 break;
228 case '\177':
229 printf("#\\Delete");
230 break;
231 default:
232 strcpy(buffer, "#\\");
233 if (c >= 128) {
234 strcat(buffer, "m-");
235 c -= 128;
237 if (c < 32) {
238 strcat(buffer, "c-");
239 c += '@';
241 printf("%s%c", buffer, c);
242 break;
244 break;
246 case UNBOUND_MARKER_WIDETAG:
247 printf("<unbound marker>");
248 break;
250 default:
251 idx = type >> 2;
252 if (idx < (sizeof(lowtag_Names) / sizeof(char *)))
253 printf("%s", lowtag_Names[idx]);
254 else
255 printf("unknown type (0x%0x)", type);
256 break;
260 static void print_otherimm(lispobj obj)
262 int type, idx;
264 type = widetag_of(obj);
265 idx = type >> 2;
267 if (idx < (sizeof(lowtag_Names) / sizeof(char *)))
268 printf(", %s", lowtag_Names[idx]);
269 else
270 printf(", unknown type (0x%0x)", type);
272 switch (widetag_of(obj)) {
273 case BASE_CHAR_WIDETAG:
274 printf(": ");
275 brief_otherimm(obj);
276 break;
278 case SAP_WIDETAG:
279 case UNBOUND_MARKER_WIDETAG:
280 break;
282 default:
283 printf(": data=%ld", (long) (obj>>8)&0xffffff);
284 break;
288 static void brief_list(lispobj obj)
290 int space = 0;
291 int length = 0;
293 if (!is_valid_lisp_addr((os_vm_address_t)native_pointer(obj)))
294 printf("(invalid Lisp-level address)");
295 else if (obj == NIL)
296 printf("NIL");
297 else {
298 putchar('(');
299 while (lowtag_of(obj) == LIST_POINTER_LOWTAG) {
300 struct cons *cons = (struct cons *)native_pointer(obj);
302 if (space)
303 putchar(' ');
304 if (++length >= max_length) {
305 printf("...");
306 obj = NIL;
307 break;
309 print_obj(NULL, cons->car);
310 obj = cons->cdr;
311 space = 1;
312 if (obj == NIL)
313 break;
315 if (obj != NIL) {
316 printf(" . ");
317 print_obj(NULL, obj);
319 putchar(')');
323 static void print_list(lispobj obj)
325 if (!is_valid_lisp_addr((os_vm_address_t)native_pointer(obj))) {
326 printf("(invalid address)");
327 } else if (obj == NIL) {
328 printf(" (NIL)");
329 } else {
330 struct cons *cons = (struct cons *)native_pointer(obj);
332 print_obj("car: ", cons->car);
333 print_obj("cdr: ", cons->cdr);
337 static void brief_struct(lispobj obj)
339 printf("#<ptr to 0x%08lx instance>",
340 (unsigned long) ((struct instance *)native_pointer(obj))->slots[0]);
343 static void print_struct(lispobj obj)
345 struct instance *instance = (struct instance *)native_pointer(obj);
346 int i;
347 char buffer[16];
348 print_obj("type: ", ((struct instance *)native_pointer(obj))->slots[0]);
349 for (i = 1; i < HeaderValue(instance->header); i++) {
350 sprintf(buffer, "slot %d: ", i);
351 print_obj(buffer, instance->slots[i]);
355 static void brief_otherptr(lispobj obj)
357 lispobj *ptr, header;
358 int type;
359 struct symbol *symbol;
360 struct vector *vector;
361 char *charptr;
363 ptr = (lispobj *) native_pointer(obj);
365 if (!is_valid_lisp_addr((os_vm_address_t)obj)) {
366 printf("(invalid address)");
367 return;
370 header = *ptr;
371 type = widetag_of(header);
372 switch (type) {
373 case SYMBOL_HEADER_WIDETAG:
374 symbol = (struct symbol *)ptr;
375 vector = (struct vector *)native_pointer(symbol->name);
376 for (charptr = (char *)vector->data; *charptr != '\0'; charptr++) {
377 if (*charptr == '"')
378 putchar('\\');
379 putchar(*charptr);
381 break;
383 case SIMPLE_STRING_WIDETAG:
384 vector = (struct vector *)ptr;
385 putchar('"');
386 for (charptr = (char *)vector->data; *charptr != '\0'; charptr++) {
387 if (*charptr == '"')
388 putchar('\\');
389 putchar(*charptr);
391 putchar('"');
392 break;
394 default:
395 printf("#<ptr to ");
396 brief_otherimm(header);
397 putchar('>');
401 static void print_slots(char **slots, int count, lispobj *ptr)
403 while (count-- > 0) {
404 if (*slots) {
405 print_obj(*slots++, *ptr++);
406 } else {
407 print_obj("???: ", *ptr++);
412 /* FIXME: Yikes again! This, like subtype_Names[], needs to depend
413 * on the values in sbcl.h (or perhaps be generated automatically
414 * by GENESIS as part of sbcl.h). */
415 static char *symbol_slots[] = {"value: ", "unused: ",
416 "plist: ", "name: ", "package: ", NULL};
417 static char *ratio_slots[] = {"numer: ", "denom: ", NULL};
418 static char *complex_slots[] = {"real: ", "imag: ", NULL};
419 static char *code_slots[] = {"words: ", "entry: ", "debug: ", NULL};
420 static char *fn_slots[] = {
421 "self: ", "next: ", "name: ", "arglist: ", "type: ", NULL};
422 static char *closure_slots[] = {"fn: ", NULL};
423 static char *funcallable_instance_slots[] = {"fn: ", "lexenv: ", "layout: ", NULL};
424 static char *weak_pointer_slots[] = {"value: ", NULL};
425 static char *fdefn_slots[] = {"name: ", "function: ", "raw_addr: ", NULL};
426 static char *value_cell_slots[] = {"value: ", NULL};
428 static void print_otherptr(lispobj obj)
430 if (!is_valid_lisp_addr((os_vm_address_t)obj)) {
431 printf("(invalid address)");
432 } else {
433 #ifndef alpha
434 lispobj *ptr;
435 unsigned long header;
436 unsigned long length;
437 #else
438 u32 *ptr;
439 u32 header;
440 u32 length;
441 #endif
442 int count, type, index;
443 char *cptr, buffer[16];
445 ptr = (lispobj*) native_pointer(obj);
446 if (ptr == NULL) {
447 printf(" (NULL Pointer)");
448 return;
451 header = *ptr++;
452 length = (*ptr) >> 2;
453 count = header>>8;
454 type = widetag_of(header);
456 print_obj("header: ", header);
457 if (lowtag_of(header) != OTHER_IMMEDIATE_0_LOWTAG &&
458 lowtag_of(header) != OTHER_IMMEDIATE_1_LOWTAG) {
459 NEWLINE_OR_RETURN;
460 printf("(invalid header object)");
461 return;
464 switch (type) {
465 case BIGNUM_WIDETAG:
466 ptr += count;
467 NEWLINE_OR_RETURN;
468 printf("0x");
469 while (count-- > 0)
470 printf("%08lx", (unsigned long) *--ptr);
471 break;
473 case RATIO_WIDETAG:
474 print_slots(ratio_slots, count, ptr);
475 break;
477 case COMPLEX_WIDETAG:
478 print_slots(complex_slots, count, ptr);
479 break;
481 case SYMBOL_HEADER_WIDETAG:
482 print_slots(symbol_slots, count, ptr);
483 break;
485 case SINGLE_FLOAT_WIDETAG:
486 NEWLINE_OR_RETURN;
487 printf("%g", ((struct single_float *)native_pointer(obj))->value);
488 break;
490 case DOUBLE_FLOAT_WIDETAG:
491 NEWLINE_OR_RETURN;
492 printf("%g", ((struct double_float *)native_pointer(obj))->value);
493 break;
495 #ifdef LONG_FLOAT_WIDETAG
496 case LONG_FLOAT_WIDETAG:
497 NEWLINE_OR_RETURN;
498 printf("%Lg", ((struct long_float *)native_pointer(obj))->value);
499 break;
500 #endif
502 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
503 case COMPLEX_SINGLE_FLOAT_WIDETAG:
504 NEWLINE_OR_RETURN;
505 printf("%g", ((struct complex_single_float *)native_pointer(obj))->real);
506 NEWLINE_OR_RETURN;
507 printf("%g", ((struct complex_single_float *)native_pointer(obj))->imag);
508 break;
509 #endif
511 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
512 case COMPLEX_DOUBLE_FLOAT_WIDETAG:
513 NEWLINE_OR_RETURN;
514 printf("%g", ((struct complex_double_float *)native_pointer(obj))->real);
515 NEWLINE_OR_RETURN;
516 printf("%g", ((struct complex_double_float *)native_pointer(obj))->imag);
517 break;
518 #endif
520 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
521 case COMPLEX_LONG_FLOAT_WIDETAG:
522 NEWLINE_OR_RETURN;
523 printf("%Lg", ((struct complex_long_float *)native_pointer(obj))->real);
524 NEWLINE_OR_RETURN;
525 printf("%Lg", ((struct complex_long_float *)native_pointer(obj))->imag);
526 break;
527 #endif
529 case SIMPLE_STRING_WIDETAG:
530 NEWLINE_OR_RETURN;
531 cptr = (char *)(ptr+1);
532 putchar('"');
533 while (length-- > 0)
534 putchar(*cptr++);
535 putchar('"');
536 break;
538 case SIMPLE_VECTOR_WIDETAG:
539 NEWLINE_OR_RETURN;
540 printf("length = %ld", length);
541 ptr++;
542 index = 0;
543 while (length-- > 0) {
544 sprintf(buffer, "%d: ", index++);
545 print_obj(buffer, *ptr++);
547 break;
549 case INSTANCE_HEADER_WIDETAG:
550 NEWLINE_OR_RETURN;
551 printf("length = %ld", (long) count);
552 index = 0;
553 while (count-- > 0) {
554 sprintf(buffer, "%d: ", index++);
555 print_obj(buffer, *ptr++);
557 break;
559 case SIMPLE_ARRAY_WIDETAG:
560 case SIMPLE_BIT_VECTOR_WIDETAG:
561 case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
562 case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
563 case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
564 case SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG:
565 case SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG:
566 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
567 case SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG:
568 #endif
569 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
570 case SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG:
571 #endif
572 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
573 case SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG:
574 #endif
575 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
576 case SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG:
577 #endif
578 case SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG:
579 case SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG:
580 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
581 case SIMPLE_ARRAY_LONG_FLOAT_WIDETAG:
582 #endif
583 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
584 case SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG:
585 #endif
586 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
587 case SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG:
588 #endif
589 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
590 case SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG:
591 #endif
592 case COMPLEX_STRING_WIDETAG:
593 case COMPLEX_BIT_VECTOR_WIDETAG:
594 case COMPLEX_VECTOR_WIDETAG:
595 case COMPLEX_ARRAY_WIDETAG:
596 break;
598 case CODE_HEADER_WIDETAG:
599 print_slots(code_slots, count-1, ptr);
600 break;
602 case SIMPLE_FUN_HEADER_WIDETAG:
603 case CLOSURE_FUN_HEADER_WIDETAG:
604 print_slots(fn_slots, 5, ptr);
605 break;
607 case RETURN_PC_HEADER_WIDETAG:
608 print_obj("code: ", obj - (count * 4));
609 break;
611 case CLOSURE_HEADER_WIDETAG:
612 print_slots(closure_slots, count, ptr);
613 break;
615 case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
616 print_slots(funcallable_instance_slots, count, ptr);
617 break;
619 case VALUE_CELL_HEADER_WIDETAG:
620 print_slots(value_cell_slots, 1, ptr);
621 break;
623 case SAP_WIDETAG:
624 NEWLINE_OR_RETURN;
625 #ifndef alpha
626 printf("0x%08lx", (unsigned long) *ptr);
627 #else
628 printf("0x%016lx", *(lispobj*)(ptr+1));
629 #endif
630 break;
632 case WEAK_POINTER_WIDETAG:
633 print_slots(weak_pointer_slots, 1, ptr);
634 break;
636 case BASE_CHAR_WIDETAG:
637 case UNBOUND_MARKER_WIDETAG:
638 NEWLINE_OR_RETURN;
639 printf("pointer to an immediate?");
640 break;
642 case FDEFN_WIDETAG:
643 print_slots(fdefn_slots, count, ptr);
644 break;
646 default:
647 NEWLINE_OR_RETURN;
648 printf("Unknown header object?");
649 break;
654 static void print_obj(char *prefix, lispobj obj)
656 static void (*verbose_fns[])(lispobj obj)
657 = {print_fixnum, print_struct, print_otherimm, print_list,
658 print_fixnum, print_otherptr, print_otherimm, print_otherptr};
659 static void (*brief_fns[])(lispobj obj)
660 = {brief_fixnum, brief_struct, brief_otherimm, brief_list,
661 brief_fixnum, brief_otherptr, brief_otherimm, brief_otherptr};
662 int type = lowtag_of(obj);
663 struct var *var = lookup_by_obj(obj);
664 char buffer[256];
665 boolean verbose = cur_depth < brief_depth;
667 if (!continue_p(verbose))
668 return;
670 if (var != NULL && var_clock(var) == cur_clock)
671 dont_descend = 1;
673 if (var == NULL &&
674 /* FIXME: What does this "x & y & z & .." expression mean? */
675 (obj & FUN_POINTER_LOWTAG & LIST_POINTER_LOWTAG & INSTANCE_POINTER_LOWTAG & OTHER_POINTER_LOWTAG) != 0)
676 var = define_var(NULL, obj, 0);
678 if (var != NULL)
679 var_setclock(var, cur_clock);
681 cur_depth++;
682 if (verbose) {
683 if (var != NULL) {
684 sprintf(buffer, "$%s=", var_name(var));
685 newline(buffer);
687 else
688 newline(NULL);
689 printf("%s0x%08lx: ", prefix, (unsigned long) obj);
690 if (cur_depth < brief_depth) {
691 fputs(lowtag_Names[type], stdout);
692 (*verbose_fns[type])(obj);
694 else
695 (*brief_fns[type])(obj);
697 else {
698 if (dont_descend)
699 printf("$%s", var_name(var));
700 else {
701 if (var != NULL)
702 printf("$%s=", var_name(var));
703 (*brief_fns[type])(obj);
706 cur_depth--;
707 dont_descend = 0;
710 void reset_printer()
712 cur_clock++;
713 cur_lines = 0;
714 dont_descend = 0;
717 void print(lispobj obj)
719 skip_newline = 1;
720 cur_depth = 0;
721 max_depth = 5;
722 max_lines = 20;
724 print_obj("", obj);
726 putchar('\n');
729 void brief_print(lispobj obj)
731 skip_newline = 1;
732 cur_depth = 0;
733 max_depth = 1;
734 max_lines = 5000;
736 print_obj("", obj);
737 putchar('\n');
740 #else
742 void
743 brief_print(lispobj obj)
745 printf("lispobj 0x%lx\n", (unsigned long)obj);
748 #endif /* defined(LISP_FEATURE_SB_LDB) */