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
@ -16,8 +16,8 @@
|
|||||||
#define KDEBUG 1
|
#define KDEBUG 1
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
/*
|
/*
|
||||||
* The kernel debug level.
|
* The kernel debug level.
|
||||||
* Level 1 is usual asserts, > 1 should be used for very expensive runtime checks
|
* Level 1 is usual asserts, > 1 should be used for very expensive runtime checks
|
||||||
*/
|
*/
|
||||||
# define KDEBUG 1
|
# define KDEBUG 1
|
||||||
@ -37,7 +37,7 @@
|
|||||||
#if KDEBUG
|
#if KDEBUG
|
||||||
# define ASSERT(x) ASSERT_ALWAYS(x)
|
# define ASSERT(x) ASSERT_ALWAYS(x)
|
||||||
# define ASSERT_PRINT(x, format...) ASSERT_ALWAYS_PRINT(x, format)
|
# define ASSERT_PRINT(x, format...) ASSERT_ALWAYS_PRINT(x, format)
|
||||||
#else
|
#else
|
||||||
# define ASSERT(x) do { } while(0)
|
# define ASSERT(x) do { } while(0)
|
||||||
# define ASSERT_PRINT(x, format...) do { } while(0)
|
# define ASSERT_PRINT(x, format...) do { } while(0)
|
||||||
#endif
|
#endif
|
||||||
@ -69,6 +69,18 @@ struct debugger_module_info {
|
|||||||
|
|
||||||
extern int dbg_register_file[B_MAX_CPU_COUNT][14];
|
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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -83,6 +95,9 @@ extern void debug_puts(const char *s, int32 length);
|
|||||||
extern bool debug_debugger_running(void);
|
extern bool debug_debugger_running(void);
|
||||||
extern bool debug_screen_output_enabled(void);
|
extern bool debug_screen_output_enabled(void);
|
||||||
extern void debug_stop_screen_debug_output(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(const char *string);
|
||||||
extern void kputs_unfiltered(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);
|
const char* oldName, const char* description);
|
||||||
extern bool print_debugger_command_usage(const char* command);
|
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 void debug_set_demangle_hook(const char *(*hook)(const char *));
|
||||||
extern const char *debug_demangle(const char *);
|
extern const char *debug_demangle(const char *);
|
||||||
|
|
||||||
|
extern void _user_debug_output(const char *userString);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -222,7 +222,7 @@ x86_set_task_gate(int32 n, int32 segment)
|
|||||||
|
|
||||||
|
|
||||||
/** Tests if the interrupt in-service register of the responsible
|
/** 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.
|
* it must assume it's a spurious interrupt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -838,6 +838,8 @@ page_fault_exception(struct iframe* frame)
|
|||||||
if (kernelDebugger) {
|
if (kernelDebugger) {
|
||||||
// if this thread has a fault handler, we're allowed to be here
|
// if this thread has a fault handler, we're allowed to be here
|
||||||
if (thread && thread->fault_handler != 0) {
|
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;
|
frame->eip = thread->fault_handler;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,8 @@ extern "C" int kgets(char *buffer, int length);
|
|||||||
int dbg_register_file[B_MAX_CPU_COUNT][14];
|
int dbg_register_file[B_MAX_CPU_COUNT][14];
|
||||||
/* XXXmpetit -- must be made generic */
|
/* XXXmpetit -- must be made generic */
|
||||||
|
|
||||||
|
static debug_page_fault_info sPageFaultInfo;
|
||||||
|
|
||||||
static bool sSerialDebugEnabled = true;
|
static bool sSerialDebugEnabled = true;
|
||||||
static bool sSyslogOutputEnabled = true;
|
static bool sSyslogOutputEnabled = true;
|
||||||
static bool sBlueScreenEnabled = false;
|
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
|
// #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 -
|
// #pragma mark -
|
||||||
// userland syscalls
|
// userland syscalls
|
||||||
|
|
||||||
@ -1451,20 +1485,3 @@ dump_block(const char *buffer, int size, const char *prefix)
|
|||||||
dprintf("\n");
|
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);
|
INVOKE_COMMAND_FAULT);
|
||||||
|
|
||||||
case 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;
|
break;
|
||||||
|
}
|
||||||
case INVOKE_COMMAND_ERROR:
|
case INVOKE_COMMAND_ERROR:
|
||||||
// command aborted (no page fault)
|
// command aborted (no page fault)
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user