From c8f4bfdd120601d3841b2617b623412a47b8f35f Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Thu, 9 Apr 2015 10:20:48 +0100 Subject: [PATCH] gdbserver gnu/linux: stepping over breakpoint Hi, I see the following error on arm linux gdbserver, continue^M Continuing.^M ../../../binutils-gdb/gdb/gdbserver/linux-arm-low.c:458: A problem internal to GDBserver has been detected.^M raw_bkpt_type_to_arm_hwbp_type: unhandled raw type^M Remote connection closed^M (gdb) FAIL: gdb.base/cond-eval-mode.exp: hbreak: continue After we make GDBserver handling Zx/zx packet idempotent, [PATCH 3/3] [GDBserver] Make Zx/zx packet handling idempotent. https://sourceware.org/ml/gdb-patches/2014-04/msg00480.html > Now removal/insertion of all kinds of breakpoints/watchpoints, either > internal, or from GDB, always go through the target methods. GDBserver handles all kinds of breakpoints/watchpoints through target methods. However, some target backends, such as arm, don't support Z0 packet but need software breakpoint to do breakpoint stepping over in linux-low.c:start_step_over, if (can_hardware_single_step ()) { step = 1; } else { CORE_ADDR raddr = (*the_low_target.breakpoint_reinsert_addr) (); set_reinsert_breakpoint (raddr); step = 0; } a software breakpoint is requested to the backend, and the error is triggered. This problem should affect targets having breakpoint_reinsert_addr hooked. Instead of handling memory breakpoint in these affected linux backend, this patch handles memory breakpoint in linux_{insert,remove}_point, that, if memory breakpoint is requested, call {insert,remove}_memory_breakpoint respectively. Then, it becomes unnecessary to handle memory breakpoint for linux x86 backend, so this patch removes the code there. This patch is tested with GDBserver on x86_64-linux and arm-linux (-marm, -mthumb). Note that there are still some fails in gdb.base/cond-eval-mode.exp with -mthumb, because GDBserver doesn't know how to select the correct breakpoint instruction according to the arm-or-thumb-mode of requested address. This is a separate issue, anyway. gdb/gdbserver: 2015-04-09 Yao Qi * linux-low.c (linux_insert_point): Call insert_memory_breakpoint if TYPE is raw_bkpt_type_sw. (linux_remove_point): Call remove_memory_breakpoint if type is raw_bkpt_type_sw. * linux-x86-low.c (x86_insert_point): Don't call insert_memory_breakpoint. (x86_remove_point): Don't call remove_memory_breakpoint. --- gdb/gdbserver/ChangeLog | 10 ++++++++++ gdb/gdbserver/linux-low.c | 8 ++++++-- gdb/gdbserver/linux-x86-low.c | 6 ------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 5abdac2777..9bdc0de612 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,13 @@ +2015-04-09 Yao Qi + + * linux-low.c (linux_insert_point): Call + insert_memory_breakpoint if TYPE is raw_bkpt_type_sw. + (linux_remove_point): Call remove_memory_breakpoint if type is + raw_bkpt_type_sw. + * linux-x86-low.c (x86_insert_point): Don't call + insert_memory_breakpoint. + (x86_remove_point): Don't call remove_memory_breakpoint. + 2015-04-01 Pedro Alves Cleber Rosa diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index e4c54202e7..6dd922477d 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -5115,7 +5115,9 @@ static int linux_insert_point (enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp) { - if (the_low_target.insert_point != NULL) + if (type == raw_bkpt_type_sw) + return insert_memory_breakpoint (bp); + else if (the_low_target.insert_point != NULL) return the_low_target.insert_point (type, addr, size, bp); else /* Unsupported (see target.h). */ @@ -5126,7 +5128,9 @@ static int linux_remove_point (enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp) { - if (the_low_target.remove_point != NULL) + if (type == raw_bkpt_type_sw) + return remove_memory_breakpoint (bp); + else if (the_low_target.remove_point != NULL) return the_low_target.remove_point (type, addr, size, bp); else /* Unsupported (see target.h). */ diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c index e293ba4ffd..763df081f7 100644 --- a/gdb/gdbserver/linux-x86-low.c +++ b/gdb/gdbserver/linux-x86-low.c @@ -561,9 +561,6 @@ x86_insert_point (enum raw_bkpt_type type, CORE_ADDR addr, switch (type) { - case raw_bkpt_type_sw: - return insert_memory_breakpoint (bp); - case raw_bkpt_type_hw: case raw_bkpt_type_write_wp: case raw_bkpt_type_access_wp: @@ -590,9 +587,6 @@ x86_remove_point (enum raw_bkpt_type type, CORE_ADDR addr, switch (type) { - case raw_bkpt_type_sw: - return remove_memory_breakpoint (bp); - case raw_bkpt_type_hw: case raw_bkpt_type_write_wp: case raw_bkpt_type_access_wp: