Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F158008977
D29174.id85441.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D29174.id85441.diff
View Options
Index: sys/amd64/amd64/gdb_machdep.c
===================================================================
--- sys/amd64/amd64/gdb_machdep.c
+++ sys/amd64/amd64/gdb_machdep.c
@@ -152,6 +152,36 @@
return (SIGEMT);
}
+bool
+gdb_is_watchpoint_trap(int type, uintptr_t *addr)
+{
+ uint64_t dr6;
+
+ if (type != T_TRCTRAP)
+ return (false);
+
+ dr6 = rdr6();
+ load_dr6(dr6 & ~DBREG_DR6_BMASK);
+
+ if ((dr6 & DBREG_DR6_B(0)) != 0) {
+ *addr = rdr0();
+ return (true);
+ }
+ if ((dr6 & DBREG_DR6_B(1)) != 0) {
+ *addr = rdr1();
+ return (true);
+ }
+ if ((dr6 & DBREG_DR6_B(2)) != 0) {
+ *addr = rdr2();
+ return (true);
+ }
+ if ((dr6 & DBREG_DR6_B(3)) != 0) {
+ *addr = rdr3();
+ return (true);
+ }
+ return (false);
+}
+
void *
gdb_begin_write(void)
{
Index: sys/amd64/include/gdb_machdep.h
===================================================================
--- sys/amd64/include/gdb_machdep.h
+++ sys/amd64/include/gdb_machdep.h
@@ -72,5 +72,6 @@
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
void gdb_end_write(void *);
+bool gdb_is_watchpoint_trap(int type, uintptr_t *addr);
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
Index: sys/arm/include/gdb_machdep.h
===================================================================
--- sys/arm/include/gdb_machdep.h
+++ sys/arm/include/gdb_machdep.h
@@ -66,6 +66,14 @@
}
+static __inline bool
+gdb_is_watchpoint_trap(int type __unused, uintptr_t *addr __unused)
+{
+
+ /* Return false since we can't trivially find addr. */
+ return (false);
+}
+
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
Index: sys/arm64/include/gdb_machdep.h
===================================================================
--- sys/arm64/include/gdb_machdep.h
+++ sys/arm64/include/gdb_machdep.h
@@ -78,4 +78,12 @@
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
+static __inline bool
+gdb_is_watchpoint_trap(int type __unused, uintptr_t *addr __unused)
+{
+
+ /* Return false since we can't trivially find addr. */
+ return (false);
+}
+
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
Index: sys/gdb/gdb_main.c
===================================================================
--- sys/gdb/gdb_main.c
+++ sys/gdb/gdb_main.c
@@ -716,6 +716,28 @@
return;
}
+/*
+ * Communicate the stop reason for the trap to the gdb client.
+ *
+ * Normally, this is simply "thread:$tid". We can prepend more specific trap
+ * reasons when they are detected, such as the address that triggered a
+ * watchpoint. Doing so is never required, however.
+ *
+ * https://sourceware.org/gdb/onlinedocs/gdb/Stop-Reply-Packets.html
+ */
+static void
+gdb_trap_reason(int type)
+{
+ uintptr_t watch_addr;
+
+ if (gdb_is_watchpoint_trap(type, &watch_addr)) {
+ gdb_tx_str("watch:");
+ gdb_tx_varhex(watch_addr);
+ }
+ gdb_tx_str("thread:");
+ gdb_tx_varhex((uintmax_t)kdb_thread->td_tid);
+}
+
static int
gdb_trap(int type, int code)
{
@@ -745,8 +767,7 @@
gdb_tx_char(':');
gdb_tx_reg(GDB_REG_PC);
gdb_tx_char(';');
- gdb_tx_str("thread:");
- gdb_tx_varhex((long)kdb_thread->td_tid);
+ gdb_trap_reason(type);
gdb_tx_char(';');
gdb_tx_end(); /* XXX check error condition. */
Index: sys/i386/i386/gdb_machdep.c
===================================================================
--- sys/i386/i386/gdb_machdep.c
+++ sys/i386/i386/gdb_machdep.c
@@ -36,11 +36,12 @@
#include <sys/proc.h>
#include <sys/signal.h>
+#include <machine/endian.h>
+#include <machine/frame.h>
#include <machine/gdb_machdep.h>
#include <machine/pcb.h>
+#include <machine/reg.h>
#include <machine/trap.h>
-#include <machine/frame.h>
-#include <machine/endian.h>
#include <gdb/gdb.h>
@@ -114,3 +115,33 @@
}
return (SIGEMT);
}
+
+bool
+gdb_is_watchpoint_trap(int type, uintptr_t *addr)
+{
+ uint64_t dr6;
+
+ if (type != T_TRCTRAP)
+ return (false);
+
+ dr6 = rdr6();
+ load_dr6(dr6 & ~DBREG_DR6_BMASK);
+
+ if ((dr6 & DBREG_DR6_B(0)) != 0) {
+ *addr = rdr0();
+ return (true);
+ }
+ if ((dr6 & DBREG_DR6_B(1)) != 0) {
+ *addr = rdr1();
+ return (true);
+ }
+ if ((dr6 & DBREG_DR6_B(2)) != 0) {
+ *addr = rdr2();
+ return (true);
+ }
+ if ((dr6 & DBREG_DR6_B(3)) != 0) {
+ *addr = rdr3();
+ return (true);
+ }
+ return (false);
+}
Index: sys/i386/include/gdb_machdep.h
===================================================================
--- sys/i386/include/gdb_machdep.h
+++ sys/i386/include/gdb_machdep.h
@@ -63,5 +63,6 @@
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
+bool gdb_is_watchpoint_trap(int type, uintptr_t *addr);
#endif /* !_MACHINE_GDB_MACHDEP_H_ */
Index: sys/mips/include/gdb_machdep.h
===================================================================
--- sys/mips/include/gdb_machdep.h
+++ sys/mips/include/gdb_machdep.h
@@ -64,6 +64,13 @@
}
+static __inline bool
+gdb_is_watchpoint_trap(int type __unused, uintptr_t *addr __unused)
+{
+
+ return (false);
+}
+
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
Index: sys/powerpc/include/gdb_machdep.h
===================================================================
--- sys/powerpc/include/gdb_machdep.h
+++ sys/powerpc/include/gdb_machdep.h
@@ -128,6 +128,13 @@
}
+static __inline bool
+gdb_is_watchpoint_trap(int type __unused, uintptr_t *addr __unused)
+{
+
+ return (false);
+}
+
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, void *);
int gdb_cpu_signal(int, int);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, May 28, 11:00 AM (8 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33584241
Default Alt Text
D29174.id85441.diff (5 KB)
Attached To
Mode
D29174: gdb: report specific stop reason for watchpoints
Attached
Detach File
Event Timeline
Log In to Comment