History

kdb,kgdb: Implement switch and pass buffer from kdb -> gdb

When switching from kdb mode to kgdb mode packets were getting lost depending on the size of the fifo queue of the serial chip. When gdb initially connects if it is in kdb mode it should entirely send any character buffer over to the gdbstub when switching connections. Previously kdb was zero'ing out the character buffer and this could lead to gdb failing to connect at all, or a lengthy pause could occur on the initial connect.

Jason Wessel committed 15 years ago

Commit f679c491 parent 3bdb65e4 files · +29 −21Browse files

Showing the changes to kernel/debug (4 of 4 files). Show all

Unified · Split

4 files
  1. kernel/debug/gdbstub.c +15 −7
  2. kernel/debug/kdb/kdb_debugger.c +7 −10
  3. kernel/debug/kdb/kdb_io.c +6 −4
  4. kernel/debug/kdb/kdb_private.h +1 −0
kernel/debug/gdbstub.c+15−7
@@ -42,6 +42,8 @@ · 41 unmodified lines
4242 /* Our I/O buffers. */
4343 static char remcom_in_buffer[BUFMAX];
4444 static char remcom_out_buffer[BUFMAX];
45+static int gdbstub_use_prev_in_buf;
46+static int gdbstub_prev_in_buf_pos;
4547
4648 /* Storage for the registers, in GDB format. */
4749 static unsigned long gdb_regs[(NUMREGBYTES +
@@ -58,6 +60,13 @@ static int gdbstub_read_wait(void) · 10 unmodified lines
5860 int ret = -1;
5961 int i;
6062
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+
6170 /* poll any additional I/O interfaces that are defined */
6271 while (ret < 0)
6372 for (i = 0; kdb_poll_funcs[i] != NULL; i++) {
@@ -109,7 +118,6 @@ static void get_packet(char *buffer) · 45 unmodified lines
109118 buffer[count] = ch;
110119 count = count + 1;
111120 }
112− buffer[count] = 0;
113121
114122 if (ch == '#') {
115123 xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4;
@@ -124,6 +132,7 @@ static void get_packet(char *buffer) · 8 unmodified lines
124132 if (dbg_io_ops->flush)
125133 dbg_io_ops->flush();
126134 }
135+ buffer[count] = 0;
127136 } while (checksum != xmitcsum);
128137 }
129138
@@ -1082,12 +1091,11 @@ int gdbstub_state(struct kgdb_state *ks, char *cmd) · 952 unmodified lines
10821091 case 'c':
10831092 strcpy(remcom_in_buffer, cmd);
10841093 return 0;
1085− case '?':
1086− gdb_cmd_status(ks);
1087− break;
1088− case '\0':
1089− strcpy(remcom_out_buffer, "");
1090− break;
1094+ case '$':
1095+ strcpy(remcom_in_buffer, cmd);
1096+ gdbstub_use_prev_in_buf = strlen(remcom_in_buffer);
1097+ gdbstub_prev_in_buf_pos = 0;
1098+ return 0;
10911099 }
10921100 dbg_io_ops->write_char('+');
10931101 put_packet(remcom_out_buffer);
kernel/debug/kdb/kdb_debugger.c+7−10
@@ -30,6 +30,8 @@ EXPORT_SYMBOL_GPL(kdb_poll_funcs); · 29 unmodified lines
3030 int kdb_poll_idx = 1;
3131 EXPORT_SYMBOL_GPL(kdb_poll_idx);
3232
33+static struct kgdb_state *kdb_ks;
34+
3335 int kdb_stub(struct kgdb_state *ks)
3436 {
3537 int error = 0;
@@ -39,6 +41,7 @@ int kdb_stub(struct kgdb_state *ks) · 3 unmodified lines
3941 kdb_dbtrap_t db_result = KDB_DB_NOBPT;
4042 int i;
4143
44+ kdb_ks = ks;
4245 if (KDB_STATE(REENTRY)) {
4346 reason = KDB_REASON_SWITCH;
4447 KDB_STATE_CLEAR(REENTRY);
@@ -124,16 +127,6 @@ int kdb_stub(struct kgdb_state *ks) · 79 unmodified lines
124127 kdbnearsym_cleanup();
125128 if (error == KDB_CMD_KGDB) {
126129 if (KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2)) {
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, "");
137130 KDB_STATE_CLEAR(DOING_KGDB);
138131 KDB_STATE_CLEAR(DOING_KGDB2);
139132 }
@@ -166,3 +159,7 @@ int kdb_stub(struct kgdb_state *ks) · 26 unmodified lines
166159 return kgdb_info[ks->cpu].ret_state;
167160 }
168161
162+void kdb_gdb_state_pass(char *buf)
163+{
164+ gdbstub_state(kdb_ks, buf);
165+}
kernel/debug/kdb/kdb_io.c+6−4
@@ -35,8 +35,8 @@ static void kgdb_transition_check(char *buffer) · 34 unmodified lines
3535 {
3636 int slen = strlen(buffer);
3737 if (strncmp(buffer, "$?#3f", slen) != 0 &&
38− strncmp(buffer, "$qSupported#37", slen) != 0 &&
39− strncmp(buffer, "+$qSupported#37", slen) != 0) {
38+ strncmp(buffer, "$qSupported", slen) != 0 &&
39+ strncmp(buffer, "+$qSupported", slen) != 0) {
4040 KDB_STATE_SET(KGDB_TRANS);
4141 kdb_printf("%s", buffer);
4242 }
@@ -390,12 +390,14 @@ poll_again: · 347 unmodified lines
390390 /* Special escape to kgdb */
391391 if (lastchar - buffer >= 5 &&
392392 strcmp(lastchar - 5, "$?#3f") == 0) {
393+ kdb_gdb_state_pass(lastchar - 5);
393394 strcpy(buffer, "kgdb");
394395 KDB_STATE_SET(DOING_KGDB);
395396 return buffer;
396397 }
397− if (lastchar - buffer >= 14 &&
398− strcmp(lastchar - 14, "$qSupported#37") == 0) {
398+ if (lastchar - buffer >= 11 &&
399+ strcmp(lastchar - 11, "$qSupported") == 0) {
400+ kdb_gdb_state_pass(lastchar - 11);
399401 strcpy(buffer, "kgdb");
400402 KDB_STATE_SET(DOING_KGDB2);
401403 return buffer;
kernel/debug/kdb/kdb_private.h+1−0
@@ -218,6 +218,7 @@ extern void kdb_print_nameval(const char *name, unsigned long val); · 217 unmodified lines
218218 extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info);
219219 extern void kdb_meminfo_proc_show(void);
220220 extern char *kdb_getstr(char *, size_t, char *);
221+extern void kdb_gdb_state_pass(char *buf);
221222
222223 /* Defines for kdb_symbol_print */
223224 #define KDB_SP_SPACEB 0x0001 /* Space before string */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t