diff options
Diffstat (limited to 'kernel/debug/kdb/kdb_main.c')
-rw-r--r-- | kernel/debug/kdb/kdb_main.c | 137 |
1 files changed, 39 insertions, 98 deletions
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 4d5f8d5612f3..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 " |
@@ -1970,6 +1970,8 @@ static int kdb_lsmod(int argc, const char **argv) | |||
1970 | 1970 | ||
1971 | kdb_printf("Module Size modstruct Used by\n"); | 1971 | kdb_printf("Module Size modstruct Used by\n"); |
1972 | list_for_each_entry(mod, kdb_modules, list) { | 1972 | list_for_each_entry(mod, kdb_modules, list) { |
1973 | if (mod->state == MODULE_STATE_UNFORMED) | ||
1974 | continue; | ||
1973 | 1975 | ||
1974 | kdb_printf("%-20s%8u 0x%p ", mod->name, | 1976 | kdb_printf("%-20s%8u 0x%p ", mod->name, |
1975 | mod->core_size, (void *)mod); | 1977 | mod->core_size, (void *)mod); |
@@ -2348,69 +2350,6 @@ static int kdb_pid(int argc, const char **argv) | |||
2348 | return 0; | 2350 | return 0; |
2349 | } | 2351 | } |
2350 | 2352 | ||
2351 | /* | ||
2352 | * kdb_ll - This function implements the 'll' command which follows a | ||
2353 | * linked list and executes an arbitrary command for each | ||
2354 | * element. | ||
2355 | */ | ||
2356 | static int kdb_ll(int argc, const char **argv) | ||
2357 | { | ||
2358 | int diag = 0; | ||
2359 | unsigned long addr; | ||
2360 | long offset = 0; | ||
2361 | unsigned long va; | ||
2362 | unsigned long linkoffset; | ||
2363 | int nextarg; | ||
2364 | const char *command; | ||
2365 | |||
2366 | if (argc != 3) | ||
2367 | return KDB_ARGCOUNT; | ||
2368 | |||
2369 | nextarg = 1; | ||
2370 | diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); | ||
2371 | if (diag) | ||
2372 | return diag; | ||
2373 | |||
2374 | diag = kdbgetularg(argv[2], &linkoffset); | ||
2375 | if (diag) | ||
2376 | return diag; | ||
2377 | |||
2378 | /* | ||
2379 | * Using the starting address as | ||
2380 | * the first element in the list, and assuming that | ||
2381 | * the list ends with a null pointer. | ||
2382 | */ | ||
2383 | |||
2384 | va = addr; | ||
2385 | command = kdb_strdup(argv[3], GFP_KDB); | ||
2386 | if (!command) { | ||
2387 | kdb_printf("%s: cannot duplicate command\n", __func__); | ||
2388 | return 0; | ||
2389 | } | ||
2390 | /* Recursive use of kdb_parse, do not use argv after this point */ | ||
2391 | argv = NULL; | ||
2392 | |||
2393 | while (va) { | ||
2394 | char buf[80]; | ||
2395 | |||
2396 | if (KDB_FLAG(CMD_INTERRUPT)) | ||
2397 | goto out; | ||
2398 | |||
2399 | sprintf(buf, "%s " kdb_machreg_fmt "\n", command, va); | ||
2400 | diag = kdb_parse(buf); | ||
2401 | if (diag) | ||
2402 | goto out; | ||
2403 | |||
2404 | addr = va + linkoffset; | ||
2405 | if (kdb_getword(&va, addr, sizeof(va))) | ||
2406 | goto out; | ||
2407 | } | ||
2408 | |||
2409 | out: | ||
2410 | kfree(command); | ||
2411 | return diag; | ||
2412 | } | ||
2413 | |||
2414 | static int kdb_kgdb(int argc, const char **argv) | 2353 | static int kdb_kgdb(int argc, const char **argv) |
2415 | { | 2354 | { |
2416 | return KDB_CMD_KGDB; | 2355 | return KDB_CMD_KGDB; |
@@ -2428,11 +2367,15 @@ static int kdb_help(int argc, const char **argv) | |||
2428 | kdb_printf("-----------------------------" | 2367 | kdb_printf("-----------------------------" |
2429 | "-----------------------------\n"); | 2368 | "-----------------------------\n"); |
2430 | for_each_kdbcmd(kt, i) { | 2369 | for_each_kdbcmd(kt, i) { |
2431 | if (kt->cmd_name) | 2370 | char *space = ""; |
2432 | kdb_printf("%-15.15s %-20.20s %s\n", kt->cmd_name, | ||
2433 | kt->cmd_usage, kt->cmd_help); | ||
2434 | if (KDB_FLAG(CMD_INTERRUPT)) | 2371 | if (KDB_FLAG(CMD_INTERRUPT)) |
2435 | 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); | ||
2436 | } | 2379 | } |
2437 | return 0; | 2380 | return 0; |
2438 | } | 2381 | } |
@@ -2737,7 +2680,7 @@ int kdb_register_repeat(char *cmd, | |||
2737 | (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new)); | 2680 | (kdb_max_commands - KDB_BASE_CMD_MAX) * sizeof(*new)); |
2738 | kfree(kdb_commands); | 2681 | kfree(kdb_commands); |
2739 | } | 2682 | } |
2740 | memset(new + kdb_max_commands, 0, | 2683 | memset(new + kdb_max_commands - KDB_BASE_CMD_MAX, 0, |
2741 | kdb_command_extend * sizeof(*new)); | 2684 | kdb_command_extend * sizeof(*new)); |
2742 | kdb_commands = new; | 2685 | kdb_commands = new; |
2743 | kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX; | 2686 | kp = kdb_commands + kdb_max_commands - KDB_BASE_CMD_MAX; |
@@ -2841,15 +2784,13 @@ static void __init kdb_inittab(void) | |||
2841 | "Stack traceback", 1, KDB_REPEAT_NONE); | 2784 | "Stack traceback", 1, KDB_REPEAT_NONE); |
2842 | kdb_register_repeat("btp", kdb_bt, "<pid>", | 2785 | kdb_register_repeat("btp", kdb_bt, "<pid>", |
2843 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); | 2786 | "Display stack for process <pid>", 0, KDB_REPEAT_NONE); |
2844 | 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]", |
2845 | "Display stack all processes", 0, KDB_REPEAT_NONE); | 2788 | "Backtrace all processes matching state flag", 0, KDB_REPEAT_NONE); |
2846 | kdb_register_repeat("btc", kdb_bt, "", | 2789 | kdb_register_repeat("btc", kdb_bt, "", |
2847 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); | 2790 | "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); |
2848 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", | 2791 | kdb_register_repeat("btt", kdb_bt, "<vaddr>", |
2849 | "Backtrace process given its struct task address", 0, | 2792 | "Backtrace process given its struct task address", 0, |
2850 | KDB_REPEAT_NONE); | 2793 | KDB_REPEAT_NONE); |
2851 | kdb_register_repeat("ll", kdb_ll, "<first-element> <linkoffset> <cmd>", | ||
2852 | "Execute cmd for each element in linked list", 0, KDB_REPEAT_NONE); | ||
2853 | kdb_register_repeat("env", kdb_env, "", | 2794 | kdb_register_repeat("env", kdb_env, "", |
2854 | "Show environment variables", 0, KDB_REPEAT_NONE); | 2795 | "Show environment variables", 0, KDB_REPEAT_NONE); |
2855 | kdb_register_repeat("set", kdb_set, "", | 2796 | kdb_register_repeat("set", kdb_set, "", |