Skip to content

Commit 17b572e

Browse files
committed
kdb,vt_console: Fix missed data due to pager overruns
It is possible to miss data when using the kdb pager. The kdb pager does not pay attention to the maximum column constraint of the screen or serial terminal. This result is not incrementing the shown lines correctly and the pager will print more lines that fit on the screen. Obviously that is less than useful when using a VGA console where you cannot scroll back. The pager will now look at the kdb_buffer string to see how many characters are printed. It might not be perfect considering you can output ASCII that might move the cursor position, but it is a substantially better approximation for viewing dmesg and trace logs. This also means that the vt screen needs to set the kdb COLUMNS variable. Cc: <stable@vger.kernel.org> Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
1 parent d1871b3 commit 17b572e

2 files changed

Lines changed: 41 additions & 5 deletions

File tree

drivers/tty/vt/vt.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3475,6 +3475,19 @@ int con_debug_enter(struct vc_data *vc)
34753475
kdb_set(2, setargs);
34763476
}
34773477
}
3478+
if (vc->vc_cols < 999) {
3479+
int colcount;
3480+
char cols[4];
3481+
const char *setargs[3] = {
3482+
"set",
3483+
"COLUMNS",
3484+
cols,
3485+
};
3486+
if (kdbgetintenv(setargs[0], &colcount)) {
3487+
snprintf(cols, 4, "%i", vc->vc_cols);
3488+
kdb_set(2, setargs);
3489+
}
3490+
}
34783491
#endif /* CONFIG_KGDB_KDB */
34793492
return ret;
34803493
}

kernel/debug/kdb/kdb_io.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ int vkdb_printf(const char *fmt, va_list ap)
552552
{
553553
int diag;
554554
int linecount;
555+
int colcount;
555556
int logging, saved_loglevel = 0;
556557
int saved_trap_printk;
557558
int got_printf_lock = 0;
@@ -584,6 +585,10 @@ int vkdb_printf(const char *fmt, va_list ap)
584585
if (diag || linecount <= 1)
585586
linecount = 24;
586587

588+
diag = kdbgetintenv("COLUMNS", &colcount);
589+
if (diag || colcount <= 1)
590+
colcount = 80;
591+
587592
diag = kdbgetintenv("LOGGING", &logging);
588593
if (diag)
589594
logging = 0;
@@ -690,7 +695,7 @@ int vkdb_printf(const char *fmt, va_list ap)
690695
gdbstub_msg_write(kdb_buffer, retlen);
691696
} else {
692697
if (dbg_io_ops && !dbg_io_ops->is_console) {
693-
len = strlen(kdb_buffer);
698+
len = retlen;
694699
cp = kdb_buffer;
695700
while (len--) {
696701
dbg_io_ops->write_char(*cp);
@@ -709,11 +714,29 @@ int vkdb_printf(const char *fmt, va_list ap)
709714
printk(KERN_INFO "%s", kdb_buffer);
710715
}
711716

712-
if (KDB_STATE(PAGER) && strchr(kdb_buffer, '\n'))
713-
kdb_nextline++;
717+
if (KDB_STATE(PAGER)) {
718+
/*
719+
* Check printed string to decide how to bump the
720+
* kdb_nextline to control when the more prompt should
721+
* show up.
722+
*/
723+
int got = 0;
724+
len = retlen;
725+
while (len--) {
726+
if (kdb_buffer[len] == '\n') {
727+
kdb_nextline++;
728+
got = 0;
729+
} else if (kdb_buffer[len] == '\r') {
730+
got = 0;
731+
} else {
732+
got++;
733+
}
734+
}
735+
kdb_nextline += got / (colcount + 1);
736+
}
714737

715738
/* check for having reached the LINES number of printed lines */
716-
if (kdb_nextline == linecount) {
739+
if (kdb_nextline >= linecount) {
717740
char buf1[16] = "";
718741

719742
/* Watch out for recursion here. Any routine that calls
@@ -765,7 +788,7 @@ int vkdb_printf(const char *fmt, va_list ap)
765788
kdb_grepping_flag = 0;
766789
kdb_printf("\n");
767790
} else if (buf1[0] == ' ') {
768-
kdb_printf("\n");
791+
kdb_printf("\r");
769792
suspend_grep = 1; /* for this recursion */
770793
} else if (buf1[0] == '\n') {
771794
kdb_nextline = linecount - 1;

0 commit comments

Comments
 (0)