tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: KGDB/i386 broken/supposed to work?



> I'll keep digging.

The problem is that KGDB isn't prepared to deal with the non-blocking serial port reads that matt's commit introduced in 2013 (am I really the first one to try this on bare metal since then?)

Where the read function `com_common_getc` used to block, it will now return -1, which KGDB happily takes for real input (an endless stream of 0xff) having arrived on the serial port.
This leads to excessively long input (from KGDB's perspective) which eventually makes it bail out of interpreting the received data.
Compare sys/kern/kgdb_stub.c:

268  while ((c = GETC()) != KGDB_END && len < maxlen) {
269          DPRINTF(("%c",c));
             [...]
273          len++;
274  }
     [...]    [`len` now has a significant value due to `c` repeatedly being -1]
     [...]    [so the following conditional is taken:]
279  if (len >= maxlen) {
280          DPRINTF(("Long- "));
281          PUTC(KGDB_BADP);
282          continue;
283  }

(It would have been easy to spot thanks to the DPRINTFs, but the one on line 269 completely flooded the console, preventing me from catching the one on line 280)

If I replace the `GETC` macro with a function that spins as long as -1 is "read", as in the patch below, the problem disappears.

The patch below is of course just an ad-hoc fix that Works For Me(TM), I'm currently not sure how to address the problem in a more general manner -- perhaps by providing a blocking interface to the serial port on top of the non-blocking one, in a way similar to what the `GETC` function below does, and directing kgdb to use that instead?


--- sys/kern/kgdb_stub.c.orig	2015-06-26 01:49:32.000000000 +0200
+++ sys/kern/kgdb_stub.c	2015-06-26 01:51:31.000000000 +0200
@@ -85,7 +85,17 @@
 static u_char buffer[KGDB_BUFLEN];
 static kgdb_reg_t gdb_regs[KGDB_NUMREGS];
 
-#define GETC()	((*kgdb_getc)(kgdb_ioarg))
+static int
+GETC(void)
+{
+	int c;
+
+	while ((c = kgdb_getc(kgdb_ioarg)) == -1)
+		;
+
+	return c;
+}
+//#define GETC()	((*kgdb_getc)(kgdb_ioarg))
 #define PUTC(c)	((*kgdb_putc)(kgdb_ioarg, c))
 
 /*


Home | Main Index | Thread Index | Old Index