Detect segfaults in modules and print information
This commit is contained in:
parent
711285f2b6
commit
cc0c32f278
@ -14,9 +14,10 @@ typedef struct {
|
||||
module_defs * mod_info;
|
||||
void * bin_data;
|
||||
hashmap_t * symbols;
|
||||
uintptr_t end;
|
||||
} module_data_t;
|
||||
|
||||
extern void * module_load_direct(void * blob);
|
||||
extern void * module_load_direct(void * blob, size_t size);
|
||||
extern void * module_load(char * filename);
|
||||
extern void module_unload(char * name);
|
||||
extern void modules_install(void);
|
||||
|
@ -143,8 +143,10 @@ int kmain(struct multiboot *mboot, uint32_t mboot_mag, uintptr_t esp) {
|
||||
for (unsigned int i = 0; i < mboot_ptr->mods_count; ++i ) {
|
||||
mboot_mod_t * mod = &mboot_mods[i];
|
||||
uint32_t module_start = mod->mod_start;
|
||||
uint32_t module_end = mod->mod_end;
|
||||
size_t module_size = module_end - module_end;
|
||||
debug_print(NOTICE, "Loading a module: 0x%x:0x%x", module_start);
|
||||
module_defs * mod_info = (module_defs *)module_load_direct((void *)(module_start));
|
||||
module_defs * mod_info = (module_defs *)module_load_direct((void *)(module_start), module_size);
|
||||
debug_print(NOTICE, "Loaded: %s", mod_info->name);
|
||||
}
|
||||
|
||||
|
@ -341,35 +341,56 @@ page_fault(
|
||||
int reserved = r->err_code & 0x8 ? 1 : 0;
|
||||
int id = r->err_code & 0x10 ? 1 : 0;
|
||||
|
||||
/* find closest symbol */
|
||||
typedef struct {
|
||||
uintptr_t addr;
|
||||
char name[];
|
||||
} kernel_symbol_t;
|
||||
|
||||
kernel_symbol_t * closest = NULL;
|
||||
size_t distance = 0xFFFFFFFF;
|
||||
|
||||
list_t * hash_keys = hashmap_keys(modules_get_symbols());
|
||||
foreach(_key, hash_keys) {
|
||||
char * key = (char *)_key->value;
|
||||
kernel_symbol_t * k = hashmap_get(modules_get_symbols(), key);
|
||||
|
||||
if (!k->addr) continue;
|
||||
if ((uintptr_t)k->addr <= r->eip) {
|
||||
size_t d = r->eip - k->addr;
|
||||
if (d < distance) {
|
||||
kprintf("%s is closer [d=%d]", key, d);
|
||||
closest = k;
|
||||
distance = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kprintf("\033[1;37;41mSegmentation fault. (p:%d,rw:%d,user:%d,res:%d,id:%d) at 0x%x eip:0x%x pid=%d,%d [%s]\033[0m\n",
|
||||
present, rw, user, reserved, id, faulting_address, r->eip, current_process->id, current_process->group, current_process->name);
|
||||
|
||||
kprintf("\033[1;31mLast symbol before faulting address: %s [0x%x]\n", &closest->name, closest->addr);
|
||||
if (r->eip < heap_end) {
|
||||
/* find closest symbol */
|
||||
typedef struct {
|
||||
uintptr_t addr;
|
||||
char name[];
|
||||
} kernel_symbol_t;
|
||||
|
||||
char * closest = NULL;
|
||||
size_t distance = 0xFFFFFFFF;
|
||||
uintptr_t addr = 0;
|
||||
|
||||
list_t * hash_keys = hashmap_keys(modules_get_symbols());
|
||||
foreach(_key, hash_keys) {
|
||||
char * key = (char *)_key->value;
|
||||
uintptr_t a = (uintptr_t)hashmap_get(modules_get_symbols(), key);
|
||||
|
||||
if (!a) continue;
|
||||
|
||||
size_t d;
|
||||
if (a <= r->eip) {
|
||||
d = r->eip - a;
|
||||
} else {
|
||||
d = a - r->eip;
|
||||
}
|
||||
if (d < distance) {
|
||||
closest = key;
|
||||
distance = d;
|
||||
addr = a;
|
||||
}
|
||||
}
|
||||
|
||||
kprintf("\033[1;31mClosest symbol to faulting address:\033[0m %s [0x%x]\n", closest, addr);
|
||||
|
||||
hash_keys = hashmap_keys(modules_get_list());
|
||||
foreach(_key, hash_keys) {
|
||||
char * key = (char *)_key->value;
|
||||
module_data_t * m = (module_data_t *)hashmap_get(modules_get_list(), key);
|
||||
|
||||
if ((r->eip >= (uintptr_t)m->bin_data) && (r->eip < m->end)) {
|
||||
kprintf("\033[1;31mIn module:\033[0m %s (starts at 0x%x)\n", m->mod_info->name, m->bin_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
kprintf("\033[1;31m(In userspace)\033[0m\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -20,7 +20,7 @@ extern char kernel_symbols_start[];
|
||||
extern char kernel_symbols_end[];
|
||||
|
||||
|
||||
void * module_load_direct(void * blob) {
|
||||
void * module_load_direct(void * blob, size_t length) {
|
||||
Elf32_Header * target = (Elf32_Header *)blob;
|
||||
|
||||
if (target->e_ident[0] != ELFMAG0 ||
|
||||
@ -199,12 +199,21 @@ void * module_load_direct(void * blob) {
|
||||
|
||||
debug_print(NOTICE, "Finished loading module %s", mod_info->name);
|
||||
|
||||
hashmap_set(modules, mod_info->name, (void *)mod_info);
|
||||
|
||||
/* We don't do this anymore
|
||||
* TODO: Do this in the module unload function
|
||||
hashmap_free(local_symbols);
|
||||
free(local_symbols);
|
||||
*/
|
||||
|
||||
return mod_info;
|
||||
module_data_t * mod_data = malloc(sizeof(module_data_t));
|
||||
mod_data->mod_info = mod_info;
|
||||
mod_data->bin_data = target;
|
||||
mod_data->symbols = local_symbols;
|
||||
mod_data->end = (uintptr_t)target + length;
|
||||
|
||||
hashmap_set(modules, mod_info->name, (void *)mod_data);
|
||||
|
||||
return mod_data;
|
||||
|
||||
mod_load_error:
|
||||
return NULL;
|
||||
@ -226,7 +235,7 @@ void * module_load(char * filename) {
|
||||
void * blob = (void *)kvmalloc(file->length);
|
||||
read_fs(file, 0, file->length, (uint8_t *)blob);
|
||||
|
||||
void * result = module_load_direct(blob);
|
||||
void * result = module_load_direct(blob, file->length);
|
||||
|
||||
close_fs(file);
|
||||
return result;
|
||||
|
18
modules/crash.c
Normal file
18
modules/crash.c
Normal file
@ -0,0 +1,18 @@
|
||||
#include <module.h>
|
||||
#include <mod/shell.h>
|
||||
|
||||
DEFINE_SHELL_FUNCTION(crash, "Dereference NULL.") {
|
||||
int x = *((int *)0x20000000 );
|
||||
return x;
|
||||
}
|
||||
|
||||
static int crash_init(void) {
|
||||
BIND_SHELL_FUNCTION(crash);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crash_fini(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_DEF(crash, crash_init, crash_fini);
|
@ -611,13 +611,13 @@ static int shell_mod(fs_node_t * tty, int argc, char * argv[]) {
|
||||
}
|
||||
|
||||
fs_printf(tty, "Okay, going to load a module!\n");
|
||||
module_defs * mod_info = module_load(argv[1]);
|
||||
module_data_t * mod_info = module_load(argv[1]);
|
||||
if (!mod_info) {
|
||||
fs_printf(tty, "Something went wrong, failed to load module: %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fs_printf(tty, "Loaded %s!\n", mod_info->name);
|
||||
fs_printf(tty, "Loaded %s at 0x%x\n", mod_info->mod_info->name, mod_info->bin_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -683,9 +683,11 @@ static int shell_modules(fs_node_t * tty, int argc, char * argv[]) {
|
||||
list_t * hash_keys = hashmap_keys(modules_get_list());
|
||||
foreach(_key, hash_keys) {
|
||||
char * key = (char *)_key->value;
|
||||
module_defs * mod_info = hashmap_get(modules_get_list(), key);
|
||||
module_data_t * mod_info = hashmap_get(modules_get_list(), key);
|
||||
|
||||
fs_printf(tty, "%s {.init=0x%x, .fini=0x%x}\n", mod_info->name, mod_info->initialize, mod_info->finalize);
|
||||
fs_printf(tty, "%s at 0x%x {.init=0x%x, .fini=0x%x}\n",
|
||||
mod_info->mod_info->name, mod_info->bin_data,
|
||||
mod_info->mod_info->initialize, mod_info->mod_info->finalize);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user