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:
Kevin Lange 2012-09-03 22:35:11 -07:00
parent 2bd3ad4007
commit 8ed06789ed
13 changed files with 152 additions and 40 deletions

View File

@ -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;

View File

@ -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

View File

@ -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)();

View File

@ -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);
}

View File

@ -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], &current_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], &current_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], &current_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], &current_directory->tables[i], i * 0x1000 * 1024, kernel_directory->tables[i]);
for (uint16_t j = 0; j < 1024; ++j) {
#if 0
page_t * p= &current_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");

View File

@ -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;
}
}
}

View File

@ -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(

View File

@ -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 */
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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();

View File

@ -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) {

View File

@ -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;