i386/71715: [PATCH] Fix breakpoints for ddb and kgdb + improve kgdb
reg access
Stephan Uphoff
ups at tree.com
Mon Sep 13 21:00:54 PDT 2004
>Number: 71715
>Category: i386
>Synopsis: [PATCH] Fix breakpoints for ddb and kgdb + improve kgdb reg access
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-i386
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Sep 14 04:00:27 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Stephan Uphoff
>Release: FreeBSD 6.0-CURRENT i386
>Organization:
>Environment:
System: FreeBSD 6.0-CURRENT FreeBSD 6.0-CURRENT #14: Mon Sep 13 17:16:54 EDT 2004 root at giant:/usr/obj/usr/src/sys/GENERIC i386
>Description:
Breakpoint handling for i386 is currently broken in ddb and kgdb.
Mostly the cause of the problems was not keeping the kdb_pcb
and the trap frame for the current thread in sync for the instruction pointer.
Another problem was that gdb_rx_varhex assumes hex strings are for big
endian architecture.
This causes the val argument for gdb_cpu_setreg to be in network order.
To keep the patch small gdb_cpu_setreg now uses __bswap32() to convert the
value locally.
Kgdb was not able to read some registers since they are not in the pcb.
However for the important exception of the stopped thread important
registers can be read for the trap frame.
Please see the patch for details.
Disclaimer: This is not a pretty patch and only meant as a temporary
fix until a better solution is committed.
>How-To-Repeat:
Try using breakpoints in ddb or kgdb.
( set breakpoint ; continue ; stop at breakpoint ; continue)
>Fix:
--- debug.patch begins here ---
Index: sys/i386/include/db_machdep.h
===================================================================
RCS file: /cvsroot/src/sys/i386/include/db_machdep.h,v
retrieving revision 1.18
diff -u -r1.18 db_machdep.h
--- sys/i386/include/db_machdep.h 10 Jul 2004 23:47:19 -0000 1.18
+++ sys/i386/include/db_machdep.h 14 Sep 2004 02:34:57 -0000
@@ -41,9 +41,9 @@
#define BKPT_SIZE (1) /* size of breakpoint inst */
#define BKPT_SET(inst) (BKPT_INST)
-#define BKPT_SKIP kdb_frame->tf_eip += 1
+#define BKPT_SKIP do {kdb_frame->tf_eip += 1;kdb_thrctx->pcb_eip +=1;} while(0)
-#define FIXUP_PC_AFTER_BREAK kdb_frame->tf_eip -= 1;
+#define FIXUP_PC_AFTER_BREAK do {kdb_frame->tf_eip -= 1;kdb_thrctx->pcb_eip -=1;} while(0);
#define db_clear_single_step kdb_cpu_clear_singlestep
#define db_set_single_step kdb_cpu_set_singlestep
Index: sys/i386/i386/gdb_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/i386/i386/gdb_machdep.c,v
retrieving revision 1.1
diff -u -r1.1 gdb_machdep.c
--- sys/i386/i386/gdb_machdep.c 10 Jul 2004 17:47:21 -0000 1.1
+++ sys/i386/i386/gdb_machdep.c 14 Sep 2004 02:34:57 -0000
@@ -37,6 +37,9 @@
#include <machine/gdb_machdep.h>
#include <machine/pcb.h>
#include <machine/trap.h>
+#include <machine/frame.h>
+
+#include <machine/endian.h>
#include <gdb/gdb.h>
@@ -45,6 +48,15 @@
{
*regsz = gdb_cpu_regsz(regnum);
+
+ if (kdb_thread == curthread)
+ switch (regnum) {
+ case 0: return (&kdb_frame->tf_eax);
+ case 1: return (&kdb_frame->tf_ecx);
+ case 2: return (&kdb_frame->tf_edx);
+ }
+
+
switch (regnum) {
case 3: return (&kdb_thrctx->pcb_ebx);
case 4: return (&kdb_thrctx->pcb_esp);
@@ -60,8 +72,14 @@
gdb_cpu_setreg(int regnum, register_t val)
{
+ val = __bswap32(val);
+
switch (regnum) {
- case GDB_REG_PC: kdb_thrctx->pcb_eip = val; break;
+ case GDB_REG_PC:
+ kdb_thrctx->pcb_eip = val;
+ if (kdb_thread == curthread)
+ kdb_frame->tf_eip = val;
+ break;
}
}
--- debug.patch ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-i386
mailing list