public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-jankratochvil-watchpoint3: Provide workarounds for both RHBZ#660003 and RHBZ#660204.
@ 2010-12-06 3:54 jkratoch
0 siblings, 0 replies; only message in thread
From: jkratoch @ 2010-12-06 3:54 UTC (permalink / raw)
To: archer-commits
The branch, archer-jankratochvil-watchpoint3 has been updated
via 0fb20226dad52db5c9a6a8bb0d3e308cbee76a6f (commit)
from f4b3b3c77e4892760da95092c082e26be011d617 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 0fb20226dad52db5c9a6a8bb0d3e308cbee76a6f
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date: Mon Dec 6 04:53:12 2010 +0100
Provide workarounds for both RHBZ#660003 and RHBZ#660204.
-----------------------------------------------------------------------
Summary of changes:
gdb/amd64-linux-nat.c | 85 +++++++++++++++++++++++++-----------------------
gdb/linux-nat.c | 46 ++++++++++++++++++++++++++
gdb/linux-nat.h | 5 +++
3 files changed, 95 insertions(+), 41 deletions(-)
First 500 lines of diff:
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 03a0c74..c1e88a6 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -268,15 +268,10 @@ amd64_linux_store_inferior_registers (struct target_ops *ops,
static unsigned long amd64_linux_dr[DR_CONTROL + 1];
static unsigned long
-amd64_linux_dr_get (ptid_t ptid, int regnum)
+amd64_linux_dr_get (int tid, int regnum)
{
- int tid;
unsigned long value;
- tid = TIDGET (ptid);
- if (tid == 0)
- tid = PIDGET (ptid);
-
/* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
ptrace call fails breaks debugging remote targets. The correct
way to fix this is to add the hardware breakpoint and watchpoint
@@ -298,14 +293,8 @@ amd64_linux_dr_get (ptid_t ptid, int regnum)
/* Set debug register REGNUM to VALUE in only the one LWP of PTID. */
static void
-amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
+amd64_linux_dr_set (int tid, int regnum, unsigned long value)
{
- int tid;
-
- tid = TIDGET (ptid);
- if (tid == 0)
- tid = PIDGET (ptid);
-
errno = 0;
ptrace (PTRACE_POKEUSER, tid,
offsetof (struct user, u_debugreg[regnum]), value);
@@ -315,15 +304,26 @@ amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
/* Helper for amd64_linux_dr_set_control. */
-static int
-amd64_linux_dr_set_control_callback (struct lwp_info *lp, void *control_voidp)
+static void
+amd64_linux_dr_set_control_callback (int tid, void *control_voidp)
{
unsigned long control = (unsigned long) control_voidp;
+ int inferior_pid = ptid_get_pid (inferior_ptid);
+ struct inferior *inf = current_inferior ();
+
+ if (inf->pid != inferior_pid)
+ {
+ int i;
+
+ /* Workaround some kernel versions reporting EINVAL on setting
+ DR_CONTROL with still unset DR_*ADDR registers.
+ See: https://bugzilla.redhat.com/show_bug.cgi?id=660204 */
- amd64_linux_dr_set (lp->ptid, DR_CONTROL, control);
+ for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
+ amd64_linux_dr_set (tid, i, amd64_linux_dr[i]);
+ }
- /* Continue the traversal. */
- return 0;
+ amd64_linux_dr_set (tid, DR_CONTROL, control);
}
/* Set DR_CONTROL to ADDR in all LWPs of CURRENT_INFERIOR. */
@@ -333,8 +333,8 @@ amd64_linux_dr_set_control (unsigned long control)
{
amd64_linux_dr[DR_CONTROL] = control;
- iterate_over_lwps (pid_to_ptid (GET_PID (inferior_ptid)),
- amd64_linux_dr_set_control_callback, (void *) control);
+ linux_nat_iterate_watchpoint_lwps (amd64_linux_dr_set_control_callback,
+ (void *) control);
}
/* Helper for amd64_linux_dr_set_addr. */
@@ -345,15 +345,12 @@ struct amd64_linux_dr_set_addr_data
CORE_ADDR addr;
};
-static int
-amd64_linux_dr_set_addr_callback (struct lwp_info *lp, void *datap_voidp)
+static void
+amd64_linux_dr_set_addr_callback (int tid, void *datap_voidp)
{
const struct amd64_linux_dr_set_addr_data *datap = datap_voidp;
- amd64_linux_dr_set (lp->ptid, DR_FIRSTADDR + datap->regnum, datap->addr);
-
- /* Continue the traversal. */
- return 0;
+ amd64_linux_dr_set (tid, DR_FIRSTADDR + datap->regnum, datap->addr);
}
/* Set address REGNUM (zero based) to ADDR in all LWPs of CURRENT_INFERIOR.
@@ -370,8 +367,7 @@ amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
data.regnum = regnum;
data.addr = addr;
- iterate_over_lwps (pid_to_ptid (GET_PID (inferior_ptid)),
- amd64_linux_dr_set_addr_callback, &data);
+ linux_nat_iterate_watchpoint_lwps (amd64_linux_dr_set_addr_callback, &data);
}
/* Set address REGNUM (zero based) to zero in all LWPs of CURRENT_INFERIOR.
@@ -388,23 +384,26 @@ amd64_linux_dr_reset_addr (int regnum)
static unsigned long
amd64_linux_dr_get_status (void)
{
- return amd64_linux_dr_get (inferior_ptid, DR_STATUS);
+ int tid;
+
+ tid = TIDGET (inferior_ptid);
+ if (tid == 0)
+ tid = PIDGET (inferior_ptid);
+
+ return amd64_linux_dr_get (tid, DR_STATUS);
}
/* Helper for amd64_linux_dr_unset_status. */
-static int
-amd64_linux_dr_unset_status_callback (struct lwp_info *lp, void *mask_voidp)
+static void
+amd64_linux_dr_unset_status_callback (int tid, void *mask_voidp)
{
unsigned long mask = (unsigned long) mask_voidp;
unsigned long value;
- value = amd64_linux_dr_get (lp->ptid, DR_STATUS);
+ value = amd64_linux_dr_get (tid, DR_STATUS);
value &= ~mask;
- amd64_linux_dr_set (lp->ptid, DR_STATUS, value);
-
- /* Continue the traversal. */
- return 0;
+ amd64_linux_dr_set (tid, DR_STATUS, value);
}
/* Unset MASK bits in DR_STATUS in all LWPs of CURRENT_INFERIOR. */
@@ -412,19 +411,23 @@ amd64_linux_dr_unset_status_callback (struct lwp_info *lp, void *mask_voidp)
static void
amd64_linux_dr_unset_status (unsigned long mask)
{
- iterate_over_lwps (pid_to_ptid (GET_PID (inferior_ptid)),
- amd64_linux_dr_unset_status_callback, (void *) mask);
+ linux_nat_iterate_watchpoint_lwps (amd64_linux_dr_unset_status_callback,
+ (void *) mask);
}
static void
amd64_linux_new_thread (ptid_t ptid)
{
- int i;
+ int i, tid;
+
+ tid = TIDGET (ptid);
+ if (tid == 0)
+ tid = PIDGET (ptid);
for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
- amd64_linux_dr_set (ptid, i, amd64_linux_dr[i]);
+ amd64_linux_dr_set (tid, i, amd64_linux_dr[i]);
- amd64_linux_dr_set (ptid, DR_CONTROL, amd64_linux_dr[DR_CONTROL]);
+ amd64_linux_dr_set (tid, DR_CONTROL, amd64_linux_dr[DR_CONTROL]);
}
\f
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 56490cc..6794517 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -1243,6 +1243,52 @@ iterate_over_lwps (ptid_t filter,
return NULL;
}
+/* Helper for linux_nat_iterate_watchpoint_lwps. */
+
+struct iterate_watchpoint_lwps_data
+ {
+ linux_nat_iterate_watchpoint_lwps_ftype callback;
+ void *callback_data;
+ };
+
+static int
+iterate_watchpoint_lwps_callback (struct lwp_info *lp, void *datap_voidp)
+{
+ struct iterate_watchpoint_lwps_data *datap = datap_voidp;
+ int tid;
+
+ tid = TIDGET (lp->ptid);
+ if (tid == 0)
+ tid = PIDGET (lp->ptid);
+
+ datap->callback (tid, datap->callback_data);
+
+ /* Continue the traversal. */
+ return 0;
+}
+
+/* Iterate the same style like iterate_over_lwps does except when forking-off
+ a child call CALLBACK with CALLBACK_DATA specifically only for that new
+ child PID. */
+
+void
+linux_nat_iterate_watchpoint_lwps
+ (linux_nat_iterate_watchpoint_lwps_ftype callback, void *callback_data)
+{
+ struct iterate_watchpoint_lwps_data data;
+ int inferior_pid = ptid_get_pid (inferior_ptid);
+ struct inferior *inf = current_inferior ();
+
+ data.callback = callback;
+ data.callback_data = callback_data;
+
+ if (inf->pid == inferior_pid)
+ iterate_over_lwps (pid_to_ptid (inferior_pid),
+ iterate_watchpoint_lwps_callback, &data);
+ else
+ callback (inferior_pid, callback_data);
+}
+
/* Update our internal state when changing from one checkpoint to
another indicated by NEW_PTID. We can only switch single-threaded
applications, so we only create one new LWP, and the previous list
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index 64393fd..a053cbd 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -139,6 +139,11 @@ struct lwp_info *iterate_over_lwps (ptid_t filter,
void *),
void *data);
+typedef void (*linux_nat_iterate_watchpoint_lwps_ftype) (int tid, void *data);
+
+extern void linux_nat_iterate_watchpoint_lwps
+ (linux_nat_iterate_watchpoint_lwps_ftype callback, void *callback_data);
+
/* Create a prototype generic GNU/Linux target. The client can
override it with local methods. */
struct target_ops * linux_target (void);
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-12-06 3:54 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-06 3:54 [SCM] archer-jankratochvil-watchpoint3: Provide workarounds for both RHBZ#660003 and RHBZ#660204 jkratoch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).