diff options
Diffstat (limited to 'kernel/debug')
-rw-r--r-- | kernel/debug/gdbstub.c | 22 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_bt.c | 5 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_cmds | 4 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_debugger.c | 21 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_io.c | 36 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_main.c | 4 | ||||
-rw-r--r-- | kernel/debug/kdb/kdb_private.h | 3 |
7 files changed, 53 insertions, 42 deletions
diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c index a11db956dd62..34872482315e 100644 --- a/kernel/debug/gdbstub.c +++ b/kernel/debug/gdbstub.c | |||
@@ -42,6 +42,8 @@ | |||
42 | /* Our I/O buffers. */ | 42 | /* Our I/O buffers. */ |
43 | static char remcom_in_buffer[BUFMAX]; | 43 | static char remcom_in_buffer[BUFMAX]; |
44 | static char remcom_out_buffer[BUFMAX]; | 44 | static char remcom_out_buffer[BUFMAX]; |
45 | static int gdbstub_use_prev_in_buf; | ||
46 | static int gdbstub_prev_in_buf_pos; | ||
45 | 47 | ||
46 | /* Storage for the registers, in GDB format. */ | 48 | /* Storage for the registers, in GDB format. */ |
47 | static unsigned long gdb_regs[(NUMREGBYTES + | 49 | static unsigned long gdb_regs[(NUMREGBYTES + |
@@ -58,6 +60,13 @@ static int gdbstub_read_wait(void) | |||
58 | int ret = -1; | 60 | int ret = -1; |
59 | int i; | 61 | int i; |
60 | 62 | ||
63 | if (unlikely(gdbstub_use_prev_in_buf)) { | ||
64 | if (gdbstub_prev_in_buf_pos < gdbstub_use_prev_in_buf) | ||
65 | return remcom_in_buffer[gdbstub_prev_in_buf_pos++]; | ||
66 | else | ||
67 | gdbstub_use_prev_in_buf = 0; | ||
68 | } | ||
69 | |||
61 | /* poll any additional I/O interfaces that are defined */ | 70 | /* poll any additional I/O interfaces that are defined */ |
62 | while (ret < 0) | 71 | while (ret < 0) |
63 | for (i = 0; kdb_poll_funcs[i] != NULL; i++) { | 72 | for (i = 0; kdb_poll_funcs[i] != NULL; i++) { |
@@ -109,7 +118,6 @@ static void get_packet(char *buffer) | |||
109 | buffer[count] = ch; | 118 | buffer[count] = ch; |
110 | count = count + 1; | 119 | count = count + 1; |
111 | } | 120 | } |
112 | buffer[count] = 0; | ||
113 | 121 | ||
114 | if (ch == '#') { | 122 | if (ch == '#') { |
115 | xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4; | 123 | xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4; |
@@ -124,6 +132,7 @@ static void get_packet(char *buffer) | |||
124 | if (dbg_io_ops->flush) | 132 | if (dbg_io_ops->flush) |
125 | dbg_io_ops->flush(); | 133 | dbg_io_ops->flush(); |
126 | } | 134 | } |
135 | buffer[count] = 0; | ||
127 | } while (checksum != xmitcsum); | 136 | } while (checksum != xmitcsum); |
128 | } | 137 | } |
129 | 138 | ||
@@ -1082,12 +1091,11 @@ int gdbstub_state(struct kgdb_state *ks, char *cmd) | |||
1082 | case 'c': | 1091 | case 'c': |
1083 | strcpy(remcom_in_buffer, cmd); | 1092 | strcpy(remcom_in_buffer, cmd); |
1084 | return 0; | 1093 | return 0; |
1085 | case '?': | 1094 | case '$': |
1086 | gdb_cmd_status(ks); | 1095 | strcpy(remcom_in_buffer, cmd); |
1087 | break; | 1096 | gdbstub_use_prev_in_buf = strlen(remcom_in_buffer); |
1088 | case '\0': | 1097 | gdbstub_prev_in_buf_pos = 0; |
1089 | strcpy(remcom_out_buffer, ""); | 1098 | return 0; |
1090 | break; | ||
1091 | } | 1099 | } |
1092 | dbg_io_ops->write_char('+'); | 1100 | dbg_io_ops->write_char('+'); |
1093 | put_packet(remcom_out_buffer); | 1101 | put_packet(remcom_out_buffer); |
diff --git a/kernel/debug/kdb/kdb_bt.c b/kernel/debug/kdb/kdb_bt.c index 2f62fe85f16a..7179eac7b41c 100644 --- a/kernel/debug/kdb/kdb_bt.c +++ b/kernel/debug/kdb/kdb_bt.c | |||
@@ -112,9 +112,8 @@ kdb_bt(int argc, const char **argv) | |||
112 | unsigned long addr; | 112 | unsigned long addr; |
113 | long offset; | 113 | long offset; |
114 | 114 | ||
115 | kdbgetintenv("BTARGS", &argcount); /* Arguments to print */ | 115 | /* Prompt after each proc in bta */ |
116 | kdbgetintenv("BTAPROMPT", &btaprompt); /* Prompt after each | 116 | kdbgetintenv("BTAPROMPT", &btaprompt); |
117 | * proc in bta */ | ||
118 | 117 | ||
119 | if (strcmp(argv[0], "bta") == 0) { | 118 | if (strcmp(argv[0], "bta") == 0) { |
120 | struct task_struct *g, *p; | 119 | struct task_struct *g, *p; |
diff --git a/kernel/debug/kdb/kdb_cmds b/kernel/debug/kdb/kdb_cmds index 56c88e4db309..9834ad303ab6 100644 --- a/kernel/debug/kdb/kdb_cmds +++ b/kernel/debug/kdb/kdb_cmds | |||
@@ -18,16 +18,12 @@ defcmd dumpcommon "" "Common kdb debugging" | |||
18 | endefcmd | 18 | endefcmd |
19 | 19 | ||
20 | defcmd dumpall "" "First line debugging" | 20 | defcmd dumpall "" "First line debugging" |
21 | set BTSYMARG 1 | ||
22 | set BTARGS 9 | ||
23 | pid R | 21 | pid R |
24 | -dumpcommon | 22 | -dumpcommon |
25 | -bta | 23 | -bta |
26 | endefcmd | 24 | endefcmd |
27 | 25 | ||
28 | defcmd dumpcpu "" "Same as dumpall but only tasks on cpus" | 26 | defcmd dumpcpu "" "Same as dumpall but only tasks on cpus" |
29 | set BTSYMARG 1 | ||
30 | set BTARGS 9 | ||
31 | pid R | 27 | pid R |
32 | -dumpcommon | 28 | -dumpcommon |
33 | -btc | 29 | -btc |
diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index dd0b1b7dd02c..d9ca9aa481ec 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c | |||
@@ -30,6 +30,8 @@ EXPORT_SYMBOL_GPL(kdb_poll_funcs); | |||
30 | int kdb_poll_idx = 1; | 30 | int kdb_poll_idx = 1; |
31 | EXPORT_SYMBOL_GPL(kdb_poll_idx); | 31 | EXPORT_SYMBOL_GPL(kdb_poll_idx); |
32 | 32 | ||
33 | static struct kgdb_state *kdb_ks; | ||
34 | |||
33 | int kdb_stub(struct kgdb_state *ks) | 35 | int kdb_stub(struct kgdb_state *ks) |
34 | { | 36 | { |
35 | int error = 0; | 37 | int error = 0; |
@@ -39,6 +41,7 @@ int kdb_stub(struct kgdb_state *ks) | |||
39 | kdb_dbtrap_t db_result = KDB_DB_NOBPT; | 41 | kdb_dbtrap_t db_result = KDB_DB_NOBPT; |
40 | int i; | 42 | int i; |
41 | 43 | ||
44 | kdb_ks = ks; | ||
42 | if (KDB_STATE(REENTRY)) { | 45 | if (KDB_STATE(REENTRY)) { |
43 | reason = KDB_REASON_SWITCH; | 46 | reason = KDB_REASON_SWITCH; |
44 | KDB_STATE_CLEAR(REENTRY); | 47 | KDB_STATE_CLEAR(REENTRY); |
@@ -123,20 +126,8 @@ int kdb_stub(struct kgdb_state *ks) | |||
123 | KDB_STATE_CLEAR(PAGER); | 126 | KDB_STATE_CLEAR(PAGER); |
124 | kdbnearsym_cleanup(); | 127 | kdbnearsym_cleanup(); |
125 | if (error == KDB_CMD_KGDB) { | 128 | if (error == KDB_CMD_KGDB) { |
126 | if (KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2)) { | 129 | if (KDB_STATE(DOING_KGDB)) |
127 | /* | ||
128 | * This inteface glue which allows kdb to transition in into | ||
129 | * the gdb stub. In order to do this the '?' or '' gdb serial | ||
130 | * packet response is processed here. And then control is | ||
131 | * passed to the gdbstub. | ||
132 | */ | ||
133 | if (KDB_STATE(DOING_KGDB)) | ||
134 | gdbstub_state(ks, "?"); | ||
135 | else | ||
136 | gdbstub_state(ks, ""); | ||
137 | KDB_STATE_CLEAR(DOING_KGDB); | 130 | KDB_STATE_CLEAR(DOING_KGDB); |
138 | KDB_STATE_CLEAR(DOING_KGDB2); | ||
139 | } | ||
140 | return DBG_PASS_EVENT; | 131 | return DBG_PASS_EVENT; |
141 | } | 132 | } |
142 | kdb_bp_install(ks->linux_regs); | 133 | kdb_bp_install(ks->linux_regs); |
@@ -166,3 +157,7 @@ int kdb_stub(struct kgdb_state *ks) | |||
166 | return kgdb_info[ks->cpu].ret_state; | 157 | return kgdb_info[ks->cpu].ret_state; |
167 | } | 158 | } |
168 | 159 | ||
160 | void kdb_gdb_state_pass(char *buf) | ||
161 | { | ||
162 | gdbstub_state(kdb_ks, buf); | ||
163 | } | ||
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 96fdaac46a80..4802eb5840e1 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c | |||
@@ -31,15 +31,21 @@ char kdb_prompt_str[CMD_BUFLEN]; | |||
31 | 31 | ||
32 | int kdb_trap_printk; | 32 | int kdb_trap_printk; |
33 | 33 | ||
34 | static void kgdb_transition_check(char *buffer) | 34 | static int kgdb_transition_check(char *buffer) |
35 | { | 35 | { |
36 | int slen = strlen(buffer); | 36 | if (buffer[0] != '+' && buffer[0] != '$') { |
37 | if (strncmp(buffer, "$?#3f", slen) != 0 && | ||
38 | strncmp(buffer, "$qSupported#37", slen) != 0 && | ||
39 | strncmp(buffer, "+$qSupported#37", slen) != 0) { | ||
40 | KDB_STATE_SET(KGDB_TRANS); | 37 | KDB_STATE_SET(KGDB_TRANS); |
41 | kdb_printf("%s", buffer); | 38 | kdb_printf("%s", buffer); |
39 | } else { | ||
40 | int slen = strlen(buffer); | ||
41 | if (slen > 3 && buffer[slen - 3] == '#') { | ||
42 | kdb_gdb_state_pass(buffer); | ||
43 | strcpy(buffer, "kgdb"); | ||
44 | KDB_STATE_SET(DOING_KGDB); | ||
45 | return 1; | ||
46 | } | ||
42 | } | 47 | } |
48 | return 0; | ||
43 | } | 49 | } |
44 | 50 | ||
45 | static int kdb_read_get_key(char *buffer, size_t bufsize) | 51 | static int kdb_read_get_key(char *buffer, size_t bufsize) |
@@ -251,6 +257,10 @@ poll_again: | |||
251 | case 13: /* enter */ | 257 | case 13: /* enter */ |
252 | *lastchar++ = '\n'; | 258 | *lastchar++ = '\n'; |
253 | *lastchar++ = '\0'; | 259 | *lastchar++ = '\0'; |
260 | if (!KDB_STATE(KGDB_TRANS)) { | ||
261 | KDB_STATE_SET(KGDB_TRANS); | ||
262 | kdb_printf("%s", buffer); | ||
263 | } | ||
254 | kdb_printf("\n"); | 264 | kdb_printf("\n"); |
255 | return buffer; | 265 | return buffer; |
256 | case 4: /* Del */ | 266 | case 4: /* Del */ |
@@ -382,22 +392,26 @@ poll_again: | |||
382 | * printed characters if we think that | 392 | * printed characters if we think that |
383 | * kgdb is connecting, until the check | 393 | * kgdb is connecting, until the check |
384 | * fails */ | 394 | * fails */ |
385 | if (!KDB_STATE(KGDB_TRANS)) | 395 | if (!KDB_STATE(KGDB_TRANS)) { |
386 | kgdb_transition_check(buffer); | 396 | if (kgdb_transition_check(buffer)) |
387 | else | 397 | return buffer; |
398 | } else { | ||
388 | kdb_printf("%c", key); | 399 | kdb_printf("%c", key); |
400 | } | ||
389 | } | 401 | } |
390 | /* Special escape to kgdb */ | 402 | /* Special escape to kgdb */ |
391 | if (lastchar - buffer >= 5 && | 403 | if (lastchar - buffer >= 5 && |
392 | strcmp(lastchar - 5, "$?#3f") == 0) { | 404 | strcmp(lastchar - 5, "$?#3f") == 0) { |
405 | kdb_gdb_state_pass(lastchar - 5); | ||
393 | strcpy(buffer, "kgdb"); | 406 | strcpy(buffer, "kgdb"); |
394 | KDB_STATE_SET(DOING_KGDB); | 407 | KDB_STATE_SET(DOING_KGDB); |
395 | return buffer; | 408 | return buffer; |
396 | } | 409 | } |
397 | if (lastchar - buffer >= 14 && | 410 | if (lastchar - buffer >= 11 && |
398 | strcmp(lastchar - 14, "$qSupported#37") == 0) { | 411 | strcmp(lastchar - 11, "$qSupported") == 0) { |
412 | kdb_gdb_state_pass(lastchar - 11); | ||
399 | strcpy(buffer, "kgdb"); | 413 | strcpy(buffer, "kgdb"); |
400 | KDB_STATE_SET(DOING_KGDB2); | 414 | KDB_STATE_SET(DOING_KGDB); |
401 | return buffer; | 415 | return buffer; |
402 | } | 416 | } |
403 | } | 417 | } |
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index be14779bcef6..63786e71a3cd 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -145,7 +145,6 @@ static char *__env[] = { | |||
145 | #endif | 145 | #endif |
146 | "RADIX=16", | 146 | "RADIX=16", |
147 | "MDCOUNT=8", /* lines of md output */ | 147 | "MDCOUNT=8", /* lines of md output */ |
148 | "BTARGS=9", /* 9 possible args in bt */ | ||
149 | KDB_PLATFORM_ENV, | 148 | KDB_PLATFORM_ENV, |
150 | "DTABCOUNT=30", | 149 | "DTABCOUNT=30", |
151 | "NOSECT=1", | 150 | "NOSECT=1", |
@@ -172,6 +171,7 @@ static char *__env[] = { | |||
172 | (char *)0, | 171 | (char *)0, |
173 | (char *)0, | 172 | (char *)0, |
174 | (char *)0, | 173 | (char *)0, |
174 | (char *)0, | ||
175 | }; | 175 | }; |
176 | 176 | ||
177 | static const int __nenv = (sizeof(__env) / sizeof(char *)); | 177 | static const int __nenv = (sizeof(__env) / sizeof(char *)); |
@@ -1386,7 +1386,7 @@ int kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error, | |||
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | if (result == KDB_CMD_KGDB) { | 1388 | if (result == KDB_CMD_KGDB) { |
1389 | if (!(KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2))) | 1389 | if (!KDB_STATE(DOING_KGDB)) |
1390 | kdb_printf("Entering please attach debugger " | 1390 | kdb_printf("Entering please attach debugger " |
1391 | "or use $D#44+ or $3#33\n"); | 1391 | "or use $D#44+ or $3#33\n"); |
1392 | break; | 1392 | break; |
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 35d69ed1dfb5..e381d105b40b 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h | |||
@@ -21,7 +21,6 @@ | |||
21 | #define KDB_CMD_SS (-1003) | 21 | #define KDB_CMD_SS (-1003) |
22 | #define KDB_CMD_SSB (-1004) | 22 | #define KDB_CMD_SSB (-1004) |
23 | #define KDB_CMD_KGDB (-1005) | 23 | #define KDB_CMD_KGDB (-1005) |
24 | #define KDB_CMD_KGDB2 (-1006) | ||
25 | 24 | ||
26 | /* Internal debug flags */ | 25 | /* Internal debug flags */ |
27 | #define KDB_DEBUG_FLAG_BP 0x0002 /* Breakpoint subsystem debug */ | 26 | #define KDB_DEBUG_FLAG_BP 0x0002 /* Breakpoint subsystem debug */ |
@@ -146,7 +145,6 @@ extern int kdb_state; | |||
146 | * keyboard on this cpu */ | 145 | * keyboard on this cpu */ |
147 | #define KDB_STATE_KEXEC 0x00040000 /* kexec issued */ | 146 | #define KDB_STATE_KEXEC 0x00040000 /* kexec issued */ |
148 | #define KDB_STATE_DOING_KGDB 0x00080000 /* kgdb enter now issued */ | 147 | #define KDB_STATE_DOING_KGDB 0x00080000 /* kgdb enter now issued */ |
149 | #define KDB_STATE_DOING_KGDB2 0x00100000 /* kgdb enter now issued */ | ||
150 | #define KDB_STATE_KGDB_TRANS 0x00200000 /* Transition to kgdb */ | 148 | #define KDB_STATE_KGDB_TRANS 0x00200000 /* Transition to kgdb */ |
151 | #define KDB_STATE_ARCH 0xff000000 /* Reserved for arch | 149 | #define KDB_STATE_ARCH 0xff000000 /* Reserved for arch |
152 | * specific use */ | 150 | * specific use */ |
@@ -218,6 +216,7 @@ extern void kdb_print_nameval(const char *name, unsigned long val); | |||
218 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); | 216 | extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info); |
219 | extern void kdb_meminfo_proc_show(void); | 217 | extern void kdb_meminfo_proc_show(void); |
220 | extern char *kdb_getstr(char *, size_t, char *); | 218 | extern char *kdb_getstr(char *, size_t, char *); |
219 | extern void kdb_gdb_state_pass(char *buf); | ||
221 | 220 | ||
222 | /* Defines for kdb_symbol_print */ | 221 | /* Defines for kdb_symbol_print */ |
223 | #define KDB_SP_SPACEB 0x0001 /* Space before string */ | 222 | #define KDB_SP_SPACEB 0x0001 /* Space before string */ |