|
|
0b42f8 |
http://sourceware.org/ml/gdb-patches/2015-02/msg00731.html
|
|
|
0b42f8 |
Subject: [PATCH 5/8] Linux native: Use TRAP_BRKPT/TRAP_HWBPT
|
|
|
0b42f8 |
|
|
|
0b42f8 |
This patch adjusts the native Linux target backend to tell the core
|
|
|
0b42f8 |
whether a trap was caused by a breakpoint.
|
|
|
0b42f8 |
|
|
|
0b42f8 |
It teaches the target to get that information out of the si_code of
|
|
|
0b42f8 |
the SIGTRAP siginfo.
|
|
|
0b42f8 |
|
|
|
0b42f8 |
Tested on x86-64 Fedora 20, s390 RHEL 7, and PPC64 Fedora 18. An
|
|
|
0b42f8 |
earlier version was tested on ARM Fedora 21.
|
|
|
0b42f8 |
|
|
|
0b42f8 |
gdb/ChangeLog:
|
|
|
0b42f8 |
2015-02-25 Pedro Alves <palves@redhat.com>
|
|
|
0b42f8 |
|
|
|
0b42f8 |
* linux-nat.c (save_sigtrap): Check for breakpoints before
|
|
|
0b42f8 |
checking watchpoints.
|
|
|
0b42f8 |
(status_callback) [USE_SIGTRAP_SIGINFO]: Don't check whether a
|
|
|
0b42f8 |
breakpoint is inserted if relying on SIGTRAP's siginfo.si_code.
|
|
|
0b42f8 |
(check_stopped_by_breakpoint) [USE_SIGTRAP_SIGINFO]: Decide whether
|
|
|
0b42f8 |
a breakpoint triggered based on the SIGTRAP's siginfo.si_code.
|
|
|
0b42f8 |
(linux_nat_stopped_by_sw_breakpoint)
|
|
|
0b42f8 |
(linux_nat_supports_stopped_by_sw_breakpoint)
|
|
|
0b42f8 |
(linux_nat_stopped_by_hw_breakpoint)
|
|
|
0b42f8 |
(linux_nat_supports_stopped_by_hw_breakpoint): New functions.
|
|
|
0b42f8 |
(linux_nat_wait_1): Don't re-increment the PC if relying on
|
|
|
0b42f8 |
SIGTRAP's siginfo->si_code.
|
|
|
0b42f8 |
(linux_nat_add_target): Install new target methods.
|
|
|
0b42f8 |
* linux-thread-db.c (check_event): Don't account for breakpoint PC
|
|
|
0b42f8 |
offset if the target already adjusted the PC.
|
|
|
0b42f8 |
* nat/linux-ptrace.h (USE_SIGTRAP_SIGINFO): New.
|
|
|
0b42f8 |
(GDB_ARCH_TRAP_BRKPT): New.
|
|
|
0b42f8 |
(TRAP_HWBKPT): Define if not already defined.
|
|
|
0b42f8 |
---
|
|
|
0b42f8 |
gdb/linux-nat.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++---
|
|
|
0b42f8 |
gdb/linux-thread-db.c | 6 ++-
|
|
|
0b42f8 |
gdb/nat/linux-ptrace.h | 51 +++++++++++++++++++++++
|
|
|
0b42f8 |
3 files changed, 159 insertions(+), 7 deletions(-)
|
|
|
0b42f8 |
|
|
|
0b42f8 |
Index: gdb-7.6.1/gdb/linux-nat.c
|
|
|
0b42f8 |
===================================================================
|
|
|
0b42f8 |
--- gdb-7.6.1.orig/gdb/linux-nat.c 2016-03-13 19:26:22.736952457 +0100
|
|
|
0b42f8 |
+++ gdb-7.6.1/gdb/linux-nat.c 2016-03-13 19:45:29.343367943 +0100
|
|
|
0b42f8 |
@@ -1953,6 +1953,7 @@
|
|
|
0b42f8 |
otherwise handle_zombie_lwp_error would get confused. */
|
|
|
0b42f8 |
lp->stopped = 0;
|
|
|
0b42f8 |
lp->stopped_by_watchpoint = 0;
|
|
|
0b42f8 |
+ lp->stopped_by_hw_breakpoint = 0;
|
|
|
0b42f8 |
registers_changed_ptid (lp->ptid);
|
|
|
0b42f8 |
}
|
|
|
0b42f8 |
|
|
|
0b42f8 |
@@ -2874,6 +2875,15 @@
|
|
|
0b42f8 |
}
|
|
|
0b42f8 |
|
|
|
0b42f8 |
do_cleanups (old_chain);
|
|
|
0b42f8 |
+
|
|
|
0b42f8 |
+ {
|
|
|
0b42f8 |
+#define __SI_FAULT 0
|
|
|
0b42f8 |
+#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint/watchpoint */
|
|
|
0b42f8 |
+ siginfo_t siginfo;
|
|
|
0b42f8 |
+ if (linux_nat_get_siginfo (lp->ptid, &siginfo)
|
|
|
0b42f8 |
+ && siginfo.si_signo == SIGTRAP && siginfo.si_code == TRAP_HWBKPT)
|
|
|
0b42f8 |
+ lp->stopped_by_hw_breakpoint = 1;
|
|
|
0b42f8 |
+ }
|
|
|
0b42f8 |
}
|
|
|
0b42f8 |
|
|
|
0b42f8 |
/* See save_sigtrap. */
|
|
|
0b42f8 |
@@ -3162,6 +3172,17 @@
|
|
|
0b42f8 |
return 0;
|
|
|
0b42f8 |
}
|
|
|
0b42f8 |
|
|
|
0b42f8 |
+static int
|
|
|
0b42f8 |
+linux_nat_stopped_by_hw_breakpoint (struct target_ops *ops)
|
|
|
0b42f8 |
+{
|
|
|
0b42f8 |
+ struct lwp_info *lp = find_lwp_pid (inferior_ptid);
|
|
|
0b42f8 |
+
|
|
|
0b42f8 |
+ if (lp == NULL)
|
|
|
0b42f8 |
+ return 0;
|
|
|
0b42f8 |
+
|
|
|
0b42f8 |
+ return lp->stopped_by_hw_breakpoint;
|
|
|
0b42f8 |
+}
|
|
|
0b42f8 |
+
|
|
|
0b42f8 |
/* Select one LWP out of those that have events pending. */
|
|
|
0b42f8 |
|
|
|
0b42f8 |
static void
|
|
|
0b42f8 |
@@ -5233,6 +5254,7 @@
|
|
|
0b42f8 |
t->to_thread_address_space = linux_nat_thread_address_space;
|
|
|
0b42f8 |
t->to_stopped_by_watchpoint = linux_nat_stopped_by_watchpoint;
|
|
|
0b42f8 |
t->to_stopped_data_address = linux_nat_stopped_data_address;
|
|
|
0b42f8 |
+ t->to_stopped_by_hw_breakpoint = linux_nat_stopped_by_hw_breakpoint;
|
|
|
0b42f8 |
|
|
|
0b42f8 |
t->to_can_async_p = linux_nat_can_async_p;
|
|
|
0b42f8 |
t->to_is_async_p = linux_nat_is_async_p;
|
|
|
0b42f8 |
Index: gdb-7.6.1/gdb/linux-nat.h
|
|
|
0b42f8 |
===================================================================
|
|
|
0b42f8 |
--- gdb-7.6.1.orig/gdb/linux-nat.h 2016-03-13 19:26:19.411928036 +0100
|
|
|
0b42f8 |
+++ gdb-7.6.1/gdb/linux-nat.h 2016-03-13 19:44:29.437928457 +0100
|
|
|
0b42f8 |
@@ -80,6 +80,9 @@
|
|
|
0b42f8 |
watchpoint trap. */
|
|
|
0b42f8 |
int stopped_by_watchpoint;
|
|
|
0b42f8 |
|
|
|
0b42f8 |
+ /* RHEL: TARGET_STOPPED_BY_HW_BREAKPOINT */
|
|
|
0b42f8 |
+ int stopped_by_hw_breakpoint;
|
|
|
0b42f8 |
+
|
|
|
0b42f8 |
/* On architectures where it is possible to know the data address of
|
|
|
0b42f8 |
a triggered watchpoint, STOPPED_DATA_ADDRESS_P is non-zero, and
|
|
|
0b42f8 |
STOPPED_DATA_ADDRESS contains such data address. Otherwise,
|