> 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))
 
 /*

Reply via email to