mirror of
https://github.com/torvalds/linux.git
synced 2024-12-25 20:32:22 +00:00
KGDB/KDB New:
* KDB: improved searching * No longer enter debug core on panic if panic timeout is set KGDB/KDB regressions / cleanups * fix pdf doc build errors * prevent junk characters on kdb console from printk levels -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJU5qxHAAoJEIciOldedpOjliYP/izuoNZ/EtjjeihOL44ic0o0 cmvdSc/ovR/mO4fbDpftMB0nhzclgRyAvr+VTPd3Bp5Poh+wJ0ZKu1R7f+ioSN73 Y4ek9PJqPSBQr+JdfPK80N56Choeni48bsC6up12i3BTfXobj81zlu4Sj0SMOoHq IkFkB7soRuiFoc5IkKMvf3N3T9j1PnEULmHteNDRr0hTmGipEzkD3zocc/bRFV/l JTZRzIMGBNGnF01DPLDcuvbu0wGBh6ADMBLtx5v1UrhV32ypfJq2bgxFvgM/AXn2 3VG4HcRbVsGmlBOahFR6X0DE/WAplw01yu1EabR2EWUePyz41cnSkxl4nR/NNhwz qMbr3uzu1iWUTTz5ySRcWxSuRRCihVQqNk6p+y21N/jY/5cr2jI03qJm0zZ/ObqL VUcPE7CfdcriCDXoepgXZE4XfX65Jf5tUiyiCj+1ds05ab5qHELIwKOZdjU2ON1b pb2ElPngGSEEoU/eSDgP2RVJ9Mk/k5s2TxaPXVJNkeWGNxPU5HtCytZpVI5hckbP /NZWTtyUDZ85is8cWUkHEdjnQ+CdzaA/FwJEqnB0or2is91mo8uBxP5BvdqPnPL0 QdPPnVgD72dumXfJpH2HY3DdUs24LaP0vgSO8ELKgfA67nprS+5xztNSd8ekNnhF 4wMhZbuAhB68E6bA0X7G =TH0R -----END PGP SIGNATURE----- Merge tag 'for_linux-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb Pull kgdb/kdb updates from Jason Wessel: "KGDB/KDB New: - KDB: improved searching - No longer enter debug core on panic if panic timeout is set KGDB/KDB regressions / cleanups - fix pdf doc build errors - prevent junk characters on kdb console from printk levels" * tag 'for_linux-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb: kgdb, docs: Fix <para> pdfdocs build errors debug: prevent entering debug mode on panic/exception. kdb: Const qualifier for kdb_getstr's prompt argument kdb: Provide forward search at more prompt kdb: Fix a prompt management bug when using | grep kdb: Remove stack dump when entering kgdb due to NMI kdb: Avoid printing KERN_ levels to consoles kdb: Fix off by one error in kdb_cpu() kdb: fix incorrect counts in KDB summary command output
This commit is contained in:
commit
4fbd0a81a0
@ -197,6 +197,7 @@
|
||||
may be configured as a kernel built-in or a kernel loadable module.
|
||||
You can only make use of <constant>kgdbwait</constant> and early
|
||||
debugging if you build kgdboc into the kernel as a built-in.
|
||||
</para>
|
||||
<para>Optionally you can elect to activate kms (Kernel Mode
|
||||
Setting) integration. When you use kms with kgdboc and you have a
|
||||
video driver that has atomic mode setting hooks, it is possible to
|
||||
@ -206,7 +207,6 @@
|
||||
crashes or doing analysis of memory with kdb while allowing the
|
||||
full graphics console applications to run.
|
||||
</para>
|
||||
</para>
|
||||
<sect2 id="kgdbocArgs">
|
||||
<title>kgdboc arguments</title>
|
||||
<para>Usage: <constant>kgdboc=[kms][[,]kbd][[,]serial_device][,baud]</constant></para>
|
||||
@ -284,7 +284,6 @@
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
</sect3>
|
||||
<para>NOTE: Kgdboc does not support interrupting the target via the
|
||||
gdb remote protocol. You must manually send a sysrq-g unless you
|
||||
have a proxy that splits console output to a terminal program.
|
||||
@ -305,6 +304,7 @@
|
||||
as well as on the initial connect, or to use a debugger proxy that
|
||||
allows an unmodified gdb to do the debugging.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="kgdbwait">
|
||||
@ -350,12 +350,12 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
<para>IMPORTANT NOTE: You cannot use kgdboc + kgdbcon on a tty that is an
|
||||
active system console. An example of incorrect usage is <constant>console=ttyS0,115200 kgdboc=ttyS0 kgdbcon</constant>
|
||||
</para>
|
||||
<para>It is possible to use this option with kgdboc on a tty that is not a system console.
|
||||
</para>
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="kgdbreboot">
|
||||
<title>Run time parameter: kgdbreboot</title>
|
||||
|
@ -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 *, ...);
|
||||
|
||||
|
@ -604,7 +604,7 @@ return_normal:
|
||||
online_cpus)
|
||||
cpu_relax();
|
||||
if (!time_left)
|
||||
pr_crit("KGDB: Timed out waiting for secondary CPUs.\n");
|
||||
pr_crit("Timed out waiting for secondary CPUs.\n");
|
||||
|
||||
/*
|
||||
* At this point the primary processor is completely
|
||||
@ -696,6 +696,14 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs)
|
||||
|
||||
if (arch_kgdb_ops.enable_nmi)
|
||||
arch_kgdb_ops.enable_nmi(0);
|
||||
/*
|
||||
* Avoid entering the debugger if we were triggered due to an oops
|
||||
* but panic_timeout indicates the system should automatically
|
||||
* reboot on panic. We don't want to get stuck waiting for input
|
||||
* on such systems, especially if its "just" an oops.
|
||||
*/
|
||||
if (signo != SIGTRAP && panic_timeout)
|
||||
return 1;
|
||||
|
||||
memset(ks, 0, sizeof(struct kgdb_state));
|
||||
ks->cpu = raw_smp_processor_id();
|
||||
@ -828,6 +836,15 @@ static int kgdb_panic_event(struct notifier_block *self,
|
||||
unsigned long val,
|
||||
void *data)
|
||||
{
|
||||
/*
|
||||
* Avoid entering the debugger if we were triggered due to a panic
|
||||
* We don't want to get stuck waiting for input from user in such case.
|
||||
* panic_timeout indicates the system should automatically
|
||||
* reboot on panic.
|
||||
*/
|
||||
if (panic_timeout)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (dbg_kdb_mode)
|
||||
kdb_printf("PANIC: %s\n", (char *)data);
|
||||
kgdb_breakpoint();
|
||||
|
@ -439,7 +439,7 @@ poll_again:
|
||||
* substituted for %d, %x or %o in the prompt.
|
||||
*/
|
||||
|
||||
char *kdb_getstr(char *buffer, size_t bufsize, char *prompt)
|
||||
char *kdb_getstr(char *buffer, size_t bufsize, const char *prompt)
|
||||
{
|
||||
if (prompt && kdb_prompt_str != prompt)
|
||||
strncpy(kdb_prompt_str, prompt, CMD_BUFLEN);
|
||||
@ -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;
|
||||
@ -680,6 +680,12 @@ int vkdb_printf(const char *fmt, va_list ap)
|
||||
size_avail = sizeof(kdb_buffer) - len;
|
||||
goto kdb_print_out;
|
||||
}
|
||||
if (kdb_grepping_flag >= KDB_GREPPING_FLAG_SEARCH)
|
||||
/*
|
||||
* This was a interactive search (using '/' at more
|
||||
* prompt) and it has completed. Clear the flag.
|
||||
*/
|
||||
kdb_grepping_flag = 0;
|
||||
/*
|
||||
* at this point the string is a full line and
|
||||
* should be printed, up to the null.
|
||||
@ -691,19 +697,20 @@ kdb_printit:
|
||||
* 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;
|
||||
}
|
||||
@ -711,7 +718,10 @@ kdb_printit:
|
||||
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)) {
|
||||
@ -794,11 +804,23 @@ kdb_printit:
|
||||
kdb_nextline = linecount - 1;
|
||||
kdb_printf("\r");
|
||||
suspend_grep = 1; /* for this recursion */
|
||||
} else if (buf1[0] == '/' && !kdb_grepping_flag) {
|
||||
kdb_printf("\r");
|
||||
kdb_getstr(kdb_grep_string, KDB_GREP_STRLEN,
|
||||
kdbgetenv("SEARCHPROMPT") ?: "search> ");
|
||||
*strchrnul(kdb_grep_string, '\n') = '\0';
|
||||
kdb_grepping_flag += KDB_GREPPING_FLAG_SEARCH;
|
||||
suspend_grep = 1; /* for this recursion */
|
||||
} else if (buf1[0] && buf1[0] != '\n') {
|
||||
/* user hit something other than enter */
|
||||
suspend_grep = 1; /* for this recursion */
|
||||
kdb_printf("\nOnly 'q' or 'Q' are processed at more "
|
||||
"prompt, input ignored\n");
|
||||
if (buf1[0] != '/')
|
||||
kdb_printf(
|
||||
"\nOnly 'q', 'Q' or '/' are processed at "
|
||||
"more prompt, input ignored\n");
|
||||
else
|
||||
kdb_printf("\n'/' cannot be used during | "
|
||||
"grep filtering, input ignored\n");
|
||||
} else if (kdb_grepping_flag) {
|
||||
/* user hit enter */
|
||||
suspend_grep = 1; /* for this recursion */
|
||||
@ -844,7 +866,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;
|
||||
|
@ -50,8 +50,7 @@
|
||||
static int kdb_cmd_enabled = CONFIG_KDB_DEFAULT_ENABLE;
|
||||
module_param_named(cmd_enable, kdb_cmd_enabled, int, 0600);
|
||||
|
||||
#define GREP_LEN 256
|
||||
char kdb_grep_string[GREP_LEN];
|
||||
char kdb_grep_string[KDB_GREP_STRLEN];
|
||||
int kdb_grepping_flag;
|
||||
EXPORT_SYMBOL(kdb_grepping_flag);
|
||||
int kdb_grep_leading;
|
||||
@ -870,7 +869,7 @@ static void parse_grep(const char *str)
|
||||
len = strlen(cp);
|
||||
if (!len)
|
||||
return;
|
||||
if (len >= GREP_LEN) {
|
||||
if (len >= KDB_GREP_STRLEN) {
|
||||
kdb_printf("search string too long\n");
|
||||
return;
|
||||
}
|
||||
@ -915,13 +914,12 @@ int kdb_parse(const char *cmdstr)
|
||||
char *cp;
|
||||
char *cpp, quoted;
|
||||
kdbtab_t *tp;
|
||||
int i, escaped, ignore_errors = 0, check_grep;
|
||||
int i, escaped, ignore_errors = 0, check_grep = 0;
|
||||
|
||||
/*
|
||||
* First tokenize the command string.
|
||||
*/
|
||||
cp = (char *)cmdstr;
|
||||
kdb_grepping_flag = check_grep = 0;
|
||||
|
||||
if (KDB_FLAG(CMD_INTERRUPT)) {
|
||||
/* Previous command was interrupted, newline must not
|
||||
@ -1247,7 +1245,6 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
|
||||
kdb_printf("due to NonMaskable Interrupt @ "
|
||||
kdb_machreg_fmt "\n",
|
||||
instruction_pointer(regs));
|
||||
kdb_dumpregs(regs);
|
||||
break;
|
||||
case KDB_REASON_SSTEP:
|
||||
case KDB_REASON_BREAK:
|
||||
@ -1281,6 +1278,9 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
|
||||
*/
|
||||
kdb_nextline = 1;
|
||||
KDB_STATE_CLEAR(SUPPRESS);
|
||||
kdb_grepping_flag = 0;
|
||||
/* ensure the old search does not leak into '/' commands */
|
||||
kdb_grep_string[0] = '\0';
|
||||
|
||||
cmdbuf = cmd_cur;
|
||||
*cmdbuf = '\0';
|
||||
@ -2256,7 +2256,7 @@ static int kdb_cpu(int argc, const char **argv)
|
||||
/*
|
||||
* Validate cpunum
|
||||
*/
|
||||
if ((cpunum > NR_CPUS) || !kgdb_info[cpunum].enter_kgdb)
|
||||
if ((cpunum >= CONFIG_NR_CPUS) || !kgdb_info[cpunum].enter_kgdb)
|
||||
return KDB_BADCPUNUM;
|
||||
|
||||
dbg_switch_cpu = cpunum;
|
||||
@ -2583,7 +2583,7 @@ static int kdb_summary(int argc, const char **argv)
|
||||
#define K(x) ((x) << (PAGE_SHIFT - 10))
|
||||
kdb_printf("\nMemTotal: %8lu kB\nMemFree: %8lu kB\n"
|
||||
"Buffers: %8lu kB\n",
|
||||
val.totalram, val.freeram, val.bufferram);
|
||||
K(val.totalram), K(val.freeram), K(val.bufferram));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,9 @@ extern int kdb_main_loop(kdb_reason_t, kdb_reason_t,
|
||||
|
||||
/* Miscellaneous functions and data areas */
|
||||
extern int kdb_grepping_flag;
|
||||
#define KDB_GREPPING_FLAG_SEARCH 0x8000
|
||||
extern char kdb_grep_string[];
|
||||
#define KDB_GREP_STRLEN 256
|
||||
extern int kdb_grep_leading;
|
||||
extern int kdb_grep_trailing;
|
||||
extern char *kdb_cmds[];
|
||||
@ -209,7 +211,7 @@ extern void kdb_ps1(const struct task_struct *p);
|
||||
extern void kdb_print_nameval(const char *name, unsigned long val);
|
||||
extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info);
|
||||
extern void kdb_meminfo_proc_show(void);
|
||||
extern char *kdb_getstr(char *, size_t, char *);
|
||||
extern char *kdb_getstr(char *, size_t, const char *);
|
||||
extern void kdb_gdb_state_pass(char *buf);
|
||||
|
||||
/* Defines for kdb_symbol_print */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user