diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-20 18:13:29 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-20 18:13:29 -0500 |
commit | 4fbd0a81a0059f22d06780de96e73f9ddbccd8a4 (patch) | |
tree | da867d35f345180234e2243df833eb6237c12d73 /kernel | |
parent | 7bad2227f639723230dbc40fe32e16101321b5b7 (diff) | |
parent | dd8f30cc0550f36861ddfa42c27cc5c580b0bf8c (diff) |
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
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/debug/debug_core.c | 19 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_io.c | 46 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_main.c | 16 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_private.h | 4 | ||||
-rw-r--r-- | kernel/printk/printk.c | 2 |
5 files changed, 64 insertions, 23 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 07ce18ca71e0..0874e2edd275 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
@@ -604,7 +604,7 @@ return_normal: | |||
604 | online_cpus) | 604 | online_cpus) |
605 | cpu_relax(); | 605 | cpu_relax(); |
606 | if (!time_left) | 606 | if (!time_left) |
607 | pr_crit("KGDB: Timed out waiting for secondary CPUs.\n"); | 607 | pr_crit("Timed out waiting for secondary CPUs.\n"); |
608 | 608 | ||
609 | /* | 609 | /* |
610 | * At this point the primary processor is completely | 610 | * 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) | |||
696 | 696 | ||
697 | if (arch_kgdb_ops.enable_nmi) | 697 | if (arch_kgdb_ops.enable_nmi) |
698 | arch_kgdb_ops.enable_nmi(0); | 698 | arch_kgdb_ops.enable_nmi(0); |
699 | /* | ||
700 | * Avoid entering the debugger if we were triggered due to an oops | ||
701 | * but panic_timeout indicates the system should automatically | ||
702 | * reboot on panic. We don't want to get stuck waiting for input | ||
703 | * on such systems, especially if its "just" an oops. | ||
704 | */ | ||
705 | if (signo != SIGTRAP && panic_timeout) | ||
706 | return 1; | ||
699 | 707 | ||
700 | memset(ks, 0, sizeof(struct kgdb_state)); | 708 | memset(ks, 0, sizeof(struct kgdb_state)); |
701 | ks->cpu = raw_smp_processor_id(); | 709 | ks->cpu = raw_smp_processor_id(); |
@@ -828,6 +836,15 @@ static int kgdb_panic_event(struct notifier_block *self, | |||
828 | unsigned long val, | 836 | unsigned long val, |
829 | void *data) | 837 | void *data) |
830 | { | 838 | { |
839 | /* | ||
840 | * Avoid entering the debugger if we were triggered due to a panic | ||
841 | * We don't want to get stuck waiting for input from user in such case. | ||
842 | * panic_timeout indicates the system should automatically | ||
843 | * reboot on panic. | ||
844 | */ | ||
845 | if (panic_timeout) | ||
846 | return NOTIFY_DONE; | ||
847 | |||
831 | if (dbg_kdb_mode) | 848 | if (dbg_kdb_mode) |
832 | kdb_printf("PANIC: %s\n", (char *)data); | 849 | kdb_printf("PANIC: %s\n", (char *)data); |
833 | kgdb_breakpoint(); | 850 | kgdb_breakpoint(); |
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 7c70812caea5..fc1ef736253c 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c | |||
@@ -439,7 +439,7 @@ poll_again: | |||
439 | * substituted for %d, %x or %o in the prompt. | 439 | * substituted for %d, %x or %o in the prompt. |
440 | */ | 440 | */ |
441 | 441 | ||
442 | char *kdb_getstr(char *buffer, size_t bufsize, char *prompt) | 442 | char *kdb_getstr(char *buffer, size_t bufsize, const char *prompt) |
443 | { | 443 | { |
444 | if (prompt && kdb_prompt_str != prompt) | 444 | if (prompt && kdb_prompt_str != prompt) |
445 | strncpy(kdb_prompt_str, prompt, CMD_BUFLEN); | 445 | strncpy(kdb_prompt_str, prompt, CMD_BUFLEN); |
@@ -548,7 +548,7 @@ static int kdb_search_string(char *searched, char *searchfor) | |||
548 | return 0; | 548 | return 0; |
549 | } | 549 | } |
550 | 550 | ||
551 | int vkdb_printf(const char *fmt, va_list ap) | 551 | int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) |
552 | { | 552 | { |
553 | int diag; | 553 | int diag; |
554 | int linecount; | 554 | int linecount; |
@@ -680,6 +680,12 @@ int vkdb_printf(const char *fmt, va_list ap) | |||
680 | size_avail = sizeof(kdb_buffer) - len; | 680 | size_avail = sizeof(kdb_buffer) - len; |
681 | goto kdb_print_out; | 681 | goto kdb_print_out; |
682 | } | 682 | } |
683 | if (kdb_grepping_flag >= KDB_GREPPING_FLAG_SEARCH) | ||
684 | /* | ||
685 | * This was a interactive search (using '/' at more | ||
686 | * prompt) and it has completed. Clear the flag. | ||
687 | */ | ||
688 | kdb_grepping_flag = 0; | ||
683 | /* | 689 | /* |
684 | * at this point the string is a full line and | 690 | * at this point the string is a full line and |
685 | * should be printed, up to the null. | 691 | * should be printed, up to the null. |
@@ -691,19 +697,20 @@ kdb_printit: | |||
691 | * Write to all consoles. | 697 | * Write to all consoles. |
692 | */ | 698 | */ |
693 | retlen = strlen(kdb_buffer); | 699 | retlen = strlen(kdb_buffer); |
700 | cp = (char *) printk_skip_level(kdb_buffer); | ||
694 | if (!dbg_kdb_mode && kgdb_connected) { | 701 | if (!dbg_kdb_mode && kgdb_connected) { |
695 | gdbstub_msg_write(kdb_buffer, retlen); | 702 | gdbstub_msg_write(cp, retlen - (cp - kdb_buffer)); |
696 | } else { | 703 | } else { |
697 | if (dbg_io_ops && !dbg_io_ops->is_console) { | 704 | if (dbg_io_ops && !dbg_io_ops->is_console) { |
698 | len = retlen; | 705 | len = retlen - (cp - kdb_buffer); |
699 | cp = kdb_buffer; | 706 | cp2 = cp; |
700 | while (len--) { | 707 | while (len--) { |
701 | dbg_io_ops->write_char(*cp); | 708 | dbg_io_ops->write_char(*cp2); |
702 | cp++; | 709 | cp2++; |
703 | } | 710 | } |
704 | } | 711 | } |
705 | while (c) { | 712 | while (c) { |
706 | c->write(c, kdb_buffer, retlen); | 713 | c->write(c, cp, retlen - (cp - kdb_buffer)); |
707 | touch_nmi_watchdog(); | 714 | touch_nmi_watchdog(); |
708 | c = c->next; | 715 | c = c->next; |
709 | } | 716 | } |
@@ -711,7 +718,10 @@ kdb_printit: | |||
711 | if (logging) { | 718 | if (logging) { |
712 | saved_loglevel = console_loglevel; | 719 | saved_loglevel = console_loglevel; |
713 | console_loglevel = CONSOLE_LOGLEVEL_SILENT; | 720 | console_loglevel = CONSOLE_LOGLEVEL_SILENT; |
714 | printk(KERN_INFO "%s", kdb_buffer); | 721 | if (printk_get_level(kdb_buffer) || src == KDB_MSGSRC_PRINTK) |
722 | printk("%s", kdb_buffer); | ||
723 | else | ||
724 | pr_info("%s", kdb_buffer); | ||
715 | } | 725 | } |
716 | 726 | ||
717 | if (KDB_STATE(PAGER)) { | 727 | if (KDB_STATE(PAGER)) { |
@@ -794,11 +804,23 @@ kdb_printit: | |||
794 | kdb_nextline = linecount - 1; | 804 | kdb_nextline = linecount - 1; |
795 | kdb_printf("\r"); | 805 | kdb_printf("\r"); |
796 | suspend_grep = 1; /* for this recursion */ | 806 | suspend_grep = 1; /* for this recursion */ |
807 | } else if (buf1[0] == '/' && !kdb_grepping_flag) { | ||
808 | kdb_printf("\r"); | ||
809 | kdb_getstr(kdb_grep_string, KDB_GREP_STRLEN, | ||
810 | kdbgetenv("SEARCHPROMPT") ?: "search> "); | ||
811 | *strchrnul(kdb_grep_string, '\n') = '\0'; | ||
812 | kdb_grepping_flag += KDB_GREPPING_FLAG_SEARCH; | ||
813 | suspend_grep = 1; /* for this recursion */ | ||
797 | } else if (buf1[0] && buf1[0] != '\n') { | 814 | } else if (buf1[0] && buf1[0] != '\n') { |
798 | /* user hit something other than enter */ | 815 | /* user hit something other than enter */ |
799 | suspend_grep = 1; /* for this recursion */ | 816 | suspend_grep = 1; /* for this recursion */ |
800 | kdb_printf("\nOnly 'q' or 'Q' are processed at more " | 817 | if (buf1[0] != '/') |
801 | "prompt, input ignored\n"); | 818 | kdb_printf( |
819 | "\nOnly 'q', 'Q' or '/' are processed at " | ||
820 | "more prompt, input ignored\n"); | ||
821 | else | ||
822 | kdb_printf("\n'/' cannot be used during | " | ||
823 | "grep filtering, input ignored\n"); | ||
802 | } else if (kdb_grepping_flag) { | 824 | } else if (kdb_grepping_flag) { |
803 | /* user hit enter */ | 825 | /* user hit enter */ |
804 | suspend_grep = 1; /* for this recursion */ | 826 | suspend_grep = 1; /* for this recursion */ |
@@ -844,7 +866,7 @@ int kdb_printf(const char *fmt, ...) | |||
844 | int r; | 866 | int r; |
845 | 867 | ||
846 | va_start(ap, fmt); | 868 | va_start(ap, fmt); |
847 | r = vkdb_printf(fmt, ap); | 869 | r = vkdb_printf(KDB_MSGSRC_INTERNAL, fmt, ap); |
848 | va_end(ap); | 870 | va_end(ap); |
849 | 871 | ||
850 | return r; | 872 | return r; |
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 7b40c5f07dce..4121345498e0 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -50,8 +50,7 @@ | |||
50 | static int kdb_cmd_enabled = CONFIG_KDB_DEFAULT_ENABLE; | 50 | static int kdb_cmd_enabled = CONFIG_KDB_DEFAULT_ENABLE; |
51 | module_param_named(cmd_enable, kdb_cmd_enabled, int, 0600); | 51 | module_param_named(cmd_enable, kdb_cmd_enabled, int, 0600); |
52 | 52 | ||
53 | #define GREP_LEN 256 | 53 | char kdb_grep_string[KDB_GREP_STRLEN]; |
54 | char kdb_grep_string[GREP_LEN]; | ||
55 | int kdb_grepping_flag; | 54 | int kdb_grepping_flag; |
56 | EXPORT_SYMBOL(kdb_grepping_flag); | 55 | EXPORT_SYMBOL(kdb_grepping_flag); |
57 | int kdb_grep_leading; | 56 | int kdb_grep_leading; |
@@ -870,7 +869,7 @@ static void parse_grep(const char *str) | |||
870 | len = strlen(cp); | 869 | len = strlen(cp); |
871 | if (!len) | 870 | if (!len) |
872 | return; | 871 | return; |
873 | if (len >= GREP_LEN) { | 872 | if (len >= KDB_GREP_STRLEN) { |
874 | kdb_printf("search string too long\n"); | 873 | kdb_printf("search string too long\n"); |
875 | return; | 874 | return; |
876 | } | 875 | } |
@@ -915,13 +914,12 @@ int kdb_parse(const char *cmdstr) | |||
915 | char *cp; | 914 | char *cp; |
916 | char *cpp, quoted; | 915 | char *cpp, quoted; |
917 | kdbtab_t *tp; | 916 | kdbtab_t *tp; |
918 | int i, escaped, ignore_errors = 0, check_grep; | 917 | int i, escaped, ignore_errors = 0, check_grep = 0; |
919 | 918 | ||
920 | /* | 919 | /* |
921 | * First tokenize the command string. | 920 | * First tokenize the command string. |
922 | */ | 921 | */ |
923 | cp = (char *)cmdstr; | 922 | cp = (char *)cmdstr; |
924 | kdb_grepping_flag = check_grep = 0; | ||
925 | 923 | ||
926 | if (KDB_FLAG(CMD_INTERRUPT)) { | 924 | if (KDB_FLAG(CMD_INTERRUPT)) { |
927 | /* Previous command was interrupted, newline must not | 925 | /* 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, | |||
1247 | kdb_printf("due to NonMaskable Interrupt @ " | 1245 | kdb_printf("due to NonMaskable Interrupt @ " |
1248 | kdb_machreg_fmt "\n", | 1246 | kdb_machreg_fmt "\n", |
1249 | instruction_pointer(regs)); | 1247 | instruction_pointer(regs)); |
1250 | kdb_dumpregs(regs); | ||
1251 | break; | 1248 | break; |
1252 | case KDB_REASON_SSTEP: | 1249 | case KDB_REASON_SSTEP: |
1253 | case KDB_REASON_BREAK: | 1250 | case KDB_REASON_BREAK: |
@@ -1281,6 +1278,9 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, | |||
1281 | */ | 1278 | */ |
1282 | kdb_nextline = 1; | 1279 | kdb_nextline = 1; |
1283 | KDB_STATE_CLEAR(SUPPRESS); | 1280 | KDB_STATE_CLEAR(SUPPRESS); |
1281 | kdb_grepping_flag = 0; | ||
1282 | /* ensure the old search does not leak into '/' commands */ | ||
1283 | kdb_grep_string[0] = '\0'; | ||
1284 | 1284 | ||
1285 | cmdbuf = cmd_cur; | 1285 | cmdbuf = cmd_cur; |
1286 | *cmdbuf = '\0'; | 1286 | *cmdbuf = '\0'; |
@@ -2256,7 +2256,7 @@ static int kdb_cpu(int argc, const char **argv) | |||
2256 | /* | 2256 | /* |
2257 | * Validate cpunum | 2257 | * Validate cpunum |
2258 | */ | 2258 | */ |
2259 | if ((cpunum > NR_CPUS) || !kgdb_info[cpunum].enter_kgdb) | 2259 | if ((cpunum >= CONFIG_NR_CPUS) || !kgdb_info[cpunum].enter_kgdb) |
2260 | return KDB_BADCPUNUM; | 2260 | return KDB_BADCPUNUM; |
2261 | 2261 | ||
2262 | dbg_switch_cpu = cpunum; | 2262 | dbg_switch_cpu = cpunum; |
@@ -2583,7 +2583,7 @@ static int kdb_summary(int argc, const char **argv) | |||
2583 | #define K(x) ((x) << (PAGE_SHIFT - 10)) | 2583 | #define K(x) ((x) << (PAGE_SHIFT - 10)) |
2584 | kdb_printf("\nMemTotal: %8lu kB\nMemFree: %8lu kB\n" | 2584 | kdb_printf("\nMemTotal: %8lu kB\nMemFree: %8lu kB\n" |
2585 | "Buffers: %8lu kB\n", | 2585 | "Buffers: %8lu kB\n", |
2586 | val.totalram, val.freeram, val.bufferram); | 2586 | K(val.totalram), K(val.freeram), K(val.bufferram)); |
2587 | return 0; | 2587 | return 0; |
2588 | } | 2588 | } |
2589 | 2589 | ||
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index eaacd1693954..75014d7f4568 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h | |||
@@ -196,7 +196,9 @@ extern int kdb_main_loop(kdb_reason_t, kdb_reason_t, | |||
196 | 196 | ||
197 | /* Miscellaneous functions and data areas */ | 197 | /* Miscellaneous functions and data areas */ |
198 | extern int kdb_grepping_flag; | 198 | extern int kdb_grepping_flag; |
199 | #define KDB_GREPPING_FLAG_SEARCH 0x8000 | ||
199 | extern char kdb_grep_string[]; | 200 | extern char kdb_grep_string[]; |
201 | #define KDB_GREP_STRLEN 256 | ||
200 | extern int kdb_grep_leading; | 202 | extern int kdb_grep_leading; |
201 | extern int kdb_grep_trailing; | 203 | extern int kdb_grep_trailing; |
202 | extern char *kdb_cmds[]; | 204 | extern char *kdb_cmds[]; |
@@ -209,7 +211,7 @@ extern void kdb_ps1(const struct task_struct *p); | |||
209 | extern void kdb_print_nameval(const char *name, unsigned long val); | 211 | extern void kdb_print_nameval(const char *name, unsigned long val); |
210 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); | 212 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); |
211 | extern void kdb_meminfo_proc_show(void); | 213 | extern void kdb_meminfo_proc_show(void); |
212 | extern char *kdb_getstr(char *, size_t, char *); | 214 | extern char *kdb_getstr(char *, size_t, const char *); |
213 | extern void kdb_gdb_state_pass(char *buf); | 215 | extern void kdb_gdb_state_pass(char *buf); |
214 | 216 | ||
215 | /* Defines for kdb_symbol_print */ | 217 | /* Defines for kdb_symbol_print */ |
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index c06df7de0963..01cfd69c54c6 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c | |||
@@ -1811,7 +1811,7 @@ int vprintk_default(const char *fmt, va_list args) | |||
1811 | 1811 | ||
1812 | #ifdef CONFIG_KGDB_KDB | 1812 | #ifdef CONFIG_KGDB_KDB |
1813 | if (unlikely(kdb_trap_printk)) { | 1813 | if (unlikely(kdb_trap_printk)) { |
1814 | r = vkdb_printf(fmt, args); | 1814 | r = vkdb_printf(KDB_MSGSRC_PRINTK, fmt, args); |
1815 | return r; | 1815 | return r; |
1816 | } | 1816 | } |
1817 | #endif | 1817 | #endif |