New debug printing facilities.
- Can now register a userspace file descriptor as the output for kernel print statements through kprintf() - Can set logging levels for debug print messages, which are separate from kernel log events and meant to be more readily visible. Log events are recorded in a buffer to be viewed later, though nothing actually using logging at the moment. - Serial output is disabled by default now. You can enable it yourself by appending the logtoserial argument to the kernel on boot.
This commit is contained in:
parent
2bd3ad4007
commit
8ed06789ed
@ -7,6 +7,7 @@
|
||||
#include <fs.h>
|
||||
#include <list.h>
|
||||
#include <process.h>
|
||||
#include <logging.h>
|
||||
|
||||
fs_node_t *fs_root = 0;
|
||||
|
||||
@ -179,7 +180,7 @@ int mkdir_fs(char *name, uint16_t permission) {
|
||||
}
|
||||
|
||||
if (node == NULL) {
|
||||
kprintf("mkdir: Directory does not exist\n");
|
||||
debug_print(WARNING, "mkdir: Directory does not exist");
|
||||
free(dir_name);
|
||||
return 1;
|
||||
}
|
||||
@ -326,6 +327,7 @@ char *canonicalize_path(char *cwd, char *input) {
|
||||
*
|
||||
*/
|
||||
fs_node_t *get_mount_point(char * path, size_t path_depth) {
|
||||
#if 0
|
||||
size_t depth;
|
||||
|
||||
kprintf("[root]");
|
||||
@ -333,6 +335,7 @@ fs_node_t *get_mount_point(char * path, size_t path_depth) {
|
||||
kprintf("%s%c", path, (depth == path_depth) ? '\n' : '/');
|
||||
path += strlen(path) + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
tree_node_t * tnode = from;
|
||||
|
@ -26,4 +26,17 @@ void logging_install();
|
||||
void blog(char * string);
|
||||
void bfinish(int status);
|
||||
|
||||
log_type_t debug_level;
|
||||
void _debug_print(char * title, int line_no, log_type_t level, char *fmt, ...);
|
||||
|
||||
#ifndef MODULE_NAME
|
||||
#define MODULE_NAME __FILE__
|
||||
#endif
|
||||
|
||||
#ifndef QUIET
|
||||
#define debug_print(level, ...) _debug_print(MODULE_NAME, __LINE__, level, __VA_ARGS__)
|
||||
#else
|
||||
#define debug_print(level, ...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -156,7 +156,17 @@ extern void mouse_install();
|
||||
|
||||
/* kprintf */
|
||||
extern size_t vasprintf(char * buf, const char *fmt, va_list args);
|
||||
#ifndef EXTREME_KPRINTF_DEBUGGING
|
||||
extern int kprintf(const char *fmt, ...);
|
||||
#else
|
||||
/* This is really, really extreme */
|
||||
extern int _kprintf(char * file, int line, const char *fmt, ...);
|
||||
#define kprintf(...) _kprintf(__FILE__, __LINE__, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
extern short kprint_to_serial;
|
||||
extern void * kprint_to_file;
|
||||
|
||||
extern int sprintf(char *buf, const char *fmt, ...);
|
||||
extern int kgets(char *buf, int size);
|
||||
typedef void (*kgets_redraw_t)();
|
||||
|
@ -130,6 +130,8 @@ int main(struct multiboot *mboot, uint32_t mboot_mag, uintptr_t esp) {
|
||||
|
||||
keyboard_install(); /* Keyboard interrupt handler */
|
||||
|
||||
debug_print(WARNING, "I am test, test test test!");
|
||||
|
||||
if (ramdisk) {
|
||||
initrd_mount((uintptr_t)ramdisk, ramdisk_top);
|
||||
}
|
||||
|
@ -269,26 +269,26 @@ paging_install(uint32_t memsize) {
|
||||
|
||||
void
|
||||
debug_print_directory() {
|
||||
kprintf(" ---- [k:0x%x u:0x%x]\n", kernel_directory, current_directory);
|
||||
debug_print(INFO, " ---- [k:0x%x u:0x%x]", kernel_directory, current_directory);
|
||||
for (uintptr_t i = 0; i < 1024; ++i) {
|
||||
if (!current_directory->tables[i] || (uintptr_t)current_directory->tables[i] == (uintptr_t)0xFFFFFFFF) {
|
||||
continue;
|
||||
}
|
||||
if (kernel_directory->tables[i] == current_directory->tables[i]) {
|
||||
kprintf(" 0x%x - kern [0x%x/0x%x] 0x%x\n", current_directory->tables[i], ¤t_directory->tables[i], &kernel_directory->tables[i], i * 0x1000 * 1024);
|
||||
debug_print(INFO, " 0x%x - kern [0x%x/0x%x] 0x%x", current_directory->tables[i], ¤t_directory->tables[i], &kernel_directory->tables[i], i * 0x1000 * 1024);
|
||||
} else {
|
||||
kprintf(" 0x%x - user [0x%x] 0x%x [0x%x]\n", current_directory->tables[i], ¤t_directory->tables[i], i * 0x1000 * 1024, kernel_directory->tables[i]);
|
||||
debug_print(INFO, " 0x%x - user [0x%x] 0x%x [0x%x]", current_directory->tables[i], ¤t_directory->tables[i], i * 0x1000 * 1024, kernel_directory->tables[i]);
|
||||
for (uint16_t j = 0; j < 1024; ++j) {
|
||||
#if 0
|
||||
page_t * p= ¤t_directory->tables[i]->pages[j];
|
||||
if (p->frame) {
|
||||
kprintf(" 0x%x - 0x%x %s\n", p->frame * 0x1000, p->frame * 0x1000 + 0xFFF, p->present ? "[present]" : "");
|
||||
debug_print(INFO, " 0x%x - 0x%x %s", p->frame * 0x1000, p->frame * 0x1000 + 0xFFF, p->present ? "[present]" : "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
kprintf(" ---- [done]\n");
|
||||
debug_print(INFO, " ---- [done]");
|
||||
}
|
||||
|
||||
void
|
||||
@ -333,7 +333,7 @@ page_fault(
|
||||
if (r->eip == SIGNAL_RETURN) {
|
||||
return_from_signal_handler();
|
||||
} else if (r->eip == THREAD_RETURN) {
|
||||
kprintf("[kernel:XXX] Return from thread!\n");
|
||||
debug_print(INFO, "Returned from thread.");
|
||||
kexit(0);
|
||||
}
|
||||
|
||||
@ -376,9 +376,9 @@ void *
|
||||
sbrk(
|
||||
uintptr_t increment
|
||||
) {
|
||||
#if 1
|
||||
#if 0
|
||||
if (current_process) {
|
||||
kprintf("[kernel] sbrk [0x%x]+0x%x pid=%d [%s]\n", heap_end, increment, getpid(), current_process->name);
|
||||
debug_print(INFO, "sbrk [0x%x]+0x%x pid=%d [%s]", heap_end, increment, getpid(), current_process->name);
|
||||
}
|
||||
#endif
|
||||
ASSERT((increment % 0x1000 == 0) && "Kernel requested to expand heap by a non-page-multiple value");
|
||||
|
@ -83,6 +83,8 @@ parse_args(
|
||||
} else if (!strcmp(argp[0],"start")) {
|
||||
if (argc < 2) { kprintf("start=?\n"); continue; }
|
||||
boot_arg_extra = argp[1];
|
||||
} else if (!strcmp(argp[0],"logtoserial")) {
|
||||
kprint_to_serial = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <system.h>
|
||||
#include <process.h>
|
||||
#include <va_list.h>
|
||||
#include <fs.h>
|
||||
|
||||
/*
|
||||
* Integer to string
|
||||
@ -93,6 +94,9 @@ vasprintf(char * buf, const char *fmt, va_list args) {
|
||||
|
||||
}
|
||||
|
||||
short kprint_to_serial = 0;
|
||||
void * kprint_to_file = NULL;
|
||||
|
||||
/**
|
||||
* (Kernel) Print a formatted string.
|
||||
* %s, %c, %x, %d, %%
|
||||
@ -100,6 +104,7 @@ vasprintf(char * buf, const char *fmt, va_list args) {
|
||||
* @param fmt Formatted string to print
|
||||
* @param ... Additional arguments to format
|
||||
*/
|
||||
#ifndef EXTREME_KPRINTF_DEBUGGING
|
||||
int
|
||||
kprintf(
|
||||
const char *fmt,
|
||||
@ -112,9 +117,46 @@ kprintf(
|
||||
/* We're done with our arguments */
|
||||
va_end(args);
|
||||
/* Print that sucker */
|
||||
serial_string(buf);
|
||||
if (kprint_to_serial) {
|
||||
serial_string(buf);
|
||||
} else {
|
||||
/* TODO "Registered Ouput Terminal", which is probably *not* the serial output */
|
||||
/* XXX */
|
||||
if (kprint_to_file) {
|
||||
fs_node_t * node = (fs_node_t *)kprint_to_file;
|
||||
uint32_t out = write_fs(node, node->offset, strlen(buf), (uint8_t *)buf);
|
||||
node->offset += out;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
#else
|
||||
int
|
||||
_kprintf(
|
||||
char * file,
|
||||
int line,
|
||||
const char *fmt,
|
||||
...
|
||||
) {
|
||||
char buf[1024] = {-1};
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int out = vasprintf(buf, fmt, args);
|
||||
/* We're done with our arguments */
|
||||
va_end(args);
|
||||
/* Print that sucker */
|
||||
if (buf[strlen(buf)-1] == '\n') {
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
serial_string(buf);
|
||||
char buf2[1024];
|
||||
sprintf(buf2, " %s:%d\n", file, line);
|
||||
serial_string(buf2);
|
||||
} else {
|
||||
serial_string(buf);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
sprintf(
|
||||
|
@ -85,3 +85,29 @@ void bfinish(int status) {
|
||||
if (!last_message) { return; }
|
||||
kprintf("\033[1000D\033[0m%s\033[1000C\033[8D[%s\033[0m]\n", last_message, boot_messages[status]);
|
||||
}
|
||||
|
||||
log_type_t debug_level = NOTICE;
|
||||
|
||||
static char * c_messages[] = {
|
||||
"\033[1;34mINFO",
|
||||
"\033[1;35mNOTICE",
|
||||
"\033[1;33mWARNING",
|
||||
"\033[1;31mERROR",
|
||||
"\033[1;37;41mCRITICAL"
|
||||
};
|
||||
|
||||
|
||||
void _debug_print(char * title, int line_no, log_type_t level, char *fmt, ...) {
|
||||
if (level >= debug_level) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char buffer[1024];
|
||||
vasprintf(buffer, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
kprintf("[%s:%d] %s\033[0m: %s\n", title, line_no, c_messages[level], buffer);
|
||||
|
||||
}
|
||||
/* else ignore */
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <process.h>
|
||||
#include <tree.h>
|
||||
#include <list.h>
|
||||
#include <logging.h>
|
||||
|
||||
tree_t * process_tree; /* Parent->Children tree */
|
||||
list_t * process_queue; /* Ready queue */
|
||||
@ -237,9 +238,9 @@ process_t * spawn_process(volatile process_t * parent) {
|
||||
assert(process_tree->root && "Attempted to spawn a process without init.");
|
||||
|
||||
/* Allocate a new process */
|
||||
kprintf(" process_t {\n");
|
||||
debug_print(INFO," process_t {");
|
||||
process_t * proc = malloc(sizeof(process_t));
|
||||
kprintf(" }\n");
|
||||
debug_print(INFO," }");
|
||||
proc->id = get_next_pid(); /* Set its PID */
|
||||
proc->group = proc->id; /* Set the GID */
|
||||
proc->name = default_name; /* Use the default name */
|
||||
@ -259,9 +260,9 @@ process_t * spawn_process(volatile process_t * parent) {
|
||||
proc->image.heap = parent->image.heap;
|
||||
proc->image.heap_actual = parent->image.heap_actual;
|
||||
proc->image.size = parent->image.size;
|
||||
kprintf(" stack {\n");
|
||||
debug_print(INFO," stack {");
|
||||
proc->image.stack = (uintptr_t)malloc(KERNEL_STACK_SIZE) + KERNEL_STACK_SIZE;
|
||||
kprintf(" }\n");
|
||||
debug_print(INFO," }");
|
||||
proc->image.user_stack = parent->image.user_stack;
|
||||
proc->image.shm_heap = 0x20000000; /* Yeah, a bit of a hack. */
|
||||
|
||||
@ -272,14 +273,14 @@ process_t * spawn_process(volatile process_t * parent) {
|
||||
proc->fds->refs = 1;
|
||||
proc->fds->length = parent->fds->length;
|
||||
proc->fds->capacity = parent->fds->capacity;
|
||||
kprintf(" fds / files {\n");
|
||||
debug_print(INFO," fds / files {");
|
||||
proc->fds->entries = malloc(sizeof(fs_node_t *) * proc->fds->capacity);
|
||||
assert(proc->fds->entries && "Failed to allocate file descriptor table for new process.");
|
||||
kprintf(" ---\n");
|
||||
debug_print(INFO," ---");
|
||||
for (uint32_t i = 0; i < parent->fds->length; ++i) {
|
||||
proc->fds->entries[i] = clone_fs(parent->fds->entries[i]);
|
||||
}
|
||||
kprintf(" }\n");
|
||||
debug_print(INFO," }");
|
||||
|
||||
/* As well as the working directory */
|
||||
proc->wd_node = clone_fs(parent->wd_node);
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
void validate(void * ptr) {
|
||||
if (ptr && (uintptr_t)ptr < current_process->image.entry) {
|
||||
kprintf("SEGFAULT: Invalid pointer passed to syscall. (0x%x < 0x%x)\n", (uintptr_t)ptr, current_process->image.entry);
|
||||
debug_print(ERROR, "SEGFAULT: Invalid pointer passed to syscall. (0x%x < 0x%x)", (uintptr_t)ptr, current_process->image.entry);
|
||||
HALT_AND_CATCH_FIRE("Segmentation fault", NULL);
|
||||
}
|
||||
}
|
||||
@ -103,13 +103,13 @@ static int write(int fd, char * ptr, int len) {
|
||||
|
||||
static int wait(int child) {
|
||||
if (child < 1) {
|
||||
kprintf("[debug] Process %d requested group wait, which we can not do!\n", getpid());
|
||||
debug_print(WARNING, "Process %d requested group wait, which we can not do!", getpid());
|
||||
return 0;
|
||||
}
|
||||
process_t * volatile child_task = process_from_pid(child);
|
||||
/* If the child task doesn't exist, bail */
|
||||
if (!child_task) {
|
||||
kprintf("Tried to wait for non-existent process\n");
|
||||
debug_print(WARNING, "Tried to wait for non-existent process");
|
||||
return -1;
|
||||
}
|
||||
while (child_task->finished == 0) {
|
||||
@ -128,7 +128,7 @@ static int open(const char * file, int flags, int mode) {
|
||||
if (!node && (flags & 0x600)) {
|
||||
/* Um, make one */
|
||||
if (!create_file_fs((char *)file, 0777)) {
|
||||
kprintf("[creat] Creating file!\n");
|
||||
debug_print(NOTICE, "[creat] Creating file!");
|
||||
node = kopen((char *)file, 0);
|
||||
}
|
||||
}
|
||||
@ -137,7 +137,7 @@ static int open(const char * file, int flags, int mode) {
|
||||
}
|
||||
node->offset = 0;
|
||||
int fd = process_append_fd((process_t *)current_process, node);
|
||||
kprintf("[open] pid=%d %s -> %d\n", getpid(), file, fd);
|
||||
debug_print(INFO, "[open] pid=%d %s -> %d", getpid(), file, fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
@ -187,16 +187,16 @@ static int execve(const char * filename, char *const argv[], char *const envp[])
|
||||
while (argv[i]) {
|
||||
++i;
|
||||
}
|
||||
kprintf("Allocating space for arguments...\n");
|
||||
debug_print(INFO, "Allocating space for arguments...");
|
||||
char ** argv_ = malloc(sizeof(char *) * i);
|
||||
for (int j = 0; j < i; ++j) {
|
||||
argv_[j] = malloc((strlen(argv[j]) + 1) * sizeof(char));
|
||||
memcpy(argv_[j], argv[j], strlen(argv[j]) + 1);
|
||||
}
|
||||
kprintf("Releasing all shmem regions...\n");
|
||||
debug_print(INFO,"Releasing all shmem regions...");
|
||||
shm_release_all((process_t *)current_process);
|
||||
|
||||
kprintf("Executing...\n");
|
||||
debug_print(INFO,"Executing...");
|
||||
/* Discard envp */
|
||||
exec((char *)filename, i, (char **)argv_);
|
||||
return -1;
|
||||
@ -238,7 +238,6 @@ static int seek(int fd, int offset, int whence) {
|
||||
if (fd < 3) {
|
||||
return 0;
|
||||
}
|
||||
//kprintf("[seek] pid=%d fd=%d offset=%d whence=%d\n", getpid(), fd, offset, whence);
|
||||
if (whence == 0) {
|
||||
current_process->fds->entries[fd]->offset = offset;
|
||||
} else if (whence == 1) {
|
||||
@ -391,11 +390,11 @@ static void inspect_memory (uintptr_t vaddr) {
|
||||
*/
|
||||
|
||||
static int reboot() {
|
||||
kprintf("[kernel] Reboot requested from process %d by user #%d\n", current_process->id, current_process->user);
|
||||
debug_print(NOTICE, "[kernel] Reboot requested from process %d by user #%d", current_process->id, current_process->user);
|
||||
if (current_process->user != USER_ROOT_UID) {
|
||||
return -1;
|
||||
} else {
|
||||
kprintf("[kernel] Good bye!\n");
|
||||
debug_print(NOTICE, "[kernel] Good bye!");
|
||||
/* Goodbye, cruel world */
|
||||
uint8_t out = 0x02;
|
||||
while ((out & 0x02) != 0) {
|
||||
@ -502,10 +501,9 @@ extern void ext2_disk_sync();
|
||||
/*
|
||||
* System Function
|
||||
*/
|
||||
static int system_function(int fn, char * args) {
|
||||
static int system_function(int fn, char ** args) {
|
||||
/* System Functions are special debugging system calls */
|
||||
if (current_process->user == USER_ROOT_UID) {
|
||||
kprintf("Executing system function %d\n", fn);
|
||||
switch (fn) {
|
||||
case 1:
|
||||
/* Print memory information */
|
||||
@ -521,8 +519,14 @@ static int system_function(int fn, char * args) {
|
||||
case 3:
|
||||
ext2_disk_sync();
|
||||
return 0;
|
||||
case 4:
|
||||
/* Request kernel output to file descriptor in arg0*/
|
||||
kprintf("Setting output to file object in process %d's fd=%d!\n", getpid(), (int)args);
|
||||
kprint_to_file = current_process->fds->entries[(int)args];
|
||||
kprint_to_serial = 0;
|
||||
break;
|
||||
default:
|
||||
kprintf("Bad system function.\n");
|
||||
kprintf("Bad system function %d\n", fn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ void release_directory(page_directory_t * dir) {
|
||||
extern char * default_name;
|
||||
|
||||
void reap_process(process_t * proc) {
|
||||
kprintf("Reaping process %d; mem before = %d\n", proc->id, memory_use());
|
||||
debug_print(INFO, "Reaping process %d; mem before = %d", proc->id, memory_use());
|
||||
list_free(proc->wait_queue);
|
||||
free(proc->wait_queue);
|
||||
list_free(proc->signal_queue);
|
||||
@ -117,8 +117,8 @@ void reap_process(process_t * proc) {
|
||||
free(proc->fds);
|
||||
free((void *)(proc->image.stack - KERNEL_STACK_SIZE));
|
||||
}
|
||||
kprintf("Reaped process %d; mem after = %d\n", proc->id, memory_use());
|
||||
// These things are bad!
|
||||
debug_print(INFO, "Reaped process %d; mem after = %d", proc->id, memory_use());
|
||||
// XXX These things are bad!
|
||||
//delete_process(proc);
|
||||
//free((void *)proc);
|
||||
}
|
||||
@ -201,9 +201,9 @@ fork() {
|
||||
page_directory_t * directory = clone_directory(current_directory);
|
||||
assert(directory && "Could not allocate a new page directory!");
|
||||
/* Spawn a new process from this one */
|
||||
kprintf("\033[1;32mALLOC {\033[0m\n");
|
||||
debug_print(INFO,"\033[1;32mALLOC {\033[0m");
|
||||
process_t * new_proc = spawn_process(current_process);
|
||||
kprintf("\033[1;32m}\033[0m\n");
|
||||
debug_print(INFO,"\033[1;32m}\033[0m");
|
||||
assert(new_proc && "Could not allocate a new process!");
|
||||
/* Set the new process' page directory to clone */
|
||||
set_process_environment(new_proc, directory);
|
||||
@ -457,7 +457,7 @@ switch_next() {
|
||||
|
||||
/* Validate */
|
||||
if ((eip < (uintptr_t)&code) || (eip > (uintptr_t)&end)) {
|
||||
kprintf("[warning] Skipping broken process %d!\n", current_process->id);
|
||||
debug_print(WARNING, "Skipping broken process %d!", current_process->id);
|
||||
switch_next();
|
||||
}
|
||||
|
||||
@ -560,7 +560,7 @@ void task_exit(int retval) {
|
||||
}
|
||||
current_process->status = retval;
|
||||
current_process->finished = 1;
|
||||
kprintf("[%d] Waking up %d processes...\n", getpid(), current_process->wait_queue->length);
|
||||
debug_print(INFO, "[%d] Waking up %d processes...", getpid(), current_process->wait_queue->length);
|
||||
wakeup_queue(current_process->wait_queue);
|
||||
make_process_reapable((process_t *)current_process);
|
||||
switch_next();
|
||||
|
@ -81,7 +81,6 @@ void start_compositor() {
|
||||
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
fprintf(stderr, "[init] Hello world.\n");
|
||||
/* Hostname */
|
||||
set_hostname();
|
||||
if (argc > 1) {
|
||||
|
@ -26,6 +26,10 @@
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_CACHE_H
|
||||
|
||||
#ifndef syscall_system_function
|
||||
DEFN_SYSCALL2(system_function, 43, int, int);
|
||||
#endif
|
||||
|
||||
#include "lib/utf8_decode.h"
|
||||
#include "../kernel/include/mouse.h"
|
||||
|
||||
@ -3162,7 +3166,7 @@ int main(int argc, char ** argv) {
|
||||
int i = execve(tokens[0], tokens, NULL);
|
||||
printf("Failed to execute requested startup application `%s`!\n", argv[optind]);
|
||||
printf("Your system is now unusable, and a restart will not be attempted.\n");
|
||||
syscall_print("core-tests : FATAL : Could not execute the core-tests binary. This is a fatal error.\n");
|
||||
syscall_print("core-tests : FATAL : Failed to execute requested startup binary.\n");
|
||||
} else {
|
||||
/*
|
||||
* TODO: Check the public-readable passwd file to select which shell to run
|
||||
@ -3181,6 +3185,12 @@ int main(int argc, char ** argv) {
|
||||
return 1;
|
||||
} else {
|
||||
|
||||
if (!_windowed) {
|
||||
ansi_print("Requesting terminal output to me!\n");
|
||||
/* Request kernel output to this terminal */
|
||||
syscall_system_function(4, ofd);
|
||||
}
|
||||
|
||||
child_pid = f;
|
||||
|
||||
pthread_t wait_for_exit_thread;
|
||||
|
Loading…
x
Reference in New Issue
Block a user