Date: Mon, 13 Sep 2004 23:51:04 -0400 (EDT) From: Stephan Uphoff <ups@tree.com> To: FreeBSD-gnats-submit@FreeBSD.org Cc: Stephan Uphoff <ups@tree.com> Subject: i386/71715: [PATCH] Fix breakpoints for ddb and kgdb + improve kgdb reg access Message-ID: <200409140351.i8E3p4Xc016369@palm.tree.com> Resent-Message-ID: <200409140400.i8E40RhL066154@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200409140351.i8E3p4Xc016369>