|
|
4f0e34 |
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
|
|
4f0e34 |
From: Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
|
|
|
4f0e34 |
Date: Wed, 7 Jul 2021 19:05:04 -0400
|
|
|
4f0e34 |
Subject: gdb-rhbz1854784-powerpc-remove-region-limit-dawr-6of7.patch
|
|
|
4f0e34 |
|
|
|
4f0e34 |
;; Backport "[PowerPC] Always clear watchpoint with PTRACE_SET_DEBUGREG"
|
|
|
4f0e34 |
;; (Pedro Franco de Carvalho, RH BZ 1854784)
|
|
|
4f0e34 |
|
|
|
4f0e34 |
This patches changes low_prepare_to_resume in the ppc linux native target
|
|
|
4f0e34 |
to always clear the watchpoint when the old PTRACE_SET_DEBUGREG interface
|
|
|
4f0e34 |
is used, even if another watchpoint GDB requested to the target is
|
|
|
4f0e34 |
written right after using the same call.
|
|
|
4f0e34 |
|
|
|
4f0e34 |
The reason for this is that there were some older kernel versions for
|
|
|
4f0e34 |
which overwriting a watchpoint with PTRACE_SET_DEBUGREG would not
|
|
|
4f0e34 |
re-activate the watchpoint if it was previouly disabled following a hit.
|
|
|
4f0e34 |
This happened when the kernel was configured with CONFIG_HW_BREAKPOINT on
|
|
|
4f0e34 |
and uses perf events to install watchpoints.
|
|
|
4f0e34 |
|
|
|
4f0e34 |
Previously, the ppc linux native target would immediately remove or
|
|
|
4f0e34 |
insert watchpoints following a request from the upper layers. This was
|
|
|
4f0e34 |
changed in commit 227c0bf4b3dd0cf65dceb58e729e9da81b38b5a7 to fix other
|
|
|
4f0e34 |
issues, which caused watchpoint requests to be applied to the inferior
|
|
|
4f0e34 |
only in low_prepare_to_resume, right before the inferior is resumed.
|
|
|
4f0e34 |
|
|
|
4f0e34 |
Usually, but maybe not always, after a hit, GDB will remove the
|
|
|
4f0e34 |
watchpoint, resume the inferior for a single-step, possibly report the
|
|
|
4f0e34 |
watchpoint hit to the user, and then re-insert the watchpoint before the
|
|
|
4f0e34 |
inferior is next resumed. In this case there would be no problems, but
|
|
|
4f0e34 |
since I can't guarantee that there aren't other paths in GDB that allow
|
|
|
4f0e34 |
the user to set a new watchpoint after the first one hit, and after its
|
|
|
4f0e34 |
deletion by GDB, but before the inferior is resumed, there is a chance
|
|
|
4f0e34 |
that PTRACE_SET_DEBUGREG could be called directly without the watchpoint
|
|
|
4f0e34 |
first having been cleared, which could cause a false negative with the
|
|
|
4f0e34 |
older kernel versions.
|
|
|
4f0e34 |
|
|
|
4f0e34 |
This issue would affect kernel versions starting from this commit:
|
|
|
4f0e34 |
|
|
|
4f0e34 |
5aae8a53708025d4e718f0d2e7c2f766779ddc71
|
|
|
4f0e34 |
|
|
|
4f0e34 |
Up to the fix in this commit:
|
|
|
4f0e34 |
|
|
|
4f0e34 |
a53fd61ac2f411745471c1c877d5e072fbbf0e5c
|
|
|
4f0e34 |
|
|
|
4f0e34 |
gdb/ChangeLog:
|
|
|
4f0e34 |
|
|
|
4f0e34 |
PR breakpoints/26385
|
|
|
4f0e34 |
* ppc-linux-nat.c (ppc_linux_nat_target::low_prepare_to_resume):
|
|
|
4f0e34 |
Always clear watchpoint with PTRACE_SET_DEBUGREG.
|
|
|
4f0e34 |
|
|
|
4f0e34 |
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
|
|
|
4f0e34 |
--- a/gdb/ppc-linux-nat.c
|
|
|
4f0e34 |
+++ b/gdb/ppc-linux-nat.c
|
|
|
4f0e34 |
@@ -2922,20 +2922,23 @@ ppc_linux_nat_target::low_prepare_to_resume (struct lwp_info *lp)
|
|
|
4f0e34 |
{
|
|
|
4f0e34 |
gdb_assert (m_dreg_interface.debugreg_p ());
|
|
|
4f0e34 |
|
|
|
4f0e34 |
- /* Passing 0 to PTRACE_SET_DEBUGREG will clear the
|
|
|
4f0e34 |
- watchpoint. */
|
|
|
4f0e34 |
- long wp = 0;
|
|
|
4f0e34 |
+ /* Passing 0 to PTRACE_SET_DEBUGREG will clear the watchpoint. We
|
|
|
4f0e34 |
+ always clear the watchpoint instead of just overwriting it, in
|
|
|
4f0e34 |
+ case there is a request for a new watchpoint, because on some
|
|
|
4f0e34 |
+ older kernel versions and configurations simply overwriting the
|
|
|
4f0e34 |
+ watchpoint after it was hit would not re-enable it. */
|
|
|
4f0e34 |
+ if (ptrace (PTRACE_SET_DEBUGREG, lp->ptid.lwp (), 0, 0) < 0)
|
|
|
4f0e34 |
+ perror_with_name (_("Error clearing hardware watchpoint"));
|
|
|
4f0e34 |
|
|
|
4f0e34 |
/* GDB requested a watchpoint to be installed. */
|
|
|
4f0e34 |
if (process_it != m_process_info.end ()
|
|
|
4f0e34 |
&& process_it->second.requested_wp_val.has_value ())
|
|
|
4f0e34 |
- wp = *(process_it->second.requested_wp_val);
|
|
|
4f0e34 |
-
|
|
|
4f0e34 |
- long ret = ptrace (PTRACE_SET_DEBUGREG, lp->ptid.lwp (),
|
|
|
4f0e34 |
- 0, wp);
|
|
|
4f0e34 |
+ {
|
|
|
4f0e34 |
+ long wp = *(process_it->second.requested_wp_val);
|
|
|
4f0e34 |
|
|
|
4f0e34 |
- if (ret < 0)
|
|
|
4f0e34 |
- perror_with_name (_("Error setting hardware watchpoint"));
|
|
|
4f0e34 |
+ if (ptrace (PTRACE_SET_DEBUGREG, lp->ptid.lwp (), 0, wp) < 0)
|
|
|
4f0e34 |
+ perror_with_name (_("Error setting hardware watchpoint"));
|
|
|
4f0e34 |
+ }
|
|
|
4f0e34 |
}
|
|
|
4f0e34 |
|
|
|
4f0e34 |
lp_arch_info->debug_regs_stale = false;
|