[AArch64] Only check breakpoint alignment on inserting

This patch fixes the GDB internal error on AArch64 when running
watchpoint-fork.exp

 top?bt 15
 internal_error (file=file@entry=0x79d558 "../../binutils-gdb/gdb/linux-nat.c", line=line@entry=4866, fmt=0x793b20 "%s: Assertion `%s' failed.")
    at ../../binutils-gdb/gdb/common/errors.c:51
   0x0000000000495bc4 in linux_nat_thread_address_space (t=<optimized out>, ptid=<error reading variable: Cannot access memory at address 0x1302>)
    at ../../binutils-gdb/gdb/linux-nat.c:4866
   0x00000000005db2c8 in delegate_thread_address_space (self=<optimized out>, arg1=<error reading variable: Cannot access memory at address 0x1302>)
    at ../../binutils-gdb/gdb/target-delegates.c:2447
   0x00000000005e8c7c in target_thread_address_space (ptid=<error reading variable: Cannot access memory at address 0x1302>)
    at ../../binutils-gdb/gdb/target.c:2727
   0x000000000054eef8 in get_thread_arch_regcache (ptid=..., gdbarch=0xad51e0) at ../../binutils-gdb/gdb/regcache.c:529
   0x000000000054efcc in get_thread_regcache (ptid=...) at ../../binutils-gdb/gdb/regcache.c:546
   0x000000000054f120 in get_thread_regcache_for_ptid (ptid=...) at ../../binutils-gdb/gdb/regcache.c:560
   0x00000000004a2278 in aarch64_point_is_aligned (is_watchpoint=0, addr=34168, len=2) at ../../binutils-gdb/gdb/nat/aarch64-linux-hw-point.c:122
   0x00000000004a2e68 in aarch64_handle_breakpoint (type=hw_execute, addr=34168, len=2, is_insert=0, state=0xae8880)
    at ../../binutils-gdb/gdb/nat/aarch64-linux-hw-point.c:465
   0x000000000048edf0 in aarch64_linux_remove_hw_breakpoint (self=<optimized out>, gdbarch=<optimized out>, bp_tgt=<optimized out>)
    at ../../binutils-gdb/gdb/aarch64-linux-nat.c:657
  0x00000000005da8dc in delegate_remove_hw_breakpoint (self=<optimized out>, arg1=<optimized out>, arg2=<optimized out>)
    at ../../binutils-gdb/gdb/target-delegates.c:492
  0x0000000000536a24 in bkpt_remove_location (bl=<optimized out>) at ../../binutils-gdb/gdb/breakpoint.c:13065
  0x000000000053351c in remove_breakpoint_1 (bl=0xb3fe70, is=is@entry=mark_inserted) at ../../binutils-gdb/gdb/breakpoint.c:4026
  0x000000000053ccc0 in detach_breakpoints (ptid=...) at ../../binutils-gdb/gdb/breakpoint.c:3930
  0x00000000005a3ac0 in handle_inferior_event_1 (ecs=0x7ffffff048) at ../../binutils-gdb/gdb/infrun.c:5042

After the fork, GDB will physically remove the breakpoints from the child
process (in frame ), but at that time, GDB doesn't create an inferior
yet for child, but inferior_ptid is set to child's ptid (in frame ).
In aarch64_point_is_aligned, we'll get the regcache of current_lwp_ptid
to determine if the current process is 32-bit or 64-bit, so the inferior
can't be found, and the internal error is caused.

I don't find a better fix other than not checking alignment on removing
breakpoint.

gdb:

2015-11-27  Yao Qi  <yao.qi@linaro.org>

	* nat/aarch64-linux-hw-point.c (aarch64_dr_state_remove_one_point):
	Don't assert on alignment.
	(aarch64_handle_breakpoint): Only check alignment when IS_INSERT
	is true.
This commit is contained in:
Yao Qi
2015-11-27 14:53:32 +00:00
parent 58b584afe6
commit 805035d70c
2 changed files with 21 additions and 7 deletions

@ -1,3 +1,10 @@
2015-11-27 Yao Qi <yao.qi@linaro.org>
* nat/aarch64-linux-hw-point.c (aarch64_dr_state_remove_one_point):
Don't assert on alignment.
(aarch64_handle_breakpoint): Only check alignment when IS_INSERT
is true.
2015-11-27 Yao Qi <yao.qi@linaro.org> 2015-11-27 Yao Qi <yao.qi@linaro.org>
* aarch64-tdep.c (is_hfa): Rename to ... * aarch64-tdep.c (is_hfa): Rename to ...

@ -411,7 +411,6 @@ aarch64_dr_state_remove_one_point (struct aarch64_debug_reg_state *state,
/* Set up state pointers. */ /* Set up state pointers. */
is_watchpoint = (type != hw_execute); is_watchpoint = (type != hw_execute);
gdb_assert (aarch64_point_is_aligned (is_watchpoint, addr, len));
if (is_watchpoint) if (is_watchpoint)
{ {
num_regs = aarch64_num_wp_regs; num_regs = aarch64_num_wp_regs;
@ -459,14 +458,22 @@ int
aarch64_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr, aarch64_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr,
int len, int is_insert, int len, int is_insert,
struct aarch64_debug_reg_state *state) struct aarch64_debug_reg_state *state)
{
if (is_insert)
{ {
/* The hardware breakpoint on AArch64 should always be 4-byte /* The hardware breakpoint on AArch64 should always be 4-byte
aligned, but on AArch32, it can be 2-byte aligned. */ aligned, but on AArch32, it can be 2-byte aligned. Note that
we only check the alignment on inserting breakpoint because
aarch64_point_is_aligned needs the inferior_ptid inferior's
regcache to decide whether the inferior is 32-bit or 64-bit.
However when GDB follows the parent process and detach breakpoints
from child process, inferior_ptid is the child ptid, but the
child inferior doesn't exist in GDB's view yet. */
if (!aarch64_point_is_aligned (0 /* is_watchpoint */ , addr, len)) if (!aarch64_point_is_aligned (0 /* is_watchpoint */ , addr, len))
return -1; return -1;
if (is_insert)
return aarch64_dr_state_insert_one_point (state, type, addr, len); return aarch64_dr_state_insert_one_point (state, type, addr, len);
}
else else
return aarch64_dr_state_remove_one_point (state, type, addr, len); return aarch64_dr_state_remove_one_point (state, type, addr, len);
} }