This is an automated email from Gerrit. "Tomas Vanek <van...@fbl.cz>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6774
-- gerrit commit ebcafdeddd636da03c1ea67fcca95ef1c088620b Author: Tomas Vanek <van...@fbl.cz> Date: Mon Dec 6 18:56:44 2021 +0100 target/cortex_m: workaround setting invalid bp due to gdb bug Cortex-M uses "magic" addresses for exception return and lockup. The magic addresses are in execute never range. GDB bug in 'advance' and 'until' commands causes the magic in LR register is not properly handled and GDB tries to set a breakpoint at magic address. All tested versions of GDB up to current git master suffer from this bug. If gdb_server propagates the error from breakpoint setting to GDB, commands 'advance' and 'until' fail without running the target. How to replicate the problem with gdb (versions 8.3, 9.2, 10.2, 12.0.50) and a Cortex-M0/3/4 device with normal app loaded to the flash: (gdb) mon reset halt (gdb) step - synchronize GDB register cache after reset halt (gdb) info registers - check LR, CPU should set it to 0xffffffff (gdb) advance main Warning: Cannot insert breakpoint 0. Cannot access memory at address 0xfffffffe Command aborted. ----Part of openocd -d3 log:---- Debug: gdb_log_incoming_packet(): received packet: Z0,fffffffe,2 Debug: gdb_breakpoint_watchpoint_packet(): [stm32g4x.cpu] Debug: cmsis_dap_swd_read_process(): SWD ack not OK @ 4 FAULT ... Error: mem_ap_read(): Failed to read memory at 0xfffff000 Error: breakpoint_add_internal(): can't add breakpoint: unknown reason -------------------------------- Refuse setting a breakpoint at magic address. Do not propagate this error to GDB. Change-Id: I18aeab9e8a71c3eadbd5cf8782f570ce05eb0118 Signed-off-by: Tomas Vanek <van...@fbl.cz> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 0d2d1ae2c..6cb2d7ca5 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1750,6 +1750,17 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection, case 1: if (packet[0] == 'Z') { retval = breakpoint_add(target, address, size, bp_type); + /* + * GDB bug workaround: + * 'advance' and 'until' commands do not handle EXC_RETURN magic + * in LR register and try to set breakpoint at magic address. + * Propagation of the error to GDB would prevent target + * from run. Just ignore the error. + */ + if (retval == ERROR_TARGET_MAGIC_ADDRESS) { + LOG_DEBUG("GDB bug workaround: Breakpoint requested at magic address. Ignore to allow the target run."); + retval = ERROR_OK; + } if (retval != ERROR_OK) { retval = gdb_error(connection, retval); if (retval != ERROR_OK) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 649ee32f2..3b92c0db2 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -1586,6 +1586,18 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint return ERROR_OK; } + /* + * GDB bug workaround: + * 'advance' and 'until' commands do not handle EXC_RETURN magic + * in LR register and try to set breakpoint at magic address. + * gdb_server will not propagate this error to GDB. + */ + if (cortex_m_is_magic(breakpoint->address)) { + LOG_ERROR("Refusing to set breakpoint at magic address " + TARGET_ADDR_FMT, breakpoint->address); + return ERROR_TARGET_MAGIC_ADDRESS; + } + if (breakpoint->type == BKPT_HARD) { uint32_t fpcr_value; while (comparator_list[fp_num].used && (fp_num < cortex_m->fp_num_code)) --