When in the kernel debugger we do now record the relevant information

(fault address, pc, read/write) when a page fault occurs, and print them
in case this caused the termination of a debugger command.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26949 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2008-08-12 17:09:42 +00:00
parent 3b99126c1e
commit 46ec230162
4 changed files with 69 additions and 24 deletions

View File

@ -16,8 +16,8 @@
#define KDEBUG 1
#if DEBUG
/*
* The kernel debug level.
/*
* The kernel debug level.
* Level 1 is usual asserts, > 1 should be used for very expensive runtime checks
*/
# define KDEBUG 1
@ -37,7 +37,7 @@
#if KDEBUG
# define ASSERT(x) ASSERT_ALWAYS(x)
# define ASSERT_PRINT(x, format...) ASSERT_ALWAYS_PRINT(x, format)
#else
#else
# define ASSERT(x) do { } while(0)
# define ASSERT_PRINT(x, format...) do { } while(0)
#endif
@ -69,6 +69,18 @@ struct debugger_module_info {
extern int dbg_register_file[B_MAX_CPU_COUNT][14];
typedef struct debug_page_fault_info {
addr_t fault_address;
addr_t pc;
uint32 flags;
} debug_page_fault_info;
// debug_page_fault_info::flags
#define DEBUG_PAGE_FAULT_WRITE 0x01 /* write fault */
#define DEBUG_PAGE_FAULT_NO_INFO 0x02 /* fault address and read/write
unknown */
#ifdef __cplusplus
extern "C" {
#endif
@ -83,6 +95,9 @@ extern void debug_puts(const char *s, int32 length);
extern bool debug_debugger_running(void);
extern bool debug_screen_output_enabled(void);
extern void debug_stop_screen_debug_output(void);
extern void debug_set_page_fault_info(addr_t faultAddress, addr_t pc,
uint32 flags);
extern debug_page_fault_info* debug_get_page_fault_info();
extern void kputs(const char *string);
extern void kputs_unfiltered(const char *string);
@ -109,11 +124,11 @@ extern status_t add_debugger_command_alias(const char* newName,
const char* oldName, const char* description);
extern bool print_debugger_command_usage(const char* command);
extern void _user_debug_output(const char *userString);
extern void debug_set_demangle_hook(const char *(*hook)(const char *));
extern const char *debug_demangle(const char *);
extern void _user_debug_output(const char *userString);
#ifdef __cplusplus
}
#endif

View File

@ -222,7 +222,7 @@ x86_set_task_gate(int32 n, int32 segment)
/** Tests if the interrupt in-service register of the responsible
* PIC is set for interrupts 7 and 15, and if that's not the case,
* PIC is set for interrupts 7 and 15, and if that's not the case,
* it must assume it's a spurious interrupt.
*/
@ -838,6 +838,8 @@ page_fault_exception(struct iframe* frame)
if (kernelDebugger) {
// if this thread has a fault handler, we're allowed to be here
if (thread && thread->fault_handler != 0) {
debug_set_page_fault_info(cr2, frame->eip,
(frame->error_code & 0x2) != 0 ? DEBUG_PAGE_FAULT_WRITE : 0);
frame->eip = thread->fault_handler;
return;
}

View File

@ -49,6 +49,8 @@ extern "C" int kgets(char *buffer, int length);
int dbg_register_file[B_MAX_CPU_COUNT][14];
/* XXXmpetit -- must be made generic */
static debug_page_fault_info sPageFaultInfo;
static bool sSerialDebugEnabled = true;
static bool sSyslogOutputEnabled = true;
static bool sBlueScreenEnabled = false;
@ -1132,6 +1134,22 @@ debug_init_post_modules(struct kernel_args *args)
}
void
debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags)
{
sPageFaultInfo.fault_address = faultAddress;
sPageFaultInfo.pc = pc;
sPageFaultInfo.flags = flags;
}
debug_page_fault_info*
debug_get_page_fault_info()
{
return &sPageFaultInfo;
}
// #pragma mark - public API
@ -1392,6 +1410,22 @@ kprintf_unfiltered(const char *format, ...)
}
extern void
debug_set_demangle_hook(const char *(*hook)(const char *))
{
sDemangleHook = hook;
}
extern const char *
debug_demangle(const char *sym)
{
if (sDemangleHook)
return sDemangleHook(sym);
return sym;
}
// #pragma mark -
// userland syscalls
@ -1451,20 +1485,3 @@ dump_block(const char *buffer, int size, const char *prefix)
dprintf("\n");
}
}
extern void
debug_set_demangle_hook(const char *(*hook)(const char *))
{
sDemangleHook = hook;
}
extern const char *
debug_demangle(const char *sym)
{
if (sDemangleHook)
return sDemangleHook(sym);
return sym;
}

View File

@ -299,8 +299,19 @@ error:
INVOKE_COMMAND_FAULT);
case INVOKE_COMMAND_FAULT:
kprintf_unfiltered("\n[*** READ/WRITE FAULT ***]\n");
{
debug_page_fault_info* info = debug_get_page_fault_info();
if ((info->flags & DEBUG_PAGE_FAULT_NO_INFO) == 0) {
kprintf_unfiltered("\n[*** %s FAULT at %#lx, pc: %#lx ***]\n",
(info->flags & DEBUG_PAGE_FAULT_NO_INFO) != 0
? "WRITE" : "READ",
info->fault_address, info->pc);
} else {
kprintf_unfiltered("\n[*** READ/WRITE FAULT (?), "
"pc: %#lx ***]\n", info->pc);
}
break;
}
case INVOKE_COMMAND_ERROR:
// command aborted (no page fault)
break;