Skip to contentSkip to conversation

kernel gdb for intel

PATCH Brent Baccala 2 participants 2 messages Aug 2, 2001

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hi -

I've been trying to track down a problem I've had with a USB CD-Burner locking up. In the course of my investigations I ported the i386 remote gdb stuff to the Linux kernel, because I'm used to using gdb on the kernel (it works on SPARC and PPC) instead of trying to read oopses.

For those not familiar with the remote debug feature, you use two computers, connected together with a null modem serial line. One computer has a complete Linux kernel tree on it, compiled with debugging information (-g); the other computer is the one running the kernel under test. You can breakpoint and halt the kernel, which puts it in a tight little loop reading packets (gdb, not IP) from the serial port and responding to the debugger. You get almost all the features you're used to with gdb - stack backtraces, single stepping, source-based variable names, intelligent structure decodes, etc.

Anyway, I'm attaching the patch (against 2.4.6). After installing, a menu option appears under "Kernel hacking" for remote debugging. Recompile the whole kernel (make clean) so that it compiles with debugging info. Then supply the "kgdb" switch to the kernel command line, make sure the debugging computer is attached on COM1 (or whatever you want to call it), and run "target remote /dev/whatever" on the debugging computer. See arch/i386/kernel/stub-i386.c for more info.

Known problems:

- only runs on COM1. Shouldn't be hard to fix this

- doesn't switch stacks, so you can't use gdb's "call" feature, which scribbles on the stack. Other than that, no problem.

- doesn't support SMP, since I don't have an Intel SMP box. I'd guess what you'd want it to do is an smp_call_function that would halt all the processors and put them into some tight little loop while gdb fiddles things. ideas?

- doesn't support any concept of multiple tasks/threads, though GDB can do this with it's remote protocol, and I've discovered that it'd be really nice to switch to another task within the kernel. Lacking this, you have to do stack backtraces by hand for other tasks.

- we have to compile Linux with -O2 to get inline functions, and this can confuse GDB sometimes. When in doubt, study the assembly.

And it still sometimes does some strange things, so might need some tweaks here and there, but works 95% of the time. Please try it out and let me know what you think.

Signature · 10 lines
                                        -bwb

                                        Brent Baccala
                                        [email protected]

==============================================================================
       For news from freesoft.org, subscribe to [email protected]:
   
mailto:[email protected]?subject=subscribe&body=subscribe
==============================================================================
Makefile +5 -0
diff -Nru linux-2.4.6-dist/Makefile linux-2.4.6-kgdb/Makefile
@@ -87,8 +87,13 @@
 
 CPPFLAGS := -D__KERNEL__ -I$(HPATH)
 
+ifdef CONFIG_REMOTE_DEBUG
+CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -g
+else
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
           -fomit-frame-pointer -fno-strict-aliasing
+endif
+
 AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
 
 #
arch/i386/config.in +1 -0
diff -Nru linux-2.4.6-dist/arch/i386/config.in linux-2.4.6-kgdb/arch/i386/config.in
@@ -388,4 +388,5 @@
 
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'Remote kernel debugger (gdb)' CONFIG_REMOTE_DEBUG
 endmenu
arch/i386/kernel/Makefile +1 -0
diff -Nru linux-2.4.6-dist/arch/i386/kernel/Makefile linux-2.4.6-kgdb/arch/i386/kernel/Makefile
@@ -40,5 +40,6 @@
 obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o mpparse.o
 obj-$(CONFIG_X86_VISWS_APIC)	+= visws_apic.o
+obj-$(CONFIG_REMOTE_DEBUG)	+= i386-stub.o
 
 include $(TOPDIR)/Rules.make
arch/i386/kernel/entry.S +107 -3

138 lines not on this page · raw message

arch/i386/kernel/i386-stub.c +622 -0

622 lines not on this page · raw message

arch/i386/kernel/setup.c +19 -0
diff -Nru linux-2.4.6-dist/arch/i386/kernel/setup.c linux-2.4.6-kgdb/arch/i386/kernel/setup.c
@@ -104,6 +104,12 @@
 #include <asm/dma.h>
 #include <asm/mpspec.h>
 #include <asm/mmu_context.h>
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern int serial_kgdb_hook(int);
+extern void set_debug_traps(void);
+#endif
+
 /*
  * Machine setup..
  */
@@ -1016,6 +1022,19 @@
 	low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
 	if (low_mem_size > pci_mem_start)
 		pci_mem_start = low_mem_size;
+
+#ifdef CONFIG_REMOTE_DEBUG
+	if (strstr(*cmdline_p, "kgdb") && (serial_kgdb_hook(0) == 0)) {
+
+	     /* We can't breakpoint yet because traps haven't been set up,
+	      * but we'll just grab the UART (serial_kgdb_hook did that)
+	      * and initialize.  We'll breakpoint in traps.c as soon
+	      * as it's ready.
+	      */
+
+	     set_debug_traps();
+        }
+#endif
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
arch/i386/kernel/traps.c +88 -2

148 lines not on this page · raw message

arch/i386/mm/fault.c +11 -0
diff -Nru linux-2.4.6-dist/arch/i386/mm/fault.c linux-2.4.6-kgdb/arch/i386/mm/fault.c
@@ -25,6 +25,10 @@
 
 extern void die(const char *,struct pt_regs *,long);
 
+#ifdef CONFIG_REMOTE_DEBUG
+extern char kgdb_initialized;
+#endif
+
 /*
  * Ugly, ugly, but the goto's result in better assembly..
  */
@@ -270,6 +274,13 @@
  * Oops. The kernel tried to access some bad page. We'll have to
  * terminate things with extreme prejudice.
  */
+
+#ifdef CONFIG_REMOTE_DEBUG
+	if (kgdb_initialized) {
+		handle_exception(11, regs);	/* 11 - SIGSEGV */
+		return;
+	}
+#endif
 
 	bust_spinlocks();
 
drivers/char/serial.c +237 -5

293 lines not on this page · raw message

#1 lore raw

Hi Brent,

You can have a look at http://kgdb.sourceforge.net/
That's where I maintain kgdb for x86.
It's many more features and lot of documentation which is not there in sparc and ppc kgdbs.

Quoted 26 lines · Brent Baccala

Hi -

I've been trying to track down a problem I've had with a USB CD-Burner locking up. In the course of my investigations I ported the i386 remote gdb stuff to the Linux kernel, because I'm used to using gdb on the kernel (it works on SPARC and PPC) instead of trying to read oopses.

For those not familiar with the remote debug feature, you use two computers, connected together with a null modem serial line. One computer has a complete Linux kernel tree on it, compiled with debugging information (-g); the other computer is the one running the kernel under test. You can breakpoint and halt the kernel, which puts it in a tight little loop reading packets (gdb, not IP) from the serial port and responding to the debugger. You get almost all the features you're used to with gdb - stack backtraces, single stepping, source-based variable names, intelligent structure decodes, etc.

Anyway, I'm attaching the patch (against 2.4.6). After installing, a menu option appears under "Kernel hacking" for remote debugging. Recompile the whole kernel (make clean) so that it compiles with debugging info. Then supply the "kgdb" switch to the kernel command line, make sure the debugging computer is attached on COM1 (or whatever you want to call it), and run "target remote /dev/whatever" on the debugging computer. See arch/i386/kernel/stub-i386.c for more info.

Signature · 2 lines
Amit Kale
Veritas Software ( http://www.veritas.com )