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:
parent
3b99126c1e
commit
46ec230162
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user