This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA] Make ppc-linux-nat insert/remove breakpoint and watchpoint functions return -1.
- From: Thiago Jung Bauermann <bauerman at br dot ibm dot com>
- To: gdb-patches ml <gdb-patches at sourceware dot org>
- Date: Tue, 05 Jul 2011 17:21:07 -0300
- Subject: [RFA] Make ppc-linux-nat insert/remove breakpoint and watchpoint functions return -1.
Hi,
target_{insert,remove}_{hw_breakpoint,watchpoint,mask_watchpoint} are
supposed to return 0, 1 and -1 for success, unsupported and error,
respectively. This patch makes ppc-linux-nat.c comply.
No regressions on ppc-linux and ppc64-linux. Ok?
--
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center
2011-07-05 Thiago Jung Bauermann <bauerman@br.ibm.com>
Make insert/remove breakpoint and watchpoint functions return -1.
* ppc-linux-nat.c (ppc_linux_remove_watchpoint): Add prototype.
(booke_insert_point): Return 0 on success and -1 on error.
(booke_remove_point): Likewise.
(ppc_linux_insert_hw_breakpoint): Return 0 on success, -1 on error
and 1 if hardware breakpoints are not supported. Also, remove the
breakpoint from all threads if it couldn't be installed in one
of them.
(ppc_linux_remove_hw_breakpoint): Likewise.
(ppc_linux_insert_mask_watchpoint): Likewise. Also, remove the
watchpoint from all threads if it couldn't be installed in one
of them.
(ppc_linux_remove_mask_watchpoint): Likewise.
(ppc_linux_insert_watchpoint): Likewise. Also, remove the
watchpoint from all threads if it couldn't be installed in one
of them.
(ppc_linux_remove_watchpoint): Likewise.
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index 275de78..410755f 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -336,6 +336,9 @@ PT_FPR0 + 56, PT_FPR0 + 58, PT_FPR0 + 60, PT_FPR0 + 62,
PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, PT_XER, PT_MQ */
/* *INDENT_ON * */
+static int ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
+ struct expression *cond);
+
static int
ppc_register_u_addr (struct gdbarch *gdbarch, int regno)
{
@@ -1566,8 +1569,10 @@ booke_find_thread_points_by_tid (int tid, int alloc_new)
/* This function is a generic wrapper that is responsible for inserting a
*point (i.e., calling `ptrace' in order to issue the request to the
- kernel) and registering it internally in GDB. */
-static void
+ kernel) and registering it internally in GDB. Returns 0 for success
+ or -1 for failure. */
+
+static int
booke_insert_point (struct ppc_hw_breakpoint *b, int tid)
{
int i;
@@ -1580,10 +1585,13 @@ booke_insert_point (struct ppc_hw_breakpoint *b, int tid)
memcpy (p, b, sizeof (struct ppc_hw_breakpoint));
- errno = 0;
slot = ptrace (PPC_PTRACE_SETHWDEBUG, tid, 0, p);
if (slot < 0)
- perror_with_name (_("Unexpected error setting breakpoint or watchpoint"));
+ {
+ do_cleanups (c);
+
+ return -1;
+ }
/* Everything went fine, so we have to register this *point. */
t = booke_find_thread_points_by_tid (tid, 1);
@@ -1602,15 +1610,19 @@ booke_insert_point (struct ppc_hw_breakpoint *b, int tid)
gdb_assert (i != max_slots_number);
discard_cleanups (c);
+
+ return 0;
}
/* This function is a generic wrapper that is responsible for removing a
*point (i.e., calling `ptrace' in order to issue the request to the
- kernel), and unregistering it internally at GDB. */
-static void
+ kernel), and unregistering it internally at GDB. Returns 0 for
+ success or -1 for failure. */
+
+static int
booke_remove_point (struct ppc_hw_breakpoint *b, int tid)
{
- int i;
+ int i, ret = 0;
struct hw_break_tuple *hw_breaks;
struct thread_points *t;
@@ -1622,7 +1634,9 @@ booke_remove_point (struct ppc_hw_breakpoint *b, int tid)
if (hw_breaks[i].hw_break && booke_cmp_hw_point (hw_breaks[i].hw_break, b))
break;
- gdb_assert (i != max_slots_number);
+ /* There's no such breakpoint/watchpoint for this thread. */
+ if (i == max_slots_number)
+ return -1;
/* We have to ignore ENOENT errors because the kernel implements hardware
breakpoints/watchpoints as "one-shot", that is, they are automatically
@@ -1630,11 +1644,12 @@ booke_remove_point (struct ppc_hw_breakpoint *b, int tid)
errno = 0;
if (ptrace (PPC_PTRACE_DELHWDEBUG, tid, 0, hw_breaks[i].slot) < 0)
if (errno != ENOENT)
- perror_with_name (_("Unexpected error deleting "
- "breakpoint or watchpoint"));
+ ret = -1;
xfree (hw_breaks[i].hw_break);
hw_breaks[i].hw_break = NULL;
+
+ return ret;
}
/* Return the number of registers needed for a ranged breakpoint. */
@@ -1652,14 +1667,15 @@ ppc_linux_ranged_break_num_registers (struct target_ops *target)
static int
ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
+ struct bp_target_info *bp_tgt)
{
+ int ret;
ptid_t ptid;
struct lwp_info *lp;
struct ppc_hw_breakpoint p;
if (!have_ptrace_booke_interface ())
- return -1;
+ return 1;
p.version = PPC_DEBUG_CURRENT_VERSION;
p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
@@ -1682,21 +1698,36 @@ ppc_linux_insert_hw_breakpoint (struct gdbarch *gdbarch,
}
ALL_LWPS (lp, ptid)
- booke_insert_point (&p, TIDGET (ptid));
+ {
+ ret = booke_insert_point (&p, TIDGET (ptid));
+ if (ret)
+ break;
+ }
- return 0;
+ /* If an error occurred, remove the breakpoint from all threads, to
+ keep consistency (all threads must have the same breakpoints and
+ watchpoints intalled.) */
+ if (ret)
+ ALL_LWPS (lp, ptid)
+ booke_remove_point (&p, TIDGET (ptid));
+
+ return ret;
}
+/* Remove the hardware breakpoint described by BP_TGT. Returns 0 for
+ success, 1 if hardware breakpoints are not supported or -1 for failure. */
+
static int
ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
+ struct bp_target_info *bp_tgt)
{
+ int ret = 0;
ptid_t ptid;
struct lwp_info *lp;
struct ppc_hw_breakpoint p;
if (!have_ptrace_booke_interface ())
- return -1;
+ return 1;
p.version = PPC_DEBUG_CURRENT_VERSION;
p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE;
@@ -1719,9 +1750,9 @@ ppc_linux_remove_hw_breakpoint (struct gdbarch *gdbarch,
}
ALL_LWPS (lp, ptid)
- booke_remove_point (&p, TIDGET (ptid));
+ ret |= booke_remove_point (&p, TIDGET (ptid));
- return 0;
+ return ret;
}
static int
@@ -1741,13 +1772,14 @@ get_trigger_type (int rw)
/* Insert a new masked watchpoint at ADDR using the mask MASK.
RW may be hw_read for a read watchpoint, hw_write for a write watchpoint
- or hw_access for an access watchpoint. Returns 0 on success and throws
- an error on failure. */
+ or hw_access for an access watchpoint. Returns 0 for success, 1 if
+ masked watchpoints are not supported or -1 for failure. */
static int
ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
CORE_ADDR mask, int rw)
{
+ int ret;
ptid_t ptid;
struct lwp_info *lp;
struct ppc_hw_breakpoint p;
@@ -1763,20 +1795,32 @@ ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
p.condition_value = 0;
ALL_LWPS (lp, ptid)
- booke_insert_point (&p, TIDGET (ptid));
+ {
+ ret = booke_insert_point (&p, TIDGET (ptid));
+ if (ret)
+ break;
+ }
- return 0;
+ /* If an error occurred, remove the breakpoint from all threads, to
+ keep consistency (all threads must have the same breakpoints and
+ watchpoints intalled.) */
+ if (ret)
+ ALL_LWPS (lp, ptid)
+ booke_remove_point (&p, TIDGET (ptid));
+
+ return ret;
}
/* Remove a masked watchpoint at ADDR with the mask MASK.
RW may be hw_read for a read watchpoint, hw_write for a write watchpoint
- or hw_access for an access watchpoint. Returns 0 on success and throws
- an error on failure. */
+ or hw_access for an access watchpoint. Returns 0 for success, 1 if
+ masked watchpoints are not supported or -1 for failure. */
static int
ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
CORE_ADDR mask, int rw)
{
+ int ret = 0;
ptid_t ptid;
struct lwp_info *lp;
struct ppc_hw_breakpoint p;
@@ -1792,9 +1836,9 @@ ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
p.condition_value = 0;
ALL_LWPS (lp, ptid)
- booke_remove_point (&p, TIDGET (ptid));
+ ret |= booke_remove_point (&p, TIDGET (ptid));
- return 0;
+ return ret;
}
/* Check whether we have at least one free DVC register. */
@@ -2054,13 +2098,18 @@ create_watchpoint_request (struct ppc_hw_breakpoint *p, CORE_ADDR addr,
p->addr = (uint64_t) addr;
}
+/* Insert a hardware watchpoint at address ADDR, spanning LEN bytes.
+ RW may be hw_read for a read watchpoint, hw_write for a write watchpoint
+ or hw_access for an access watchpoint. Returns 0 for success, 1 if
+ hardware watchpoints are not supported or -1 for failure. */
+
static int
ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
struct expression *cond)
{
struct lwp_info *lp;
ptid_t ptid;
- int ret = -1;
+ int ret;
if (have_ptrace_booke_interface ())
{
@@ -2069,9 +2118,18 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
create_watchpoint_request (&p, addr, len, rw, cond, 1);
ALL_LWPS (lp, ptid)
- booke_insert_point (&p, TIDGET (ptid));
+ {
+ ret = booke_insert_point (&p, TIDGET (ptid));
+ if (ret)
+ break;
+ }
- ret = 0;
+ /* If an error occurred, remove the breakpoint from all threads, to
+ keep consistency (all threads must have the same breakpoints and
+ watchpoints intalled.) */
+ if (ret)
+ ALL_LWPS (lp, ptid)
+ booke_remove_point (&p, TIDGET (ptid));
}
else
{
@@ -2111,25 +2169,38 @@ ppc_linux_insert_watchpoint (CORE_ADDR addr, int len, int rw,
}
saved_dabr_value = dabr_value;
+ ret = 0;
ALL_LWPS (lp, ptid)
if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0,
saved_dabr_value) < 0)
- return -1;
+ {
+ ret = -1;
+ break;
+ }
- ret = 0;
+ /* If an error occurred, remove the breakpoint from all threads, to
+ keep consistency (all threads must have the same breakpoints and
+ watchpoints intalled.) */
+ if (ret)
+ ppc_linux_remove_watchpoint (addr, len, rw, cond);
}
return ret;
}
+/* Remove a hardware watchpoint at address ADDR, spanning LEN bytes.
+ RW may be hw_read for a read watchpoint, hw_write for a write watchpoint
+ or hw_access for an access watchpoint. Returns 0 for success, 1 if
+ hardware watchpoints are not supported or -1 for failure. */
+
static int
ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
struct expression *cond)
{
struct lwp_info *lp;
ptid_t ptid;
- int ret = -1;
+ int ret = 0;
if (have_ptrace_booke_interface ())
{
@@ -2138,19 +2209,16 @@ ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw,
create_watchpoint_request (&p, addr, len, rw, cond, 0);
ALL_LWPS (lp, ptid)
- booke_remove_point (&p, TIDGET (ptid));
-
- ret = 0;
+ ret |= booke_remove_point (&p, TIDGET (ptid));
}
else
{
saved_dabr_value = 0;
+
ALL_LWPS (lp, ptid)
if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0,
saved_dabr_value) < 0)
- return -1;
-
- ret = 0;
+ ret = -1;
}
return ret;