Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4fbd0a81 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 7bad2227 dd8f30cc
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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>
+7 −1
Original line number Diff line number Diff line
@@ -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 *, ...);

+18 −1
Original line number Diff line number Diff line
@@ -604,7 +604,7 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
		   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();
+34 −12
Original line number Diff line number Diff line
@@ -439,7 +439,7 @@ static char *kdb_read(char *buffer, size_t bufsize)
 *	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 @@ 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;
		}
@@ -711,7 +718,10 @@ int vkdb_printf(const char *fmt, va_list ap)
	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 @@ int vkdb_printf(const char *fmt, va_list ap)
			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;
+8 −8
Original line number Diff line number Diff line
@@ -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;
}

Loading