Skip to content

Commit

Permalink
kdb: Avoid printing KERN_ levels to consoles
Browse files Browse the repository at this point in the history
Currently when kdb traps printk messages then the raw log level prefix
(consisting of '\001' followed by a numeral) does not get stripped off
before the message is issued to the various I/O handlers supported by
kdb. This causes annoying visual noise as well as causing problems
grepping for ^. It is also a change of behaviour compared to normal usage
of printk() usage. For example <SysRq>-h ends up with different output to
that of kdb's "sr h".

This patch addresses the problem by stripping log levels from messages
before they are issued to the I/O handlers. printk() which can also
act as an i/o handler in some cases is special cased; if the caller
provided a log level then the prefix will be preserved when sent to
printk().

The addition of non-printable characters to the output of kdb commands is a
regression, albeit and extremely elderly one, introduced by commit
04d2c8c ("printk: convert the format for KERN_<LEVEL> to a 2 byte
pattern"). Note also that this patch does *not* restore the original
behaviour from v3.5. Instead it makes printk() from within a kdb command
display the message without any prefix (i.e. like printk() normally does).

Signed-off-by: Daniel Thompson <[email protected]>
Cc: Joe Perches <[email protected]>
Cc: [email protected]
Signed-off-by: Jason Wessel <[email protected]>
  • Loading branch information
daniel-thompson authored and jwessel committed Feb 19, 2015
1 parent df0036d commit f7d4ca8
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
8 changes: 7 additions & 1 deletion include/linux/kdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,14 @@ typedef enum {
KDB_REASON_SYSTEM_NMI, /* In NMI due to SYSTEM cmd; regs valid */
} kdb_reason_t;

enum kdb_msgsrc {
KDB_MSGSRC_INTERNAL, /* direct call to kdb_printf() */
KDB_MSGSRC_PRINTK, /* trapped from printk() */
};

extern int kdb_trap_printk;
extern __printf(1, 0) int vkdb_printf(const char *fmt, va_list args);
extern __printf(2, 0) int vkdb_printf(enum kdb_msgsrc src, const char *fmt,
va_list args);
extern __printf(1, 2) int kdb_printf(const char *, ...);
typedef __printf(1, 2) int (*kdb_printf_t)(const char *, ...);

Expand Down
22 changes: 13 additions & 9 deletions kernel/debug/kdb/kdb_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ static int kdb_search_string(char *searched, char *searchfor)
return 0;
}

int vkdb_printf(const char *fmt, va_list ap)
int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap)
{
int diag;
int linecount;
Expand Down Expand Up @@ -691,27 +691,31 @@ int vkdb_printf(const char *fmt, va_list ap)
* Write to all consoles.
*/
retlen = strlen(kdb_buffer);
cp = (char *) printk_skip_level(kdb_buffer);
if (!dbg_kdb_mode && kgdb_connected) {
gdbstub_msg_write(kdb_buffer, retlen);
gdbstub_msg_write(cp, retlen - (cp - kdb_buffer));
} else {
if (dbg_io_ops && !dbg_io_ops->is_console) {
len = retlen;
cp = kdb_buffer;
len = retlen - (cp - kdb_buffer);
cp2 = cp;
while (len--) {
dbg_io_ops->write_char(*cp);
cp++;
dbg_io_ops->write_char(*cp2);
cp2++;
}
}
while (c) {
c->write(c, kdb_buffer, retlen);
c->write(c, cp, retlen - (cp - kdb_buffer));
touch_nmi_watchdog();
c = c->next;
}
}
if (logging) {
saved_loglevel = console_loglevel;
console_loglevel = CONSOLE_LOGLEVEL_SILENT;
printk(KERN_INFO "%s", kdb_buffer);
if (printk_get_level(kdb_buffer) || src == KDB_MSGSRC_PRINTK)
printk("%s", kdb_buffer);
else
pr_info("%s", kdb_buffer);
}

if (KDB_STATE(PAGER)) {
Expand Down Expand Up @@ -844,7 +848,7 @@ int kdb_printf(const char *fmt, ...)
int r;

va_start(ap, fmt);
r = vkdb_printf(fmt, ap);
r = vkdb_printf(KDB_MSGSRC_INTERNAL, fmt, ap);
va_end(ap);

return r;
Expand Down
2 changes: 1 addition & 1 deletion kernel/printk/printk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1811,7 +1811,7 @@ int vprintk_default(const char *fmt, va_list args)

#ifdef CONFIG_KGDB_KDB
if (unlikely(kdb_trap_printk)) {
r = vkdb_printf(fmt, args);
r = vkdb_printf(KDB_MSGSRC_PRINTK, fmt, args);
return r;
}
#endif
Expand Down

0 comments on commit f7d4ca8

Please sign in to comment.