diff options
Diffstat (limited to 'init/log.c')
-rw-r--r-- | init/log.c | 209 |
1 files changed, 0 insertions, 209 deletions
diff --git a/init/log.c b/init/log.c deleted file mode 100644 index f39467c..0000000 --- a/init/log.c +++ /dev/null @@ -1,209 +0,0 @@ -#include <execinfo.h> -#include <signal.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/file.h> -#include <sys/syscall.h> -#include <sys/time.h> -#include <unistd.h> -#include <log.h> -#include <util.h> - -extern int subsystem_change_mode(int pid, char mode); -extern char *subsystem_get_name(int pid); -extern int mainpid; - -static const char *colors[] = { - [EMERG_LOGLEVEL] = ANSI_BLINK ANSI_REVERSE ANSI_BOLD ANSI_RED, - [ALERT_LOGLEVEL] = ANSI_REVERSE ANSI_BOLD ANSI_RED, - [CRIT_LOGLEVEL] = ANSI_BOLD ANSI_RED, - [ERR_LOGLEVEL] = ANSI_RED, - [WARNING_LOGLEVEL] = ANSI_BOLD, - [NOTICE_LOGLEVEL] = ANSI_BRIGHT_WHITE, - [INFO_LOGLEVEL] = ANSI_RESET, - [DEBUG_LOGLEVEL] = ANSI_ITALIC ANSI_BRIGHT_BLUE, -}; - -static const char *mode_to_string[] = { - [PANICMODE_DEBUGONLY] = "subsystem OOPS", - [PANICMODE_RESPAWN] = "subsystem failure", - [PANICMODE_DIE] = "catastrophic failure", -}; - -static int console_lock = 0; - -#define MAX_TRY_COUNT 1 << 17 -static void obtain_console_lock(void) -{ - int try_count = 0; - register int rax asm("rax"); -retry: - while(console_lock && try_count <= MAX_TRY_COUNT) - try_count += 1; - - asm("mov %0, 1 \n" - "xchg %0, %1" : "=r" (rax), "=m" (console_lock)); - - if(rax > 0 && try_count <= MAX_TRY_COUNT) - goto retry; - - if(try_count > MAX_TRY_COUNT) { - print(LOG_SOH "\3" "4" "log: broken console lock"); - } - - return; -} - -static int vaprint(const char *fmt, va_list ap) -{ - int loglevel = DEFAULT_LOGLEVEL; - int dolocks = 1; - int parsecolon = 1; - if(fmt[0] == LOG_SOH_ASCII) { - loglevel = (fmt[2] - 0x30) % 10; - char flags = fmt[1]; - if(flags & 1 << 1) - dolocks = 0; - if(flags & 1 << 2) - parsecolon = 0; - fmt += 3; - } - - /* not going to be printed? dont bother! */ - if(loglevel > CONSOLE_LOGLEVEL) - return 0; - - /* we essentially print the user's raw input to its own buffer, - later we will parse it and print out ANSI colors and what not */ - char buf[512]; - - vsnprintf(buf, 512, fmt, ap); - buf[512 - 1] = '\0'; - - size_t colon = 0; - if(parsecolon) { - for(; colon < strlen(buf); ++colon) { - if(buf[colon] == ':') - break; - } - } - - char tsbuf[64] = "\0"; - struct timeval time; - gettimeofday(&time, NULL); - snprintf(tsbuf, sizeof(tsbuf), "[%5ld.%06ld] ", - (long)time.tv_sec % 100000, (long)time.tv_usec); - - /* spin lock, at the cost of architecture portability - concurrency is something that we need to adjust for, and the - console will be scrambled and unreadable if we allow writing all - at the same time. I considered simply writing all at once, but - ended up just not caring enough to the point where spinlocks - prevail. */ - if(dolocks) - obtain_console_lock(); - - - /* we want to support stuff without colons, but frankly I havent - tested this at time of writing. will find out later */ - writeputs(ANSI_RESET ANSI_GREEN); - writeputs(tsbuf); - writeputs(ANSI_RESET); - if(parsecolon && buf[colon] == ':') { - writeputs(colors[loglevel]); - writeputs(ANSI_YELLOW); - write(STDOUT_FILENO, buf, colon); - writeputs(ANSI_RESET); - } - writeputs(colors[loglevel]); - if(colon && *(buf + colon)) { - writeputs(buf + colon); - } else { - writeputs(buf); - } - writeputs(ANSI_RESET); - write(STDOUT_FILENO, "\n", 1); - if(dolocks) - console_lock = 0; - return 0; -} - -void _panic(const char *fileorigin, - const int lineorigin, - const char *fmt, ...) -{ - char mode = PANICMODE_DIE; - int pid = getpid(); - if(fmt[0] == LOG_SOH_ASCII) { - mode = fmt[1]; - /* cannot respawn main thread */ - if(pid == mainpid && mode == PANICMODE_RESPAWN) - mode = PANICMODE_DIE; - fmt += 2; - } - -#define NOLOCK(loglevel) LOG_SOH "\3" loglevel - va_list ap; - va_start(ap, fmt); - char *_fmt = malloc(strlen(fmt) + 4 * sizeof(char)); - sprintf(_fmt, NOLOCK("1") "%s", fmt); - - void **backtrace_addresses = malloc(sizeof(void*) * 32); - int backtrace_count = backtrace(backtrace_addresses, 32); - char **backtrace_symbolnames = - backtrace_symbols(backtrace_addresses, backtrace_count); - - obtain_console_lock(); - - print(NOLOCK("5") "------------[ cut here ]------------"); - print(LOG_SOH "\7""0" "%s at %s:%d", mode_to_string[(int)mode], - fileorigin, lineorigin); - vaprint(_fmt, ap); - print(LOG_SOH "\7""7" "Call Trace:"); - for(int i = 0; i < backtrace_count; ++i) { - print(NOLOCK("7") " [0x%016x] %s", backtrace_addresses[i], - backtrace_symbolnames[i]); - } - if(mainpid == pid){ - print(NOLOCK("7") " <start of main thread>"); - } else { - print(NOLOCK("7") " <start of %s[%d]>", - subsystem_get_name(pid), pid); - } - - /* if we are going to die, we dont really need to clean up */ - if(mode == PANICMODE_DIE) { - kill(0, SIGTERM); - raise(SIGTERM); - exit(0); - } - - print(NOLOCK("5") "------------[ cut here ]------------"); - - console_lock = 0; - free(_fmt); - free(backtrace_symbolnames); - free(backtrace_addresses); - va_end(ap); - - if(mode == PANICMODE_DEBUGONLY) - return; - - if(pid != mainpid && mode == PANICMODE_RESPAWN) { - /* we want to let the main process handle the rest */ - subsystem_change_mode(pid, mode); - syscall(SYS_exit_group, 0); - } -} - -int print(const char *fmt, ...) -{ - int ret = 0; - va_list ap; - va_start(ap, fmt); - ret = vaprint(fmt, ap); - va_end(ap); - return ret; -} |