|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 21001 (0x5209) Types: TextFile Names: »debug.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/gnu-31mar87/scheme/microcode/debug.c«
/* Hey EMACS, this is -*- C -*- code! */ /**************************************************************** * * * Copyright (c) 1984 * * Massachusetts Institute of Technology * * * * This material was developed by the Scheme project at the * * Massachusetts Institute of Technology, Department of * * Electrical Engineering and Computer Science. Permission to * * copy this software, to redistribute it, and to use it for any * * purpose is granted, subject to the following restrictions and * * understandings. * * * * 1. Any copy made of this software must include this copyright * * notice in full. * * * * 2. Users of this software agree to make their best efforts (a)* * to return to the MIT Scheme project any improvements or * * extensions that they make, so that these may be included in * * future releases; and (b) to inform MIT of noteworthy uses of * * this software. * * * * 3. All materials developed as a consequence of the use of * * this software shall duly acknowledge such use, in accordance * * with the usual standards of acknowledging credit in academic * * research. * * * * 4. MIT has made no warrantee or representation that the * * operation of this software will be error-free, and MIT is * * under no obligation to provide any services, by way of * * maintenance, update, or otherwise. * * * * 5. In conjunction with products arising from the use of this * * material, there shall be no use of the name of the * * Massachusetts Institute of Technology nor of any adaptation * * thereof in any advertising, promotional, or sales literature * * without prior written consent from MIT in each case. * * * ****************************************************************/ /* File: DEBUG.C * * Utilities to help with debugging */ #include "scheme.h" #include "primitive.h" \f void Show_Pure() { Pointer *Obj_Address; long Pure_Size, Total_Size, i; Obj_Address = Constant_Space; while (true) { if (Obj_Address > Free_Constant) { printf("Past end of area.\n"); return; } if (Obj_Address == Free_Constant) { printf("Done.\n"); return; } Pure_Size = Get_Integer(*Obj_Address); Total_Size = Get_Integer(Obj_Address[1]); printf("0x%x: pure=0x%x, total=0x%x\n", Obj_Address, Pure_Size, Total_Size); if (Type_Code(*Obj_Address) != TC_MANIFEST_SPECIAL_NM_VECTOR) { printf("Missing initial SNMV.\n"); return; } if (Type_Code(Obj_Address[1]) != PURE_PART) printf("Missing subsequent pure header.\n"); if (Type_Code(Obj_Address[Pure_Size-1]) != TC_MANIFEST_SPECIAL_NM_VECTOR) { printf("Missing internal SNMV.\n"); return; } if (Type_Code(Obj_Address[Pure_Size]) != CONSTANT_PART) { printf("Missing constant header.\n"); return; } if (Get_Integer(Obj_Address[Pure_Size]) != Pure_Size) printf("Pure size mismatch 0x%x.\n", Get_Integer(Obj_Address[Pure_Size])); if (Type_Code(Obj_Address[Total_Size-1]) != TC_MANIFEST_SPECIAL_NM_VECTOR) { printf("Missing ending SNMV.\n"); return; } if (Type_Code(Obj_Address[Total_Size]) != END_OF_BLOCK) { printf("Missing ending header.\n"); return; } if (Get_Integer(Obj_Address[Total_Size]) != Total_Size) printf("Total size mismatch 0x%x.\n", Get_Integer(Obj_Address[Total_Size])); Obj_Address += Total_Size+1; } } \f void Show_Env(Env) Pointer Env; { Pointer *Name_Ptr, *Value_Ptr, Aux_Ptr, Aux_Slot_Ptr; long Count, i; Value_Ptr = Nth_Vector_Loc(Env, HEAP_ENV_FUNCTION); if ((Type_Code(*Value_Ptr) == TC_PROCEDURE) || (Type_Code(*Value_Ptr) == TC_EXTENDED_PROCEDURE)) { Name_Ptr = Nth_Vector_Loc(*Value_Ptr, PROCEDURE_LAMBDA_EXPR); Name_Ptr = Nth_Vector_Loc(*Name_Ptr, LAMBDA_FORMALS); Count = Vector_Length(*Name_Ptr); Name_Ptr = Nth_Vector_Loc(*Name_Ptr, 1); for (i=0; i < Count; i++) { Print_Expression(*Name_Ptr++, "Name "); Print_Expression(*Value_Ptr++, " Value "); printf("\n"); } Aux_Ptr = Vector_Ref(Env, HEAP_ENV_AUX_SLOT); if (Aux_Ptr != NIL) { printf("Auxilliary Variables\n"); while (Aux_Ptr != NIL) { Aux_Slot_Ptr = Vector_Ref(Aux_Ptr, CONS_CAR); Print_Expression(Vector_Ref(Aux_Slot_Ptr, CONS_CAR), "Name "); Print_Expression(Vector_Ref(Aux_Slot_Ptr, CONS_CAR), " Value "); Aux_Ptr = Vector_Ref(Aux_Ptr, CONS_CDR); printf("\n"); } } } else printf("Not created by a procedure"); } \f /* For debugging, given a String, return either a "not interned" * message or the address of the symbol and its global value. */ void Find_Symbol(Scheme_String) Pointer Scheme_String; { Pointer Ob_Array, The_Symbol, *Bucket; char *Ptr, *String; long i, Hashed_Value; String = Scheme_String_To_C_String(Scheme_String); Hashed_Value = Do_Hash(String, i); Ob_Array = Get_Fixed_Obj_Slot(OBArray); Hashed_Value %= Vector_Length(Ob_Array); Bucket = Nth_Vector_Loc(Ob_Array, Hashed_Value); while (*Bucket != NIL) { if (String_Equal(Scheme_String, Vector_Ref(Vector_Ref(*Bucket, CONS_CAR), SYMBOL_NAME))) { The_Symbol = Vector_Ref(*Bucket, CONS_CAR); printf("\nInterned Symbol: 0x%x", The_Symbol); Print_Expression(Vector_Ref(The_Symbol, SYMBOL_GLOBAL_VALUE), "Value"); printf("\n"); return; } Bucket = Nth_Vector_Loc(*Bucket, CONS_CDR); } printf("\nNot interned.\n"); } \f List_Print(Expr) Pointer Expr; { int Count; Count = 0; printf("("); while (Type_Code(Expr) == TC_LIST && Count < MAX_LIST_PRINT) { Print_Expression(Vector_Ref(Expr, CONS_CAR), ""); Expr = Vector_Ref(Expr, CONS_CDR); if (Type_Code(Expr) != TC_NULL) printf(" "); Count += 1; } if (Type_Code(Expr) != TC_NULL) { if (Count==MAX_LIST_PRINT) printf("..."); else { printf(". "); Print_Expression(Expr, ""); } } printf(")"); } \f long Print_Return_Name(Ptr) Pointer Ptr; { long index = Get_Integer(Ptr); char *name; if ((index <= MAX_RETURN) && ((name = Return_Names[index]) != ((char *) NULL))) printf("%s", name); else printf("[0x%x]", index); } void Print_Return(String) char *String; { printf("%s: ", String); Print_Return_Name(Fetch_Return()); CRLF(); } \f extern Boolean Prt_PName(); void Print_Expression(Expr, String) char *String; Pointer Expr; { if (String[0] != 0) printf("%s: ", String); Do_Printing(Expr, true); } Do_Printing(Expr, Detailed) Pointer Expr; Boolean Detailed; { long Temp_Address; Boolean Return_After_Print; Temp_Address = Get_Integer(Expr); Return_After_Print = false; if (Type_Code(Expr) > MAX_SAFE_TYPE) printf("{Dangerous}"); switch(Safe_Type_Code(Expr)) { case TC_ACCESS: printf("[ACCESS ("); Expr = Vector_Ref(Expr, ACCESS_NAME); goto SPrint; case TC_ASSIGNMENT: printf("[SET! ("); Expr = Vector_Ref(Vector_Ref(Expr, ASSIGN_NAME), VARIABLE_SYMBOL); goto SPrint; case TC_CHARACTER_STRING: { long Length, i; char *Next, This; printf("\""); Length = Get_Integer(Vector_Ref(Expr, STRING_LENGTH)); Next = (char *) Nth_Vector_Loc(Expr, STRING_CHARS); for (i=0; i < Length; i++) { This = *Next++; printf((This < ' ') || (This > '|') ? "\\%03o" : "%c", This); } printf("\""); return; } /* Do_Printing continues on the next page */ \f /* Do_Printing, continued */ case TC_DEFINITION: printf("[DEFINE ("); Expr = Vector_Ref(Expr, DEFINE_NAME); goto SPrint; case TC_FIXNUM: { long A; Sign_Extend(Expr, A); printf("%d", A); return; } case TC_BIG_FLONUM: printf( "%f", Get_Float(Expr)); return; case TC_LIST: List_Print(Expr); return; case TC_NULL: if (Temp_Address==0) { printf("()"); return; } printf("[NULL"); break; /* Do_Printing continues on the next page */ \f /* Do_Printing, continued */ case TC_UNINTERNED_SYMBOL: printf("[UNINTERNED_SYMBOL ("); goto SPrint; case TC_INTERNED_SYMBOL: { Pointer Name; char *Next_Char; long Length, i; Return_After_Print = true; SPrint: Name = Vector_Ref(Expr, SYMBOL_NAME); Length = Get_Integer(Vector_Ref(Name, STRING_LENGTH)); Next_Char = (char *) Nth_Vector_Loc(Name, STRING_CHARS); for (i=0; i < Length; i++) printf("%c", *Next_Char++); if (Return_After_Print) return; printf(")"); break; } /* Do_Printing continues on the next page */ \f /* Do_Printing, continued */ case TC_VARIABLE: if (Detailed) printf("[VARIABLE ("); Expr = Vector_Ref(Expr, VARIABLE_SYMBOL); if (!Detailed) Return_After_Print = true; goto SPrint; case TC_BIG_FIXNUM: printf("[BIG_FIXNUM"); break; case TC_BROKEN_HEART: printf("[BROKEN_HEART"); break; #if (TC_CHARACTER != TC_FIXNUM) case TC_CHARACTER: printf("[CHARACTER"); break; #endif case TC_COMBINATION: printf("[COMBINATION (%d args) 0x%x]", Vector_Length(Expr)-1, Temp_Address); if (Detailed) { printf(" ("); Do_Printing(Vector_Ref(Expr, COMB_FN_SLOT), false); printf(" ...)"); } return; case TC_COMBINATION_1: printf("[COMBINATION_1 0x%x]", Temp_Address); if (Detailed) { printf(" ("); Do_Printing(Vector_Ref(Expr, COMB_1_FN), false); printf(", "); Do_Printing(Vector_Ref(Expr, COMB_1_ARG_1), false); printf(")"); } return; /* Do_Printing continues on the next page */ \f /* Do_Printing, continued */ case TC_COMBINATION_2: printf("[COMBINATION_2 0x%x]", Temp_Address); if (Detailed) { printf(" ("); Do_Printing(Vector_Ref(Expr, COMB_2_FN), false); printf(", "); Do_Printing(Vector_Ref(Expr, COMB_2_ARG_1), false); printf(", "); Do_Printing(Vector_Ref(Expr, COMB_2_ARG_2), false); printf(")"); } return; case TC_COMMENT: printf("[COMMENT"); break; case TC_COMPILED_EXPRESSION: printf("[COMPILED_EXPRESSION"); break; case TC_COMPILED_PROCEDURE: printf("[COMPILED_PROCEDURE"); break; case TC_CONDITIONAL: printf("[CONDITIONAL"); break; case TC_CONTROL_POINT: printf("[CONTROL_POINT"); break; case TC_DELAY: printf("[DELAY"); break; case TC_DELAYED: printf("[DELAYED"); break; case TC_DISJUNCTION: printf("[DISJUNCTION"); break; case TC_ENVIRONMENT: printf("[ENVIRONMENT 0x%x]", Temp_Address); printf(" (from "); Do_Printing(Vector_Ref(Expr, HEAP_ENV_FUNCTION), false); printf(")"); return; case TC_EXTENDED_FIXNUM: printf("[EXTENDED_FIXNUM"); break; case TC_EXTENDED_LAMBDA: if (Detailed) printf("[EXTENDED_LAMBDA ("); Do_Printing( Vector_Ref( Vector_Ref(Expr, ELAMBDA_NAMES), 1), false); if (Detailed) printf(") 0x%x", Temp_Address); return; case TC_EXTENDED_PROCEDURE: if (Detailed) printf("[EXTENDED_PROCEDURE ("); Do_Printing(Vector_Ref(Expr, PROCEDURE_LAMBDA_EXPR), false); if (Detailed) printf(") 0x%x]", Temp_Address); break; /* Do_Printing continues on the next page */ \f /* Do_Printing, continued */ case TC_FUTURE: printf("[FUTURE"); break; case TC_HUNK3: printf("[HUNK3"); break; case TC_IN_PACKAGE: printf("[IN_PACKAGE"); break; case TC_LAMBDA: if (Detailed) printf("[LAMBDA ("); Do_Printing( Vector_Ref( Vector_Ref(Expr, LAMBDA_FORMALS), 1), false); if (Detailed) printf(") 0x%x]", Temp_Address); return; case TC_LEXPR: printf("[LEXPR"); break; case TC_MANIFEST_NM_VECTOR: printf("[MANIFEST_NM_VECTOR"); break; case TC_MANIFEST_SPECIAL_NM_VECTOR: printf("[MANIFEST_SPECIAL_NM_VECTOR"); break; case TC_NON_MARKED_VECTOR: printf("[NON_MARKED_VECTOR"); break; case TC_PCOMB0: printf("[PCOMB0"); break; case TC_PCOMB1: printf("[PCOMB1"); break; case TC_PCOMB2: printf("[PCOMB2"); break; case TC_PCOMB3: printf("[PCOMB3"); break; case TC_PRIMITIVE: printf("[PRIMITIVE "); Prt_PName(Temp_Address); printf("]"); return; case TC_PRIMITIVE_EXTERNAL: printf("[PRIMITIVE_EXTERNAL"); break; case TC_PROCEDURE: if (Detailed) printf("[PROCEDURE ("); Do_Printing(Vector_Ref(Expr, PROCEDURE_LAMBDA_EXPR), false); if (Detailed) printf(") 0x%x]", Temp_Address); return; /* Do_Printing continues on the next page */ \f /* Do_Printing, continued */ case TC_RETURN_CODE: printf("[RETURN_CODE "); Print_Return_Name(Expr); printf("]"); return; case TC_SCODE_QUOTE: printf("[SCODE_QUOTE"); break; case TC_SEQUENCE_2: printf("[SEQUENCE_2"); break; case TC_SEQUENCE_3: printf("[SEQUENCE_3"); break; case TC_THE_ENVIRONMENT: printf("[THE_ENVIRONMENT"); break; case TC_TRUE: if (Temp_Address == 0) { printf("#!true"); return; } printf("[TRUE"); break; case TC_UNASSIGNED: if (Temp_Address == UNBOUND) { printf("#!UNBOUND"); return; } else if (Temp_Address == UNASSIGNED) { printf("#!UNASSIGNED"); return; } else printf("[UNASSIGNED"); break; case TC_VECTOR: printf("[VECTOR"); break; case TC_VECTOR_16B: printf("[VECTOR_16B"); break; case TC_VECTOR_1B: printf("[VECTOR_1B"); break; default: printf("[0x%x", Type_Code(Expr)); } printf(" 0x%x]", Temp_Address); } \f /* Back_Trace relies on (a) only a call to Save_Cont puts a return code on the stack; (b) Save_Cont pushes the expression first. */ Boolean Print_One_Continuation_Frame(Temp) Pointer Temp; { Pointer Expr; Print_Expression(Temp, "Return code"); CRLF(); Expr = Pop(); Print_Expression(Expr, "Expression"); printf("\n"); if (Address(Temp) == RC_END_OF_COMPUTATION) return true; if (Address(Temp) == RC_RESTORE_CONTROL_POINT) Stack_Pointer = Get_Pointer(Expr) + 1 + 2 + REGBLOCK_NDISPLAYS; return false; } void Back_Trace() { Pointer Temp, *Old_Stack; Back_Trace_Entry_Hook(); Old_Stack = Stack_Pointer; while (Stack_Pointer < Stack_Top) { if (Return_Hook_Address == &Top_Of_Stack()) { Temp = Pop(); if (Temp != Make_Non_Pointer(TC_RETURN_CODE, RC_RETURN_TRAP_POINT)) printf("\n--> Return trap is missing here <--\n"); else { printf("\n[Return trap found here as expected]\n"); Temp = Old_Return_Code; } } else Temp = Pop(); if (Type_Code(Temp) == TC_RETURN_CODE) { if (Print_One_Continuation_Frame(Temp)) break; } else { Print_Expression(Temp, " ..."); if (Safe_Type_Code(Temp) == TC_MANIFEST_NM_VECTOR) { Stack_Pointer += Get_Integer(Temp); printf(" (skipping)"); } printf("\n"); } } Stack_Pointer = Old_Stack; Back_Trace_Exit_Hook(); } \f Boolean Prt_PName(Number) long Number; { if ((Number < 0) || (Number > MAX_PRIMITIVE) || (Primitive_Names[Number] == NULL)) { printf("Unknown primitive 0x%08x", Number); return false; } else { printf("%s", Primitive_Names[Number]); return true; } } void Print_Primitive(Number) long Number; { char NArgs; printf("Primitive: "); if (Prt_PName(Number)) NArgs = Arg_Count_Table[Number]; else NArgs = 3; /* Unknown primitive */ printf("\n"); if (NArgs > 0) { Print_Expression(Stack_Pointer[0], "...Arg 1"); printf("\n"); } if (NArgs > 1) { Print_Expression(Stack_Pointer[1], "...Arg 2"); printf("\n"); } if (NArgs > 2) { Print_Expression(Stack_Pointer[2], "...Arg 3"); printf("\n"); } } \f Debug_Printer(Expr) Pointer Expr; { Print_Expression(Expr, ""); putchar('\n'); } /* (TEMP_PRINTER OBJECT) [Primitive number 0xB2] A cheap, built-in printer intended for debugging the interpreter. */ Built_In_Primitive(Prim_Temp_Printer, 1, "TEMP-PRINTER") { Primitive_1_Arg(); Debug_Printer(Arg1); return TRUTH; } \f /* Code for interactively setting and clearing the interpreter debugging flags. Invoked via the "D" command to the ^B handler or during each FASLOAD. */ #ifdef ENABLE_DEBUGGING_TOOLS #define D_EVAL 0 #define D_HEX_INPUT 1 #define D_FILE_LOAD 2 #define D_RELOC 3 #define D_INTERN 4 #define D_CONT 5 #define D_PRIMITIVE 6 #define D_LOOKUP 7 #define D_DEFINE 8 #define D_GC 9 #define D_UPGRADE 10 #define D_DUMP 11 #define D_TRACE_ON_ERROR 12 #define D_PER_FILE 13 #define D_BIGNUM 14 #define LAST_NORMAL_SWITCH 14 Boolean *Find_Flag(Num) int Num; { switch (Num) { case D_EVAL: return &Eval_Debug; case D_HEX_INPUT: return &Hex_Input_Debug; case D_FILE_LOAD: return &File_Load_Debug; case D_RELOC: return &Reloc_Debug; case D_INTERN: return &Intern_Debug; case D_CONT: return &Cont_Debug; case D_PRIMITIVE: return &Primitive_Debug; case D_LOOKUP: return &Lookup_Debug ; case D_DEFINE: return &Define_Debug; case D_GC: return &GC_Debug; case D_UPGRADE: return &Upgrade_Debug; case D_DUMP: return &Dump_Debug; case D_TRACE_ON_ERROR: return &Trace_On_Error; case D_PER_FILE: return &Per_File; case D_BIGNUM: return &Bignum_Debug; More_Debug_Flag_Cases(); default: show_flags(true); return NULL; } } \f set_flag(Num, Value) int Num; Boolean Value; { Boolean *Flag = Find_Flag(Num); if (Flag != NULL) *Flag = Value; Set_Flag_Hook(); } char *Flag_Name(Num) int Num; { switch(Num) { case D_EVAL: return "Eval_Debug"; case D_HEX_INPUT: return "Hex_Input_Debug"; case D_FILE_LOAD: return "File_Load_Debug"; case D_RELOC: return "Reloc_Debug"; case D_INTERN: return "Intern_Debug"; case D_CONT: return "Cont_Debug"; case D_PRIMITIVE: return "Primitive_Debug"; case D_LOOKUP: return "Lookup_Debug"; case D_DEFINE: return "Define_Debug"; case D_GC: return "GC_Debug"; case D_UPGRADE: return "Upgrade_Debug"; case D_DUMP: return "Dump_Debug"; case D_TRACE_ON_ERROR: return "Trace_On_Error"; case D_PER_FILE: return "Per_File"; case D_BIGNUM: return "Bignum_Debug"; More_Debug_Flag_Names(); default: return "Unknown Debug Flag"; } } \f show_flags(All) Boolean All; { int i; for (i=0; i <= LAST_SWITCH; i++) { Boolean Value = *Find_Flag(i); if (All || Value) { printf("Flag %d (%s) is %s.\n", i, Flag_Name(i), Value? "set" : "clear"); } } } extern char OS_tty_tyi(); #define C_STRING_LENGTH 256 \f void Handle_Debug_Flags() { char c, input_string[C_STRING_LENGTH]; int Which, free; Boolean interrupted; show_flags(false); while (true) { interrupted = false; printf("Clear<number>, Set<number>, Done, ?, or Halt: "); OS_Flush_Output_Buffer(); /* Considerably haired up to go through standard (safe) interface */ c = OS_tty_tyi(false, &interrupted); if (interrupted) return; for (free = 0; free < C_STRING_LENGTH; free++) { input_string[free] = OS_tty_tyi(false, &interrupted); if (interrupted) return; if (input_string[free] == '\n') { input_string[free] = '\0'; break; } } /* Handle_Debug_Flags continues on the next page */ \f /* Handle_Debug_Flags, continued */ switch (c) { case 'c': case 'C': Which=debug_getdec(input_string); set_flag(Which, false); break; case 's': case 'S': Which=debug_getdec(input_string); set_flag(Which, true); break; case 'd': case 'D': return; case 'h': case 'H': Microcode_Termination(TERM_HALT); case '?': default : show_flags(true); break; } } } int normal_debug_getdec(str) { int Result; sscanf(str, "%d", &Result); return Result; } #else /* ENABLE_DEBUGGING_TOOLS */ void Handle_Debug_Flags() { fprintf(stderr, "Not a debugging version. No flags to handle.\n"); return; } #endif /* not ENABLE_DEBUGGING_TOOLS */