diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-03-02 11:31:39 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-03-02 11:31:39 -0500 |
commit | 3cfb07743a5bffecba83f0da26444e85c0a9bfbb (patch) | |
tree | c27f27a8d8f4bad9eed265cf0894d2ce8f058b1d | |
parent | e23b62256a361611cbd45cd1456638f1a5106b5c (diff) | |
parent | 36dfea42cc35509b481377980338cc3b89d79256 (diff) |
Merge tag 'for_linux-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb
Pull KGDB/KDB fixes and cleanups from Jason Wessel:
"For a change we removed more code than we added. If people aren't
using it we shouldn't be carrying it. :-)
Cleanups:
- Remove kdb ssb command - there is no in kernel disassembler to
support it
- Remove kdb ll command - Always caused a kernel oops and there were
no bug reports so no one was using this command
- Use kernel ARRAY_SIZE macro instead of array computations
Fixes:
- Stop oops in kdb if user executes kdb_defcmd with args
- kdb help command truncated text
- ppc64 support for kgdbts
- Add missing kconfig option from original kdb port for dealing with
catastrophic kernel crashes such that you can reboot automatically
on continue from kdb"
* tag 'for_linux-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb:
kdb: Remove unhandled ssb command
kdb: Prevent kernel oops with kdb_defcmd
kdb: Remove the ll command
kdb_main: fix help print
kdb: Fix overlap in buffers with strcpy
Fixed dead ifdef block by adding missing Kconfig option.
kdb: Setup basic kdb state before invoking commands via kgdb
kdb: use ARRAY_SIZE where possible
kgdb/kgdbts: support ppc64
kdb: A fix for kdb command table expansion
-rw-r--r-- | drivers/misc/kgdbts.c | 2 | ||||
-rw-r--r-- | kernel/debug/debug_core.h | 2 | ||||
-rw-r--r-- | kernel/debug/gdbstub.c | 3 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_bp.c | 20 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_debugger.c | 25 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_main.c | 135 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_private.h | 4 | ||||
-rw-r--r-- | lib/Kconfig.kgdb | 18 |
8 files changed, 82 insertions, 127 deletions
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index 3aa9a969b373..36f5d52775a9 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c | |||
@@ -103,6 +103,7 @@ | |||
103 | #include <linux/delay.h> | 103 | #include <linux/delay.h> |
104 | #include <linux/kthread.h> | 104 | #include <linux/kthread.h> |
105 | #include <linux/module.h> | 105 | #include <linux/module.h> |
106 | #include <asm/sections.h> | ||
106 | 107 | ||
107 | #define v1printk(a...) do { \ | 108 | #define v1printk(a...) do { \ |
108 | if (verbose) \ | 109 | if (verbose) \ |
@@ -222,6 +223,7 @@ static unsigned long lookup_addr(char *arg) | |||
222 | addr = (unsigned long)do_fork; | 223 | addr = (unsigned long)do_fork; |
223 | else if (!strcmp(arg, "hw_break_val")) | 224 | else if (!strcmp(arg, "hw_break_val")) |
224 | addr = (unsigned long)&hw_break_val; | 225 | addr = (unsigned long)&hw_break_val; |
226 | addr = (unsigned long) dereference_function_descriptor((void *)addr); | ||
225 | return addr; | 227 | return addr; |
226 | } | 228 | } |
227 | 229 | ||
diff --git a/kernel/debug/debug_core.h b/kernel/debug/debug_core.h index 3494c28a7e7a..2235967e78b0 100644 --- a/kernel/debug/debug_core.h +++ b/kernel/debug/debug_core.h | |||
@@ -72,6 +72,8 @@ extern int dbg_kdb_mode; | |||
72 | #ifdef CONFIG_KGDB_KDB | 72 | #ifdef CONFIG_KGDB_KDB |
73 | extern int kdb_stub(struct kgdb_state *ks); | 73 | extern int kdb_stub(struct kgdb_state *ks); |
74 | extern int kdb_parse(const char *cmdstr); | 74 | extern int kdb_parse(const char *cmdstr); |
75 | extern int kdb_common_init_state(struct kgdb_state *ks); | ||
76 | extern int kdb_common_deinit_state(void); | ||
75 | #else /* ! CONFIG_KGDB_KDB */ | 77 | #else /* ! CONFIG_KGDB_KDB */ |
76 | static inline int kdb_stub(struct kgdb_state *ks) | 78 | static inline int kdb_stub(struct kgdb_state *ks) |
77 | { | 79 | { |
diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c index 38573f35a5ad..19d9a578c753 100644 --- a/kernel/debug/gdbstub.c +++ b/kernel/debug/gdbstub.c | |||
@@ -783,7 +783,10 @@ static void gdb_cmd_query(struct kgdb_state *ks) | |||
783 | len = len / 2; | 783 | len = len / 2; |
784 | remcom_out_buffer[len++] = 0; | 784 | remcom_out_buffer[len++] = 0; |
785 | 785 | ||
786 | kdb_common_init_state(ks); | ||
786 | kdb_parse(remcom_out_buffer); | 787 | kdb_parse(remcom_out_buffer); |
788 | kdb_common_deinit_state(); | ||
789 | |||
787 | strcpy(remcom_out_buffer, "OK"); | 790 | strcpy(remcom_out_buffer, "OK"); |
788 | } | 791 | } |
789 | break; | 792 | break; |
diff --git a/kernel/debug/kdb/kdb_bp.c b/kernel/debug/kdb/kdb_bp.c index 8418c2f8ec5d..70a504601dc3 100644 --- a/kernel/debug/kdb/kdb_bp.c +++ b/kernel/debug/kdb/kdb_bp.c | |||
@@ -486,11 +486,9 @@ static int kdb_bc(int argc, const char **argv) | |||
486 | /* | 486 | /* |
487 | * kdb_ss | 487 | * kdb_ss |
488 | * | 488 | * |
489 | * Process the 'ss' (Single Step) and 'ssb' (Single Step to Branch) | 489 | * Process the 'ss' (Single Step) command. |
490 | * commands. | ||
491 | * | 490 | * |
492 | * ss | 491 | * ss |
493 | * ssb | ||
494 | * | 492 | * |
495 | * Parameters: | 493 | * Parameters: |
496 | * argc Argument count | 494 | * argc Argument count |
@@ -498,35 +496,23 @@ static int kdb_bc(int argc, const char **argv) | |||
498 | * Outputs: | 496 | * Outputs: |
499 | * None. | 497 | * None. |
500 | * Returns: | 498 | * Returns: |
501 | * KDB_CMD_SS[B] for success, a kdb error if failure. | 499 | * KDB_CMD_SS for success, a kdb error if failure. |
502 | * Locking: | 500 | * Locking: |
503 | * None. | 501 | * None. |
504 | * Remarks: | 502 | * Remarks: |
505 | * | 503 | * |
506 | * Set the arch specific option to trigger a debug trap after the next | 504 | * Set the arch specific option to trigger a debug trap after the next |
507 | * instruction. | 505 | * instruction. |
508 | * | ||
509 | * For 'ssb', set the trace flag in the debug trap handler | ||
510 | * after printing the current insn and return directly without | ||
511 | * invoking the kdb command processor, until a branch instruction | ||
512 | * is encountered. | ||
513 | */ | 506 | */ |
514 | 507 | ||
515 | static int kdb_ss(int argc, const char **argv) | 508 | static int kdb_ss(int argc, const char **argv) |
516 | { | 509 | { |
517 | int ssb = 0; | ||
518 | |||
519 | ssb = (strcmp(argv[0], "ssb") == 0); | ||
520 | if (argc != 0) | 510 | if (argc != 0) |
521 | return KDB_ARGCOUNT; | 511 | return KDB_ARGCOUNT; |
522 | /* | 512 | /* |
523 | * Set trace flag and go. | 513 | * Set trace flag and go. |
524 | */ | 514 | */ |
525 | KDB_STATE_SET(DOING_SS); | 515 | KDB_STATE_SET(DOING_SS); |
526 | if (ssb) { | ||
527 | KDB_STATE_SET(DOING_SSB); | ||
528 | return KDB_CMD_SSB; | ||
529 | } | ||
530 | return KDB_CMD_SS; | 516 | return KDB_CMD_SS; |
531 | } | 517 | } |
532 | 518 | ||
@@ -561,8 +547,6 @@ void __init kdb_initbptab(void) | |||
561 | 547 | ||
562 | kdb_register_repeat("ss", kdb_ss, "", | 548 | kdb_register_repeat("ss", kdb_ss, "", |
563 | "Single Step", 1, KDB_REPEAT_NO_ARGS); | 549 | "Single Step", 1, KDB_REPEAT_NO_ARGS); |
564 | kdb_register_repeat("ssb", kdb_ss, "", | ||
565 | "Single step to branch/call", 0, KDB_REPEAT_NO_ARGS); | ||
566 | /* | 550 | /* |
567 | * Architecture dependent initialization. | 551 | * Architecture dependent initialization. |
568 | */ | 552 | */ |
diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index be7b33b73d30..328d18ef31e4 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c | |||
@@ -34,6 +34,22 @@ EXPORT_SYMBOL_GPL(kdb_poll_idx); | |||
34 | 34 | ||
35 | static struct kgdb_state *kdb_ks; | 35 | static struct kgdb_state *kdb_ks; |
36 | 36 | ||
37 | int kdb_common_init_state(struct kgdb_state *ks) | ||
38 | { | ||
39 | kdb_initial_cpu = atomic_read(&kgdb_active); | ||
40 | kdb_current_task = kgdb_info[ks->cpu].task; | ||
41 | kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo; | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | int kdb_common_deinit_state(void) | ||
46 | { | ||
47 | kdb_initial_cpu = -1; | ||
48 | kdb_current_task = NULL; | ||
49 | kdb_current_regs = NULL; | ||
50 | return 0; | ||
51 | } | ||
52 | |||
37 | int kdb_stub(struct kgdb_state *ks) | 53 | int kdb_stub(struct kgdb_state *ks) |
38 | { | 54 | { |
39 | int error = 0; | 55 | int error = 0; |
@@ -94,13 +110,10 @@ int kdb_stub(struct kgdb_state *ks) | |||
94 | } | 110 | } |
95 | /* Set initial kdb state variables */ | 111 | /* Set initial kdb state variables */ |
96 | KDB_STATE_CLEAR(KGDB_TRANS); | 112 | KDB_STATE_CLEAR(KGDB_TRANS); |
97 | kdb_initial_cpu = atomic_read(&kgdb_active); | 113 | kdb_common_init_state(ks); |
98 | kdb_current_task = kgdb_info[ks->cpu].task; | ||
99 | kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo; | ||
100 | /* Remove any breakpoints as needed by kdb and clear single step */ | 114 | /* Remove any breakpoints as needed by kdb and clear single step */ |
101 | kdb_bp_remove(); | 115 | kdb_bp_remove(); |
102 | KDB_STATE_CLEAR(DOING_SS); | 116 | KDB_STATE_CLEAR(DOING_SS); |
103 | KDB_STATE_CLEAR(DOING_SSB); | ||
104 | KDB_STATE_SET(PAGER); | 117 | KDB_STATE_SET(PAGER); |
105 | /* zero out any offline cpu data */ | 118 | /* zero out any offline cpu data */ |
106 | for_each_present_cpu(i) { | 119 | for_each_present_cpu(i) { |
@@ -125,9 +138,7 @@ int kdb_stub(struct kgdb_state *ks) | |||
125 | * Upon exit from the kdb main loop setup break points and restart | 138 | * Upon exit from the kdb main loop setup break points and restart |
126 | * the system based on the requested continue state | 139 | * the system based on the requested continue state |
127 | */ | 140 | */ |
128 | kdb_initial_cpu = -1; | 141 | kdb_common_deinit_state(); |
129 | kdb_current_task = NULL; | ||
130 | kdb_current_regs = NULL; | ||
131 | KDB_STATE_CLEAR(PAGER); | 142 | KDB_STATE_CLEAR(PAGER); |
132 | kdbnearsym_cleanup(); | 143 | kdbnearsym_cleanup(); |
133 | if (error == KDB_CMD_KGDB) { | 144 | if (error == KDB_CMD_KGDB) { |
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 8875254120b6..00eb8f7fbf41 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -124,7 +124,7 @@ static kdbmsg_t kdbmsgs[] = { | |||
124 | }; | 124 | }; |
125 | #undef KDBMSG | 125 | #undef KDBMSG |
126 | 126 | ||
127 | static const int __nkdb_err = sizeof(kdbmsgs) / sizeof(kdbmsg_t); | 127 | static const int __nkdb_err = ARRAY_SIZE(kdbmsgs); |
128 | 128 | ||
129 | 129 | ||
130 | /* | 130 | /* |
@@ -175,7 +175,7 @@ static char *__env[] = { | |||
175 | (char *)0, | 175 | (char *)0, |
176 | }; | 176 | }; |
177 | 177 | ||
178 | static const int __nenv = (sizeof(__env) / sizeof(char *)); | 178 | static const int __nenv = ARRAY_SIZE(__env); |
179 | 179 | ||
180 | struct task_struct *kdb_curr_task(int cpu) | 180 | struct task_struct *kdb_curr_task(int cpu) |
181 | { | 181 | { |
@@ -681,34 +681,50 @@ static int kdb_defcmd(int argc, const char **argv) | |||
681 | } | 681 | } |
682 | if (argc != 3) | 682 | if (argc != 3) |
683 | return KDB_ARGCOUNT; | 683 | return KDB_ARGCOUNT; |
684 | defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set), | 684 | if (in_dbg_master()) { |
685 | GFP_KDB); | 685 | kdb_printf("Command only available during kdb_init()\n"); |
686 | if (!defcmd_set) { | ||
687 | kdb_printf("Could not allocate new defcmd_set entry for %s\n", | ||
688 | argv[1]); | ||
689 | defcmd_set = save_defcmd_set; | ||
690 | return KDB_NOTIMP; | 686 | return KDB_NOTIMP; |
691 | } | 687 | } |
688 | defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set), | ||
689 | GFP_KDB); | ||
690 | if (!defcmd_set) | ||
691 | goto fail_defcmd; | ||
692 | memcpy(defcmd_set, save_defcmd_set, | 692 | memcpy(defcmd_set, save_defcmd_set, |
693 | defcmd_set_count * sizeof(*defcmd_set)); | 693 | defcmd_set_count * sizeof(*defcmd_set)); |
694 | kfree(save_defcmd_set); | ||
695 | s = defcmd_set + defcmd_set_count; | 694 | s = defcmd_set + defcmd_set_count; |
696 | memset(s, 0, sizeof(*s)); | 695 | memset(s, 0, sizeof(*s)); |
697 | s->usable = 1; | 696 | s->usable = 1; |
698 | s->name = kdb_strdup(argv[1], GFP_KDB); | 697 | s->name = kdb_strdup(argv[1], GFP_KDB); |
698 | if (!s->name) | ||
699 | goto fail_name; | ||
699 | s->usage = kdb_strdup(argv[2], GFP_KDB); | 700 | s->usage = kdb_strdup(argv[2], GFP_KDB); |
701 | if (!s->usage) | ||
702 | goto fail_usage; | ||
700 | s->help = kdb_strdup(argv[3], GFP_KDB); | 703 | s->help = kdb_strdup(argv[3], GFP_KDB); |
704 | if (!s->help) | ||
705 | goto fail_help; | ||
701 | if (s->usage[0] == '"') { | 706 | if (s->usage[0] == '"') { |
702 | strcpy(s->usage, s->usage+1); | 707 | strcpy(s->usage, argv[2]+1); |
703 | s->usage[strlen(s->usage)-1] = '\0'; | 708 | s->usage[strlen(s->usage)-1] = '\0'; |
704 | } | 709 | } |
705 | if (s->help[0] == '"') { | 710 | if (s->help[0] == '"') { |
706 | strcpy(s->help, s->help+1); | 711 | strcpy(s->help, argv[3]+1); |
707 | s->help[strlen(s->help)-1] = '\0'; | 712 | s->help[strlen(s->help)-1] = '\0'; |
708 | } | 713 | } |
709 | ++defcmd_set_count; | 714 | ++defcmd_set_count; |
710 | defcmd_in_progress = 1; | 715 | defcmd_in_progress = 1; |
716 | kfree(save_defcmd_set); | ||
711 | return 0; | 717 | return 0; |
718 | fail_help: | ||
719 | kfree(s->usage); | ||
720 | fail_usage: | ||
721 | kfree(s->name); | ||
722 | fail_name: | ||
723 | kfree(defcmd_set); | ||
724 | fail_defcmd: | ||
725 | kdb_printf("Could not allocate new defcmd_set entry for %s\n", argv[1]); | ||
726 | defcmd_set = save_defcmd_set; | ||
727 | return KDB_NOTIMP; | ||
712 | } | 728 | } |
713 | 729 | ||
714 | /* | 730 | /* |
@@ -1112,7 +1128,6 @@ void kdb_set_current_task(struct task_struct *p) | |||
1112 | * KDB_CMD_GO User typed 'go'. | 1128 | * KDB_CMD_GO User typed 'go'. |
1113 | * KDB_CMD_CPU User switched to another cpu. | 1129 | * KDB_CMD_CPU User switched to another cpu. |
1114 | * KDB_CMD_SS Single step. | 1130 | * KDB_CMD_SS Single step. |
1115 | * KDB_CMD_SSB Single step until branch. | ||
1116 | */ | 1131 | */ |
1117 | static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, | 1132 | static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, |
1118 | kdb_dbtrap_t db_result) | 1133 | kdb_dbtrap_t db_result) |
@@ -1151,14 +1166,6 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, | |||
1151 | kdb_printf("due to Debug @ " kdb_machreg_fmt "\n", | 1166 | kdb_printf("due to Debug @ " kdb_machreg_fmt "\n", |
1152 | instruction_pointer(regs)); | 1167 | instruction_pointer(regs)); |
1153 | break; | 1168 | break; |
1154 | case KDB_DB_SSB: | ||
1155 | /* | ||
1156 | * In the midst of ssb command. Just return. | ||
1157 | */ | ||
1158 | KDB_DEBUG_STATE("kdb_local 3", reason); | ||
1159 | return KDB_CMD_SSB; /* Continue with SSB command */ | ||
1160 | |||
1161 | break; | ||
1162 | case KDB_DB_SS: | 1169 | case KDB_DB_SS: |
1163 | break; | 1170 | break; |
1164 | case KDB_DB_SSBPT: | 1171 | case KDB_DB_SSBPT: |
@@ -1281,7 +1288,6 @@ do_full_getstr: | |||
1281 | if (diag == KDB_CMD_GO | 1288 | if (diag == KDB_CMD_GO |
1282 | || diag == KDB_CMD_CPU | 1289 | || diag == KDB_CMD_CPU |
1283 | || diag == KDB_CMD_SS | 1290 | || diag == KDB_CMD_SS |
1284 | || diag == KDB_CMD_SSB | ||
1285 | || diag == KDB_CMD_KGDB) | 1291 | || diag == KDB_CMD_KGDB) |
1286 | break; | 1292 | break; |
1287 | 1293 | ||
@@ -1368,12 +1374,6 @@ int kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error, | |||
1368 | break; | 1374 | break; |
1369 | } | 1375 | } |
1370 | 1376 | ||
1371 | if (result == KDB_CMD_SSB) { | ||
1372 | KDB_STATE_SET(DOING_SS); | ||
1373 | KDB_STATE_SET(DOING_SSB); | ||
1374 | break; | ||
1375 | } | ||
1376 | |||
1377 | if (result == KDB_CMD_KGDB) { | 1377 | if (result == KDB_CMD_KGDB) { |
1378 | if (!KDB_STATE(DOING_KGDB)) | 1378 | if (!KDB_STATE(DOING_KGDB)) |
1379 | kdb_printf("Entering please attach debugger " | 1379 | kdb_printf("Entering please attach debugger " |
@@ -2350,69 +2350,6 @@ static int kdb_pid(int argc, const char **argv) | |||
2350 | return 0; | 2350 | return 0; |
2351 | } | 2351 | } |
2352 | 2352 | ||
2353 | /* | ||
2354 | * kdb_ll - This function implements the 'll' command which follows a | ||
2355 | * linked list and executes an arbitrary command for each | ||
2356 | * element. | ||
2357 | */ | ||
2358 | static int kdb_ll(int argc, const char **argv) | ||
2359 | { | ||
2360 | int diag = 0; | ||
2361 | unsigned long addr; | ||
2362 | long offset = 0; | ||
2363 | unsigned long va; | ||
2364 | unsigned long linkoffset; | ||
2365 | int nextarg; | ||
2366 | const char *command; | ||
2367 | |||
2368 | if (argc != 3) | ||
2369 | return KDB_ARGCOUNT; | ||
2370 | |||
2371 | nextarg = 1; | ||
2372 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); | ||
2373 | if (diag) | ||
2374 | return diag; | ||
2375 | |||
2376 | diag = kdbgetularg(argv[2], &linkoffset); | ||
2377 | if (diag) | ||
2378 | return diag; | ||
2379 | |||
2380 | /* | ||
2381 | * Using the starting address as | ||
2382 | * the first element in the list, and assuming that | ||
2383 | * the list ends with a null pointer. | ||
2384 | */ | ||
2385 | |||
2386 | va = addr; | ||
2387 | command = kdb_strdup(argv[3], GFP_KDB); | ||
2388 | if (!command) { | ||
2389 | kdb_printf("%s: cannot duplicate command\n", __func__); | ||
2390 | return 0; | ||
2391 | } | ||
2392 | /* Recursive use of kdb_parse, do not use argv after this point */ | ||
2393 | argv = NULL; | ||
2394 | |||
2395 | while (va) { | ||
2396 | char buf[80]; | ||
2397 | |||
2398 | if (KDB_FLAG(CMD_INTERRUPT)) | ||
2399 | goto out; | ||
2400 | |||
2401 | sprintf(buf, "%s " kdb_machreg_fmt "\n", command, va); | ||
2402 | diag = kdb_parse(buf); | ||
2403 | if (diag) | ||
2404 | goto out; | ||
2405 | |||
2406 | addr = va + linkoffset; | ||
2407 | if (kdb_getword(&va, addr, sizeof(va))) | ||
2408 | goto out; | ||
2409 | } | ||
2410 | |||
2411 | out: | ||
2412 | kfree(command); | ||
2413 | return diag; | ||
2414 | } | ||
2415 | |||
2416 | static int kdb_kgdb(int argc, const char **argv) | 2353 | static int kdb_kgdb(int argc, const char **argv) |
2417 | { | 2354 | { |
2418 | return KDB_CMD_KGDB; | 2355 | return KDB_CMD_KGDB; |
@@ -2430,11 +2367,15 @@ static int kdb_help(int argc, const char **argv) | |||
2430 | kdb_printf("-----------------------------" | 2367 | kdb_printf("-----------------------------" |
2431 | "-----------------------------\n"); | 2368 | "-----------------------------\n"); |
2432 | for_each_kdbcmd(kt, i) { | 2369 | for_each_kdbcmd(kt, i) { |
2433 | if (kt->cmd_name) | 2370 | char *space = ""; |
2434 | kdb_printf("%-15.15s %-20.20s %s\n", kt->cmd_name, | ||
2435 | kt->cmd_usage, kt->cmd_help); | ||
2436 | if (KDB_FLAG(CMD_INTERRUPT)) | 2371 | if (KDB_FLAG(CMD_INTERRUPT)) |
2437 | return 0; | 2372 | return 0; |
2373 | if (!kt->cmd_name) | ||
2374 | continue; | ||
2375 | if (strlen(kt->cmd_usage) > 20) | ||
2376 | space = "\n "; | ||
2377 | kdb_printf("%-15.15s %-20s%s%s\n", kt->cmd_name, | ||
2378 | kt->cmd_usage, space, kt->cmd_help); | ||
2438 | } | 2379 | } |
2439 | return 0; | 2380 | return 0; |
2440 | } | 2381 | } |
@@ -2739,7 +2680,7 @@ int kdb_register_repeat(char *cmd, | |||
2739 | (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new)); | 2680 | (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new)); |
2740 | kfree(kdb_commands); | 2681 | kfree(kdb_commands); |
2741 | } | 2682 | } |
2742 | memset(new + kdb_max_commands, 0, | 2683 | memset(new + kdb_max_commands - KDB_BASE_CMD_MAX, 0, |
2743 | kdb_command_extend * sizeof(*new)); | 2684 | kdb_command_extend * sizeof(*new)); |
2744 | kdb_commands = new; | 2685 | kdb_commands = new; |
2745 | kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX; | 2686 | kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX; |
@@ -2843,15 +2784,13 @@ static void __init kdb_inittab(void) | |||
2843 | "Stack traceback", 1, KDB_REPEAT_NONE); | 2784 | "Stack traceback", 1, KDB_REPEAT_NONE); |
2844 | kdb_register_repeat("btp", kdb_bt, "<pid>", | 2785 | kdb_register_repeat("btp", kdb_bt, "<pid>", |
2845 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); | 2786 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); |
2846 | kdb_register_repeat("bta", kdb_bt, "[DRSTCZEUIMA]", | 2787 | kdb_register_repeat("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]", |
2847 | "Display stack all processes", 0, KDB_REPEAT_NONE); | 2788 | "Backtrace all processes matching state flag", 0, KDB_REPEAT_NONE); |
2848 | kdb_register_repeat("btc", kdb_bt, "", | 2789 | kdb_register_repeat("btc", kdb_bt, "", |
2849 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); | 2790 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); |
2850 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", | 2791 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", |
2851 | "Backtrace process given its struct task address", 0, | 2792 | "Backtrace process given its struct task address", 0, |
2852 | KDB_REPEAT_NONE); | 2793 | KDB_REPEAT_NONE); |
2853 | kdb_register_repeat("ll", kdb_ll, "<first-element> <linkoffset> <cmd>", | ||
2854 | "Execute cmd for each element in linked list", 0, KDB_REPEAT_NONE); | ||
2855 | kdb_register_repeat("env", kdb_env, "", | 2794 | kdb_register_repeat("env", kdb_env, "", |
2856 | "Show environment variables", 0, KDB_REPEAT_NONE); | 2795 | "Show environment variables", 0, KDB_REPEAT_NONE); |
2857 | kdb_register_repeat("set", kdb_set, "", | 2796 | kdb_register_repeat("set", kdb_set, "", |
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 392ec6a25844..7afd3c8c41d5 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h | |||
@@ -19,7 +19,6 @@ | |||
19 | #define KDB_CMD_GO (-1001) | 19 | #define KDB_CMD_GO (-1001) |
20 | #define KDB_CMD_CPU (-1002) | 20 | #define KDB_CMD_CPU (-1002) |
21 | #define KDB_CMD_SS (-1003) | 21 | #define KDB_CMD_SS (-1003) |
22 | #define KDB_CMD_SSB (-1004) | ||
23 | #define KDB_CMD_KGDB (-1005) | 22 | #define KDB_CMD_KGDB (-1005) |
24 | 23 | ||
25 | /* Internal debug flags */ | 24 | /* Internal debug flags */ |
@@ -125,8 +124,6 @@ extern int kdb_state; | |||
125 | * kdb control */ | 124 | * kdb control */ |
126 | #define KDB_STATE_HOLD_CPU 0x00000010 /* Hold this cpu inside kdb */ | 125 | #define KDB_STATE_HOLD_CPU 0x00000010 /* Hold this cpu inside kdb */ |
127 | #define KDB_STATE_DOING_SS 0x00000020 /* Doing ss command */ | 126 | #define KDB_STATE_DOING_SS 0x00000020 /* Doing ss command */ |
128 | #define KDB_STATE_DOING_SSB 0x00000040 /* Doing ssb command, | ||
129 | * DOING_SS is also set */ | ||
130 | #define KDB_STATE_SSBPT 0x00000080 /* Install breakpoint | 127 | #define KDB_STATE_SSBPT 0x00000080 /* Install breakpoint |
131 | * after one ss, independent of | 128 | * after one ss, independent of |
132 | * DOING_SS */ | 129 | * DOING_SS */ |
@@ -191,7 +188,6 @@ extern void kdb_bp_remove(void); | |||
191 | typedef enum { | 188 | typedef enum { |
192 | KDB_DB_BPT, /* Breakpoint */ | 189 | KDB_DB_BPT, /* Breakpoint */ |
193 | KDB_DB_SS, /* Single-step trap */ | 190 | KDB_DB_SS, /* Single-step trap */ |
194 | KDB_DB_SSB, /* Single step to branch */ | ||
195 | KDB_DB_SSBPT, /* Single step over breakpoint */ | 191 | KDB_DB_SSBPT, /* Single step over breakpoint */ |
196 | KDB_DB_NOBPT /* Spurious breakpoint */ | 192 | KDB_DB_NOBPT /* Spurious breakpoint */ |
197 | } kdb_dbtrap_t; | 193 | } kdb_dbtrap_t; |
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb index dbb58ae1b8e0..140e87824173 100644 --- a/lib/Kconfig.kgdb +++ b/lib/Kconfig.kgdb | |||
@@ -80,4 +80,22 @@ config KDB_KEYBOARD | |||
80 | help | 80 | help |
81 | KDB can use a PS/2 type keyboard for an input device | 81 | KDB can use a PS/2 type keyboard for an input device |
82 | 82 | ||
83 | config KDB_CONTINUE_CATASTROPHIC | ||
84 | int "KDB: continue after catastrophic errors" | ||
85 | depends on KGDB_KDB | ||
86 | default "0" | ||
87 | help | ||
88 | This integer controls the behaviour of kdb when the kernel gets a | ||
89 | catastrophic error, i.e. for a panic or oops. | ||
90 | When KDB is active and a catastrophic error occurs, nothing extra | ||
91 | will happen until you type 'go'. | ||
92 | CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default). The first time | ||
93 | you type 'go', you will be warned by kdb. The secend time you type | ||
94 | 'go', KDB tries to continue. No guarantees that the | ||
95 | kernel is still usable in this situation. | ||
96 | CONFIG_KDB_CONTINUE_CATASTROPHIC == 1. KDB tries to continue. | ||
97 | No guarantees that the kernel is still usable in this situation. | ||
98 | CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. KDB forces a reboot. | ||
99 | If you are not sure, say 0. | ||
100 | |||
83 | endif # KGDB | 101 | endif # KGDB |