"syslog" debugger command: By default it now ignores the output added to the

syslog in the current KDL session. Added option "-k" for the former behavior.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35976 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2010-03-27 18:13:11 +00:00
parent b5489c54b0
commit c81e68b2b2

View File

@ -99,7 +99,11 @@ static sem_id sSyslogNotify = -1;
static struct syslog_message* sSyslogMessage;
static struct ring_buffer* sSyslogBuffer;
static size_t sSyslogBufferOffset = 0;
// (relative) buffer offset of the yet unsent syslog messages
static bool sSyslogDropped = false;
static size_t sSyslogDebuggerOffset = 0;
// (relative) buffer offset of the kernel debugger messages of the current
// KDL session
static const char* sCurrentKernelDebuggerMessagePrefix;
static const char* sCurrentKernelDebuggerMessage;
@ -801,6 +805,8 @@ kernel_debugger_loop(const char* messagePrefix, const char* message,
if (sCurrentKernelDebuggerMessage != NULL)
va_copy(sCurrentKernelDebuggerMessageArgs, args);
sSyslogDebuggerOffset = ring_buffer_readable(sSyslogBuffer);
print_kernel_debugger_message();
kprintf("Welcome to Kernel Debugging Land...\n");
@ -1051,50 +1057,77 @@ cmd_dump_syslog(int argc, char** argv)
return 0;
}
bool currentOnly = false;
if (argc > 1) {
if (!strcmp(argv[1], "-n"))
currentOnly = true;
else {
print_debugger_command_usage(argv[0]);
return 0;
}
bool unsentOnly = false;
bool ignoreKDLOutput = true;
int argi = 1;
for (; argi < argc; argi++) {
if (strcmp(argv[argi], "-n") == 0)
unsentOnly = true;
else if (strcmp(argv[argi], "-k") == 0)
ignoreKDLOutput = false;
else
break;
}
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");
if (argi < argc) {
print_debugger_command_usage(argv[0]);
return 0;
}
// break it down to lines to make it grep'able
size_t debuggerOffset = sSyslogDebuggerOffset;
size_t start = unsentOnly ? sSyslogBufferOffset : 0;
size_t end = ignoreKDLOutput
? debuggerOffset : ring_buffer_readable(sSyslogBuffer);
// allocate a buffer for processing the syslog output
size_t bufferSize = 1024;
char* buffer = (char*)debug_malloc(bufferSize);
char stackBuffer[64];
if (buffer == NULL) {
buffer = stackBuffer;
bufferSize = sizeof(stackBuffer);
}
// filter the output
bool newLine = false;
char line[256];
size_t linePos = 0;
for (uint32 i = start; i < end; i++) {
char c = sSyslogBuffer->buffer[i % sSyslogBuffer->size];
if (c == '\0' || (uint8)c == 0xcc)
continue;
while (start < end) {
size_t bytesRead = ring_buffer_peek(sSyslogBuffer, start, buffer,
std::min(end - start, bufferSize - 1));
if (bytesRead == 0)
break;
start += bytesRead;
line[linePos++] = c;
newLine = false;
// remove '\0' and 0xcc
size_t toPrint = 0;
for (size_t i = 0; i < bytesRead; i++) {
if (buffer[i] != '\0' && buffer[i] != 0xcc)
buffer[toPrint++] = buffer[i];
}
if (c == '\n' || linePos == sizeof(line) - 1) {
newLine = c == '\n';
line[linePos] = '\0';
linePos = 0;
kprintf(line);
if (toPrint > 0) {
newLine = buffer[toPrint - 1] == '\n';
buffer[toPrint] = '\0';
kputs(buffer);
}
if (debuggerOffset > sSyslogDebuggerOffset) {
// Our output caused older syslog output to be evicted from the
// syslog buffer. We need to adjust our offsets accordingly. Note,
// this can still go wrong, if the buffer was already full and more
// was written to it than we have processed, but we can't help that.
size_t diff = debuggerOffset - sSyslogDebuggerOffset;
start -= std::min(start, diff);
end -= std::min(end, diff);
debuggerOffset = sSyslogDebuggerOffset;
}
}
if (!newLine)
kprintf("\n");
kputs("\n");
if (buffer != stackBuffer)
debug_free(buffer);
return 0;
}
@ -1237,6 +1270,8 @@ syslog_write(const char* text, int32 length, bool notify)
sSyslogDropped = true;
} else
sSyslogBufferOffset -= toDrop;
sSyslogDebuggerOffset -= std::min(toDrop, sSyslogDebuggerOffset);
}
ring_buffer_write(sSyslogBuffer, (uint8*)text, length);
@ -1336,7 +1371,8 @@ syslog_init_post_vm(struct kernel_args* args)
add_debugger_command_etc("syslog", &cmd_dump_syslog,
"Dumps the syslog buffer.",
"[-n]\nDumps the whole syslog buffer, or, if -n is specified, only "
"[ \"-n\" ] [ \"-k\" ]\n"
"Dumps the whole syslog buffer, or, if -k is specified, only "
"the part that hasn't been sent yet.\n", 0);
add_debugger_command("serial_input", &cmd_serial_input,