Hi This patch takes care of 2 things related to remote debuging of Linux kernel using Gdb Problem and Solution (1) ------------------------ When trying out Remote Debugging of Linux kernel using GDB, I found a possible protocol synchronisation issue between gdb (in host) and gdbstub (on RemoteTarget) in the current gdb remote protocol implementation (i.e which don't use the SequenceNumber mechanism of the protocol). The situation unfolds as follows 1) HostGdb sends a command to the RemoteTargetStub. 2) Before the RemoteTargetStub can process the command a exception or breakpoint occurs. Or the RemoteTargetStub is getting activated only now during booting of the RemoteTarget m/c. 3) RemoteTargetStub sends Sxx to HostGDB. HostGDB takes this as response to command from 1 above (or ignores the command from 1 due to this) 4) HostGDB sends a new gdb command. 5) RemoteTargetStub picks up the old gdb command (from 1), and responds to it. 6) HostGDB assumes its the response to the new command from 4 above, but actually its response to the old (now stale or no longer valid) command from 1 above. Thus the RemoteTargetGdbStub and the HostGDB go out of sync. I faced this problem when trying out remote debuging between a Linux Host and a PC Emulation software (vmware or so) using /dev/ptyq0 and /dev/ttyq0 for communication. On looking into this I found this possible synchronisation problem between the Host and Remote in GDB protocol, if there is any content or old command in the Recieve buffers (s/w buffer in gdbserial.c and or h/w buffer of uart) due to what ever reason. To solve this problem I have implemented a clearRecieveDataBufferGDB in gdbserail which when invoked will clear all buffered contents associated with recieving ((a) the s/w buffer in gdbserial and (b) the buffer in uart). It uses the existing read_char implementation of gdbserial in a loop to accomplish this. INTURN I call this from with in handle_exception of gdbstub just before sending SXX signal(to notify of the exception) to HostGDB, So that handle_exception won't respond to any old (and no longer valid)command or invalid data in the Recieve buffer. Problem and Solution (2) ------------------------ Also I noticed that HostGDB was sending a qOffsets query to the RemoteTargetStub, but x86 gdbstub doesn't currently provide a implementation for qOffset. So I implemented one which uses the following symbols to provide the required offsets stext for Text gdt_table for Data (currently corresponds to .data or sdata) __bss_start for Bss. However once Implemented I did find that HostGDBs symbol info was getting corrupted and I was forced to reload the symbols using symbol_file. On looking into gdb source casualy it felt as if I can ignore qOffsets command. Either way I already had a implementation (which is very simple) for qOffsets command, so I have retained it in the patch __as the bug__ seems to be __in the HostGDB code__. On looking into other gdbstub implementations in the linux kernel Even the PPC arch's gdbstub talks about this bug in HostGDB. Also I picked up the elegent sprintf solution to create the response string for qOffset from the PPC guys. Earlier I had tried a solution with mem2hex which retains the Bytes of the address in the Target Byte order, but for qOffset one requires to represent the address (in Hex) in the normal reading order (varified by looking into remote.c in gdb source) which automaticaly suites the sprintf solution. These problem seems to be universal as far as gdb remote debug protocols current implementations are concerned, so may be even the GDB guys need to be informed about these possible problems. But I am not in the GDB devel list, so someone on the list can inform them also. ----------- Keep :-) HanishKVC
diff -Naur linux-2.4.3-kgdb/arch/i386/kernel/gdbstub.c linux-2.4.3-kgdb-hankvc/arch/i386/kernel/gdbstub.c --- linux-2.4.3-kgdb/arch/i386/kernel/gdbstub.c Sun Apr 29 21:25:20 2001 +++ linux-2.4.3-kgdb-hankvc/arch/i386/kernel/gdbstub.c Mon Apr 30 01:53:12 2001 @@ -116,6 +116,7 @@ /* Thread reference */ typedef unsigned char threadref[8]; +extern void clearRecieveDataBufferGDB(void); /* clear the Recieve software and +hardware data buffers */ extern int putDebugChar(int); /* write a single character */ extern int getDebugChar(void); /* read and return a single char */ @@ -765,6 +766,7 @@ int i; int dr6; struct pt_regs tempregs; + extern int stext,gdt_table,__bss_start; #define regs (*linux_regs) /* @@ -830,6 +832,10 @@ gdb_i386vector = exceptionVector; gdb_i386errcode = err_code ; + /* clear existing (possibly stale) contents in the Recieve buffers + (s/w(gdbserial) and h/w) of the terminal/SerialPort used for + remote debugging, so that we start with a clean slate */ + clearRecieveDataBufferGDB(); /* reply to host that an exception has occurred */ remcomOutBuffer[0] = 'S'; remcomOutBuffer[1] = hexchars[signo >> 4]; @@ -1043,6 +1049,17 @@ case 'E': /* Print exception info */ printexceptioninfo(exceptionVector, err_code, remcomOutBuffer); + break; + + case 'O': + /* get Section offsets */ + /* gdb's symbol info seems to be getting corrupted +after + this command, even ppc guys have mentioned this. + One is required to reload using symbol-file cmd */ + /* .data (or sdata) currently correspond to gdt_table +*/ + sprintf(remcomOutBuffer, + "Text=%8.8x;Data=%8.8x;Bss=%8.8x", + (int)&stext, (int)&gdt_table, (int)&__bss_start); break; } break; diff -Naur linux-2.4.3-kgdb/drivers/char/gdbserial.c linux-2.4.3-kgdb-hankvc/drivers/char/gdbserial.c --- linux-2.4.3-kgdb/drivers/char/gdbserial.c Sun Apr 29 21:25:20 2001 +++ linux-2.4.3-kgdb-hankvc/drivers/char/gdbserial.c Mon Apr 30 02:14:15 2001 @@ -278,3 +278,25 @@ } /* putDebugChar */ +/* + * Clear the Recieve software and hardware buffers + */ +void clearRecieveDataBufferGDB(void) +{ + int iCur; + +#ifdef PRNT + printk("clearRecieveDataBufferGDB: Entering \n"); +#endif + /* while((iCur=read_data_bfr()) != -1) */ + while((iCur=read_char()) != -1) +#ifdef PRNT + printk("clearRecieveDataBufferGDB: read %c \n",iCur); +#else + ; +#endif +#ifdef PRNT + printk("clearRecieveDataBufferGDB: Leaving \n"); +#endif +} +