Hi,
I've noticed on some systems that the crash log command shows output
from the kernel log buffer which is not wrapped at the correct
location. All of the data from the buffer is present, but the display
is not from oldest to newest.
Crash uses the pointer log_start to determine the "current" location in
the log buffer. This isn't correct. log_start is the next location to
be read by the syslog interface. log_end is the pointer to the last
byte written by printk (well, last byte written +1) and this is what
should be used.
The quick fix is just to replace "log_start" with "log_end" in line
3141. The following tries to optimise the code a little and save
a gdb call some of the time.
Thanks,
Alan Tyson, HP.
--- crash-4.0-4.7/kernel.c 2007-09-25 16:01:56.000000000 +0100
+++ crash-4.0-4.7-at/kernel.c 2007-09-26 16:06:20.000000000 +0100
@@ -3111,7 +3111,7 @@ void
dump_log(int msg_level)
{
int i;
- ulong log_buf, log_start, logged_chars;
+ ulong log_buf, logged_chars;
char *buf;
char last;
ulong index;
@@ -3138,13 +3138,16 @@ dump_log(int msg_level)
buf = GETBUF(log_buf_len);
log_wrap = FALSE;
- get_symbol_data("log_start", sizeof(ulong), &log_start);
get_symbol_data("logged_chars", sizeof(ulong), &logged_chars);
readmem(log_buf, KVADDR, buf,
log_buf_len, "log_buf contents", FAULT_ON_ERROR);
- log_start &= log_buf_len-1;
- index = (logged_chars < log_buf_len) ? 0 : log_start;
+ if (logged_chars < log_buf_len) {
+ index = 0;
+ } else {
+ get_symbol_data("log_end", sizeof(ulong), &index);
+ index &= log_buf_len-1;
+ }
if ((logged_chars < log_buf_len) && (index == 0) && (buf[index]
== '<'))
loglevel = TRUE;