X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fmonitor.c;h=30f9fc74f427be8ebf7b9452e71cd00c16aefdef;hb=f0cb0cf9c0fe1b6fce5d10dbd34a0b7b249c4ae8;hp=cbd92872a5073b4632214666d022512f58fe7f8a;hpb=6cbe4d8ba6d7bc469d03a72514c789b1f3944878;p=sbcl.git diff --git a/src/runtime/monitor.c b/src/runtime/monitor.c index cbd9287..30f9fc7 100644 --- a/src/runtime/monitor.c +++ b/src/runtime/monitor.c @@ -9,30 +9,40 @@ * files for more information. */ +#include "sbcl.h" + #include #include #include #include #include +#ifndef LISP_FEATURE_WIN32 #include +#endif #include #include #include "runtime.h" -#include "sbcl.h" -#include "globals.h" -#include "vars.h" #include "parse.h" -#include "os.h" -#include "interrupt.h" -#include "lispregs.h" -#include "monitor.h" +#include "vars.h" + +/* Almost all of this file can be skipped if we're not supporting LDB. */ +#if defined(LISP_FEATURE_SB_LDB) + #include "print.h" #include "arch.h" #include "interr.h" #include "gc.h" #include "search.h" #include "purify.h" +#include "globals.h" +#include "lispregs.h" +#include "interrupt.h" +#include "thread.h" +#include "genesis/static-symbols.h" +#include "genesis/primitive-objects.h" + + /* When we need to do command input, we use this stream, which is not * in general stdin, so that things will "work" (as well as being @@ -41,7 +51,7 @@ * * (We could set up output to go to a special ldb_out stream for the * same reason, but there's been no pressure for that so far.) - * + * * The enter-the-ldb-monitor function is responsible for setting up * this stream. */ static FILE *ldb_in = 0; @@ -49,7 +59,7 @@ static int ldb_in_fd = -1; typedef void cmd(char **ptr); -static cmd call_cmd, dump_cmd, print_cmd, quit_cmd, help_cmd; +static cmd dump_cmd, print_cmd, quit_cmd, help_cmd; static cmd flush_cmd, search_cmd, regs_cmd, exit_cmd; static cmd print_context_cmd; static cmd backtrace_cmd, purify_cmd, catchers_cmd; @@ -63,7 +73,6 @@ static struct cmd { {"help", "Display this help information.", help_cmd}, {"?", "(an alias for help)", help_cmd}, {"backtrace", "Backtrace up to N frames.", backtrace_cmd}, - {"call", "Call FUNCTION with ARG1, ARG2, ...", call_cmd}, {"catchers", "Print a list of all the active catchers.", catchers_cmd}, {"context", "Print interrupt context number I.", print_context_cmd}, {"dump", "Dump memory starting at ADDRESS for COUNT words.", dump_cmd}, @@ -128,13 +137,13 @@ dump_cmd(char **ptr) } while (count-- > 0) { -#ifndef alpha - printf("0x%08lX: ", (unsigned long) addr); +#ifndef LISP_FEATURE_ALPHA + printf("0x%p: ", (os_vm_address_t) addr); #else printf("0x%08X: ", (u32) addr); #endif if (is_valid_lisp_addr((os_vm_address_t)addr)) { -#ifndef alpha +#ifndef LISP_FEATURE_ALPHA unsigned long *lptr = (unsigned long *)addr; #else u32 *lptr = (u32 *)addr; @@ -142,7 +151,14 @@ dump_cmd(char **ptr) unsigned short *sptr = (unsigned short *)addr; unsigned char *cptr = (unsigned char *)addr; - printf("0x%08lx 0x%04x 0x%04x 0x%02x 0x%02x 0x%02x 0x%02x %c%c%c%c\n", lptr[0], sptr[0], sptr[1], cptr[0], cptr[1], cptr[2], cptr[3], visible(cptr[0]), visible(cptr[1]), visible(cptr[2]), visible(cptr[3])); + printf("0x%08lx 0x%04x 0x%04x " + "0x%02x 0x%02x 0x%02x 0x%02x " + "%c%c" + "%c%c\n", + lptr[0], sptr[0], sptr[1], + cptr[0], cptr[1], cptr[2], cptr[3], + visible(cptr[0]), visible(cptr[1]), + visible(cptr[2]), visible(cptr[3])); } else printf("invalid Lisp-level address\n"); @@ -164,40 +180,48 @@ print_cmd(char **ptr) static void kill_cmd(char **ptr) { +#ifndef LISP_FEATURE_WIN32 kill(getpid(), parse_number(ptr)); +#endif } static void regs_cmd(char **ptr) { - printf("CSP\t=\t0x%08lX\n", (unsigned long)current_control_stack_pointer); - printf("FP\t=\t0x%08lX\n", (unsigned long)current_control_frame_pointer); -#if !defined(__i386__) - printf("BSP\t=\t0x%08X\n", (unsigned long)current_binding_stack_pointer); + struct thread *thread=arch_os_get_current_thread(); + + printf("CSP\t=\t0x%p ", access_control_stack_pointer(thread)); +#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) + printf("CFP\t=\t0x%p ", access_control_frame_pointer(thread)); #endif -#ifdef __i386__ - printf("BSP\t=\t0x%08lx\n", - (unsigned long)SymbolValue(BINDING_STACK_POINTER)); + +#ifdef reg_BSP + printf("BSP\t=\t0x%p\n", get_binding_stack_pointer(thread)); +#else + /* printf("BSP\t=\t0x%08lx\n", + (unsigned long)SymbolValue(BINDING_STACK_POINTER)); */ + printf("\n"); #endif - printf("DYNAMIC\t=\t0x%08lx\n", (unsigned long)DYNAMIC_SPACE_START); -#if defined(__i386__) - printf("ALLOC\t=\t0x%08lx\n", - (unsigned long)SymbolValue(ALLOCATION_POINTER)); - printf("TRIGGER\t=\t0x%08lx\n", - (unsigned long)SymbolValue(INTERNAL_GC_TRIGGER)); +#ifdef LISP_FEATURE_GENCGC + /* printf("DYNAMIC\t=\t0x%08lx\n", DYNAMIC_SPACE_START); */ #else - printf("ALLOC\t=\t0x%08X\n", - (unsigned long)dynamic_space_free_pointer); - printf("TRIGGER\t=\t0x%08lx\n", (unsigned long)current_auto_gc_trigger); + printf("STATIC\t=\t0x%p ", + SymbolValue(STATIC_SPACE_FREE_POINTER, thread)); + printf("RDONLY\t=\t0x%08lx ", + (unsigned long)SymbolValue(READ_ONLY_SPACE_FREE_POINTER, thread)); + printf("DYNAMIC\t=\t0x%08lx\n", (unsigned long)current_dynamic_space); +#endif + +#ifdef reg_ALLOC + printf("ALLOC\t=\t0x%08lx\n", (unsigned long)dynamic_space_free_pointer); +#else + printf("ALLOC\t=\t0x%08lx\n", + (unsigned long)SymbolValue(ALLOCATION_POINTER, thread)); #endif - printf("STATIC\t=\t0x%08lx\n", - (unsigned long)SymbolValue(STATIC_SPACE_FREE_POINTER)); - printf("RDONLY\t=\t0x%08lx\n", - (unsigned long)SymbolValue(READ_ONLY_SPACE_FREE_POINTER)); -#ifdef MIPS - printf("FLAGS\t=\t0x%08x\n", current_flags_register); +#ifndef LISP_FEATURE_GENCGC + printf("TRIGGER\t=\t0x%08lx\n", (unsigned long)current_auto_gc_trigger); #endif } @@ -216,7 +240,7 @@ search_cmd(char **ptr) return; } if (more_p(ptr)) { - addr = (lispobj *)PTR((long)parse_addr(ptr)); + addr = (lispobj *)native_pointer((uword_t)parse_addr(ptr)); if (more_p(ptr)) { count = parse_number(ptr); } @@ -242,95 +266,29 @@ search_cmd(char **ptr) start = end = addr; lastcount = count; - printf("searching for 0x%x at 0x%08lX\n", val, (unsigned long)end); + printf("searching for 0x%x at 0x%p\n", val, (void*)(uword_t)end); while (search_for_type(val, &end, &count)) { - printf("found 0x%x at 0x%08lX:\n", val, (unsigned long)end); + printf("found 0x%x at 0x%p:\n", val, (void*)(uword_t)end); obj = *end; addr = end; end += 2; - if (TypeOf(obj) == type_FunctionHeader) - print((long)addr | type_FunctionPointer); - else if (LowtagOf(obj) == type_OtherImmediate0 || LowtagOf(obj) == type_OtherImmediate1) - print((lispobj)addr | type_OtherPointer); - else + if (widetag_of(obj) == SIMPLE_FUN_HEADER_WIDETAG) { + print((uword_t)addr | FUN_POINTER_LOWTAG); + } else if (other_immediate_lowtag_p(obj)) { + print((lispobj)addr | OTHER_POINTER_LOWTAG); + } else { print((lispobj)addr); - if (count == -1) + } if (count == -1) { return; + } } } -static void -call_cmd(char **ptr) -{ - lispobj thing = parse_lispobj(ptr), function, result = 0, cons, args[3]; - int numargs; - - if (LowtagOf(thing) == type_OtherPointer) { - switch (TypeOf(*(lispobj *)(thing-type_OtherPointer))) { - case type_SymbolHeader: - for (cons = SymbolValue(INITIAL_FDEFN_OBJECTS); - cons != NIL; - cons = CONS(cons)->cdr) { - if (FDEFN(CONS(cons)->car)->name == thing) { - thing = CONS(cons)->car; - goto fdefn; - } - } - printf("Symbol 0x%08lx is undefined.\n", (long unsigned)thing); - return; - - case type_Fdefn: - fdefn: - function = FDEFN(thing)->function; - if (function == NIL) { - printf("Fdefn 0x%08lx is undefined.\n", (long unsigned)thing); - return; - } - break; - default: - printf("0x%08lx is not a function pointer, symbol, " - "or fdefn object.\n", - (long unsigned)thing); - return; - } - } - else if (LowtagOf(thing) != type_FunctionPointer) { - printf("0x%08lx is not a function pointer, symbol, or fdefn object.\n", - (long unsigned)thing); - return; - } - else - function = thing; - - numargs = 0; - while (more_p(ptr)) { - if (numargs >= 3) { - printf("too many arguments (no more than 3 supported)\n"); - return; - } - args[numargs++] = parse_lispobj(ptr); - } - - switch (numargs) { - case 0: - result = funcall0(function); - break; - case 1: - result = funcall1(function, args[0]); - break; - case 2: - result = funcall2(function, args[0], args[1]); - break; - case 3: - result = funcall3(function, args[0], args[1], args[2]); - break; - default: - lose("unsupported arg count made it past validity check?!"); - } - - print(result); -} +/* (There used to be call_cmd() here, to call known-at-cold-init-time + * Lisp functions from ldb, but it bitrotted and was deleted in + * sbcl-0.7.5.1. See older CVS versions if you want to resuscitate + * it.) */ static void flush_cmd(char **ptr) @@ -345,9 +303,13 @@ quit_cmd(char **ptr) printf("Really quit? [y] "); fflush(stdout); - fgets(buf, sizeof(buf), ldb_in); - if (buf[0] == 'y' || buf[0] == 'Y' || buf[0] == '\n') - exit(0); + if (fgets(buf, sizeof(buf), ldb_in)) { + if (buf[0] == 'y' || buf[0] == 'Y' || buf[0] == '\n') + exit(1); + } else { + printf("\nUnable to read response, assuming y.\n"); + exit(1); + } } static void @@ -377,92 +339,96 @@ purify_cmd(char **ptr) static void print_context(os_context_t *context) { - int i; + int i; - for (i = 0; i < NREGS; i++) { - printf("%s:\t", lisp_register_names[i]); -#ifdef __i386__ - brief_print((lispobj)(*os_context_register_addr(context, - i*2))); + for (i = 0; i < NREGS; i++) { + printf("%s:\t", lisp_register_names[i]); +#ifdef LISP_FEATURE_X86 + brief_print((lispobj)(*os_context_register_addr(context, + i*2))); #else - brief_print((lispobj)(*os_context_register_addr(context,i))); + brief_print((lispobj)(*os_context_register_addr(context,i))); +#endif + } +#ifdef LISP_FEATURE_DARWIN + printf("DAR:\t\t 0x%08lx\n", (unsigned long)(*os_context_register_addr(context, 41))); + printf("DSISR:\t\t 0x%08lx\n", (unsigned long)(*os_context_register_addr(context, 42))); #endif - } - printf("PC:\t\t 0x%08lx\n", - (unsigned long)(*os_context_pc_addr(context))); + printf("PC:\t\t 0x%08lx\n", + (unsigned long)(*os_context_pc_addr(context))); } static void print_context_cmd(char **ptr) { - int free; + int free_ici; + struct thread *thread=arch_os_get_current_thread(); - free = SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX)>>2; - - if (more_p(ptr)) { - int index; - - index = parse_number(ptr); - - if ((index >= 0) && (index < free)) { - printf("There are %d interrupt contexts.\n", free); - printf("printing context %d\n", index); - print_context(lisp_interrupt_contexts[index]); - } else { - printf("There aren't that many/few contexts.\n"); - printf("There are %d interrupt contexts.\n", free); - } - } else { - if (free == 0) - printf("There are no interrupt contexts!\n"); - else { - printf("There are %d interrupt contexts.\n", free); - printf("printing context %d\n", free - 1); - print_context(lisp_interrupt_contexts[free - 1]); - } - } + free_ici = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,thread)); + + if (more_p(ptr)) { + int index; + + index = parse_number(ptr); + + if ((index >= 0) && (index < free_ici)) { + printf("There are %d interrupt contexts.\n", free_ici); + printf("printing context %d\n", index); + print_context(thread->interrupt_contexts[index]); + } else { + printf("There aren't that many/few contexts.\n"); + printf("There are %d interrupt contexts.\n", free_ici); + } + } else { + if (free_ici == 0) + printf("There are no interrupt contexts!\n"); + else { + printf("There are %d interrupt contexts.\n", free_ici); + printf("printing context %d\n", free_ici - 1); + print_context(thread->interrupt_contexts[free_ici - 1]); + } + } } static void backtrace_cmd(char **ptr) { - void backtrace(int frames); + void lisp_backtrace(int frames); int n; if (more_p(ptr)) - n = parse_number(ptr); + n = parse_number(ptr); else - n = 100; + n = 100; printf("Backtrace:\n"); - backtrace(n); + lisp_backtrace(n); } static void catchers_cmd(char **ptr) { struct catch_block *catch; + struct thread *thread=arch_os_get_current_thread(); - catch = (struct catch_block *)SymbolValue(CURRENT_CATCH_BLOCK); + catch = (struct catch_block *)SymbolValue(CURRENT_CATCH_BLOCK,thread); if (catch == NULL) printf("There are no active catchers!\n"); else { while (catch != NULL) { -#ifndef __i386__ - printf("0x%08lX:\n\tuwp: 0x%08lX\n\tfp: 0x%08lX\n\tcode: 0x%08lx\n\tentry: 0x%08lx\n\ttag: ", - (unsigned long)catch, (unsigned long)(catch->current_uwp), - (unsigned long)(catch->current_cont), - catch->current_code, - catch->entry_pc); + printf("0x%08lX:\n\tuwp: 0x%08lX\n\tfp: 0x%08lX\n\t" + "code: 0x%08lX\n\tentry: 0x%08lX\n\ttag: ", + (uword_t)catch, + (uword_t)(catch->current_uwp), + (uword_t)(catch->current_cont), +#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) + (uword_t)component_ptr_from_pc((void*)catch->entry_pc) + + OTHER_POINTER_LOWTAG, #else - printf("0x%08lX:\n\tuwp: 0x%08lX\n\tfp: 0x%08lX\n\tcode: 0x%08lx\n\tentry: 0x%08lx\n\ttag: ", - (unsigned long)catch, (unsigned long)(catch->current_uwp), - (unsigned long)(catch->current_cont), - (unsigned long)component_ptr_from_pc((void*)catch->entry_pc) + - type_OtherPointer, - (unsigned long)catch->entry_pc); + (uword_t)(catch->current_code), #endif + (uword_t)(catch->entry_pc)); brief_print((lispobj)catch->tag); catch = catch->previous_catch; } @@ -487,8 +453,16 @@ sub_monitor(void) int ambig; if (!ldb_in) { - ldb_in = fopen("/dev/tty","r+"); - ldb_in_fd = fileno(ldb_in); +#ifndef LISP_FEATURE_WIN32 + ldb_in = fopen("/dev/tty","r+"); + if (ldb_in == NULL) { + perror("Error opening /dev/tty"); + ldb_in = stdin; + } +#else + ldb_in = stdin; +#endif + ldb_in_fd = fileno(ldb_in); } while (!done) { @@ -496,15 +470,8 @@ sub_monitor(void) fflush(stdout); line = fgets(buf, sizeof(buf), ldb_in); if (line == NULL) { - if (isatty(ldb_in_fd)) { - putchar('\n'); - continue; - } - else { - fprintf(stderr, "\nEOF on something other than a tty.\n"); - exit(0); - } - } + exit(1); + } ptr = line; if ((token = parse_token(&ptr)) == NULL) continue; @@ -541,7 +508,7 @@ ldb_monitor() bcopy(curbuf, oldbuf, sizeof(oldbuf)); - printf("LDB monitor\n"); + printf("Welcome to LDB, a low-level debugger for the Lisp runtime environment.\n"); setjmp(curbuf); @@ -557,3 +524,21 @@ throw_to_monitor() { longjmp(curbuf, 1); } + +#endif /* defined(LISP_FEATURE_SB_LDB) */ + +/* what we do when things go badly wrong at a low level */ +void +monitor_or_something() +{ +#if defined(LISP_FEATURE_SB_LDB) + ldb_monitor(); +#else + fprintf(stderr, +"The system is too badly corrupted or confused to continue at the Lisp\n\ +level. If the system had been compiled with the SB-LDB feature, we'd drop\n\ +into the LDB low-level debugger now. But there's no LDB in this build, so\n\ +we can't really do anything but just exit, sorry.\n"); + exit(1); +#endif +}