Add debugging kernel monitor functions

This commit is contained in:
Danila Fedorin 2019-04-24 23:49:13 -07:00
parent 0fe97e52c3
commit 7d76204053
3 changed files with 44 additions and 2 deletions

View File

@ -7,6 +7,7 @@
#include <inc/assert.h> #include <inc/assert.h>
#include <inc/x86.h> #include <inc/x86.h>
#include <kern/env.h>
#include <kern/ansi.h> #include <kern/ansi.h>
#include <kern/console.h> #include <kern/console.h>
#include <kern/monitor.h> #include <kern/monitor.h>
@ -31,7 +32,9 @@ static struct Command commands[] = {
{ "kerninfo", "Display information about the kernel", mon_kerninfo }, { "kerninfo", "Display information about the kernel", mon_kerninfo },
{ "backtrace", "Display current backtrace", mon_backtrace }, { "backtrace", "Display current backtrace", mon_backtrace },
{ "showmappings", "Display the physical mappings for range", mon_showmappings }, { "showmappings", "Display the physical mappings for range", mon_showmappings },
{ "mperms", "Change the permissions of a memory range", mon_mperms } { "mperms", "Change the permissions of a memory range", mon_mperms },
{ "resume", "Resume from a breakpoint", mon_resume },
{ "step", "Step to next instruction", mon_step }
}; };
@ -188,6 +191,43 @@ int mon_mperms(int argc, char** argv, struct Trapframe* tf) {
return 0; return 0;
} }
// This is a nice thought and all...
// But we should modify the trap frame.
// I feel stupid.
static inline void
set_eflag(uint16_t flagno, int value) {
uint32_t temp;
uint32_t mask = ~(1 << flagno);
uint32_t regv = value << flagno;
asm volatile("pushfl\n\t"
"pop %w0\n\t"
"and %w1, %w0\n\t"
"or %w2, %w0\n\t"
"push %w0\n\t"
"popfl\n\t"
: "=r" (temp)
: "r" (mask), "r" (regv));
}
#define EXPECT_BRKPT if(!(tf->tf_trapno == T_BRKPT || tf->tf_trapno == T_DEBUG)) { \
cprintf(ACOL_ERR("I don't think I should resume from this.\n")); \
return 0; }
#define EFLAGS_TF 0x8
int mon_resume(int argc, char** argv, struct Trapframe* tf) {
EXPECT_BRKPT;
tf->tf_eflags &= ~(1 << EFLAGS_TF);
env_pop_tf(tf);
return 0;
}
int mon_step(int argc, char** argv, struct Trapframe* tf) {
EXPECT_BRKPT;
tf->tf_eflags |= 1 << EFLAGS_TF;
env_pop_tf(tf);
return 0;
}
/***** Kernel monitor command interpreter *****/ /***** Kernel monitor command interpreter *****/
#define WHITESPACE "\t\r\n " #define WHITESPACE "\t\r\n "

View File

@ -17,5 +17,7 @@ int mon_kerninfo(int argc, char **argv, struct Trapframe *tf);
int mon_backtrace(int argc, char **argv, struct Trapframe *tf); int mon_backtrace(int argc, char **argv, struct Trapframe *tf);
int mon_showmappings(int argc, char **argv, struct Trapframe *tf); int mon_showmappings(int argc, char **argv, struct Trapframe *tf);
int mon_mperms(int argc, char** argv, struct Trapframe* tf); int mon_mperms(int argc, char** argv, struct Trapframe* tf);
int mon_resume(int argc, char** argv, struct Trapframe* tf);
int mon_step(int argc, char** argv, struct Trapframe* tf);
#endif // !JOS_KERN_MONITOR_H #endif // !JOS_KERN_MONITOR_H

View File

@ -199,7 +199,7 @@ trap_dispatch(struct Trapframe *tf)
if (tf->tf_trapno == T_PGFLT) { if (tf->tf_trapno == T_PGFLT) {
page_fault_handler(tf); page_fault_handler(tf);
return; return;
} else if (tf->tf_trapno == T_BRKPT) { } else if (tf->tf_trapno == T_BRKPT || tf->tf_trapno == T_DEBUG) {
monitor(tf); monitor(tf);
return; return;
} else if (tf->tf_trapno == T_SYSCALL) { } else if (tf->tf_trapno == T_SYSCALL) {