From 0b46f622d157d4313672dcd6220fbec0749e268b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 30 Jul 2008 10:03:22 +0000 Subject: [PATCH] * Made struct ring_buffer public (within the kernel). * Added "syslog" command that dumps the contents of the syslog ring buffer into KDL. Use the '-n' option to only show what hasn't been sent to the syslog daemon yet. * When entering the kernel debugger, the current thread ID and name are also printed (not only the current CPU). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26684 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/util/ring_buffer.h | 8 ++- src/system/kernel/debug/debug.cpp | 75 +++++++++++++++++++++-- src/system/kernel/util/ring_buffer.cpp | 11 +--- 3 files changed, 79 insertions(+), 15 deletions(-) diff --git a/headers/private/kernel/util/ring_buffer.h b/headers/private/kernel/util/ring_buffer.h index fac3deb32a..973d4c7519 100644 --- a/headers/private/kernel/util/ring_buffer.h +++ b/headers/private/kernel/util/ring_buffer.h @@ -9,7 +9,13 @@ #include -struct ring_buffer; +struct ring_buffer { + int32 first; + int32 in; + int32 size; + uint8 buffer[0]; +}; + #ifdef __cplusplus extern "C" { diff --git a/src/system/kernel/debug/debug.cpp b/src/system/kernel/debug/debug.cpp index a88b4e7c15..76d1dbff00 100644 --- a/src/system/kernel/debug/debug.cpp +++ b/src/system/kernel/debug/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de + * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001, Travis Geiselbrecht. All rights reserved. @@ -650,17 +650,20 @@ kernel_debugger_loop(void) int32 previousCPU = sDebuggerOnCPU; sDebuggerOnCPU = smp_get_current_cpu(); - // set a few temporary debug variables + kprintf("Welcome to Kernel Debugging Land...\n"); + if (struct thread* thread = thread_get_current_thread()) { + // set a few temporary debug variables set_debug_variable("_thread", (uint64)(addr_t)thread); set_debug_variable("_threadID", thread->id); set_debug_variable("_team", (uint64)(addr_t)thread->team); set_debug_variable("_teamID", thread->team->id); set_debug_variable("_cpu", sDebuggerOnCPU); - } - kprintf("Welcome to Kernel Debugging Land...\n"); - kprintf("Running on CPU %ld\n", sDebuggerOnCPU); + kprintf("Thread %ld \"%s\" running on CPU %ld\n", thread->id, + thread->name, sDebuggerOnCPU); + } else + kprintf("Running on CPU %ld\n", sDebuggerOnCPU); int32 continuableLine = -1; // Index of the previous command line, if the command returned @@ -718,6 +721,63 @@ cmd_dump_kdl_message(int argc, char **argv) } +static int +cmd_dump_syslog(int argc, char **argv) +{ + if (!sSyslogOutputEnabled) { + kprintf("Syslog is not enabled.\n"); + return 0; + } + + bool currentOnly = false; + if (argc > 1) { + if (!strcmp(argv[1], "-n")) + currentOnly = true; + else { + print_debugger_command_usage(argv[0]); + return 0; + } + } + + uint32 start = sSyslogBuffer->first; + size_t end = start + sSyslogBuffer->in; + if (!currentOnly) { + // Start the buffer after the current end (we don't really know if + // this part has been written to already). + start = (start + sSyslogBuffer->in) % sSyslogBuffer->size; + end = start + sSyslogBuffer->size; + } else if (!ring_buffer_readable(sSyslogBuffer)) { + kprintf("Syslog is empty.\n"); + return 0; + } + + // break it down to lines to make it grep'able + + bool newLine = false; + char line[256]; + size_t linePos = 0; + for (int32 i = start; i < end; i++) { + char c = sSyslogBuffer->buffer[i % sSyslogBuffer->size]; + if (c == '\0' || (uint8)c == 0xcc) + continue; + + line[linePos++] = c; + newLine = false; + + if (c == '\n' || linePos == sizeof(line) - 1) { + newLine = c == '\n'; + line[linePos] = '\0'; + linePos = 0; + kprintf(line); + } + } + if (!newLine) + kprintf("\n"); + + return 0; +} + + static status_t syslog_sender(void *data) { @@ -879,6 +939,11 @@ syslog_init(struct kernel_args *args) "Welcome to syslog debug output!\nHaiku revision: %lu\n", get_haiku_revision()); syslog_write(revisionBuffer, length); + + add_debugger_command_etc("syslog", &cmd_dump_syslog, + "Dumps the syslog buffer.\n", + "[-n]\nDumps the whole syslog buffer, or, if -n is specified, only " + "the part that hasn't been send yet.\n", 0); return B_OK; err2: diff --git a/src/system/kernel/util/ring_buffer.cpp b/src/system/kernel/util/ring_buffer.cpp index 359500a112..2e216047ab 100644 --- a/src/system/kernel/util/ring_buffer.cpp +++ b/src/system/kernel/util/ring_buffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -18,7 +18,7 @@ #define user_memcpy(x...) (memcpy(x), B_OK) #endif -/** This is a light-weight ring_buffer implementation. +/*! This is a light-weight ring_buffer implementation. * It does not provide any locking - you are supposed to ensure thread-safety * with the restrictions you choose. Unless you are passing in unsafe buffers, * the functions are safe to be called with interrupts turned off as well (not @@ -26,13 +26,6 @@ * They also don't use malloc() or any kind of locking after initialization. */ -struct ring_buffer { - int32 first; - int32 in; - int32 size; - uint8 buffer[0]; -}; - static inline int32 space_left_in_buffer(struct ring_buffer *buffer)