public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Luis Machado <luis.machado@arm.com>
To: Tomas Vanek <vanekt@fbl.cz>,
	gdb-patches@sourceware.org,
	Torbjorn SVENSSON <torbjorn.svensson@foss.st.com>
Subject: Re: [PATCH] gdb: Modify until_break_command to act correctly on SIGTRAMP_FRAME
Date: Fri, 21 Oct 2022 10:47:55 +0100	[thread overview]
Message-ID: <bdd7ac1f-d817-5d9a-26ed-65608df4a725@arm.com> (raw)
In-Reply-To: <1666035571-19996-1-git-send-email-vanekt@fbl.cz>

Hi Tomas,

Thanks for the patch.

You should reference the bugzilla ticket https://sourceware.org/bugzilla/show_bug.cgi?id=28683.

On 10/17/22 20:39, Tomas Vanek wrote:
> This patch partially depends on
> gdb/arm: Terminate frame unwinding in M-profile lockup state
> (without it lockup state is unwound as it were normal stack frame)

as it were -> as if it were a

> 
> The commands 'advance' and 'until' try to set a breakpoint
> on the bogus return address derived from Arm M-profile magic
> address (actually EXC_RETURN or a PC value indicating lockup).
> 
> The offending breakpoint should be set at return address to

at return -> at the return

to the caller function -> in the caller?

> the caller function. The magic value 0xffffffff in LR indicates
> there is no caller (return to this address would lock up the CPU).
> 
> Similar behaviour of 'advance' and 'until' is observed in
> an exception handler routine. In this case LR contains e.g.
> 0xfffffff1 (EXC_RETURN) and GDB tries to set a breakpoint at
> 0xfffffff0. It should use a return value stacked by the exception
> instead.
> 
> Testbench setup:
> STM32G474, a Cortex-M4 device. Any Cortex-M device can be used.
> A test application (an ordinary blink) with a standard startup
> is loaded to the device flash.
> 
> Steps to reproduce the problem:
> 
> start GDB server
>   $ openocd -f interface/cmsis-dap.cfg -f target/stm32g4x.cfg
> 
> start GDB in second terminal
>   $ arm-none-eabi-gdb blink.elf
> 
>   (gdb) target extended-remote localhost:3333
> 
> Reset the device and halt it:
>   (gdb) monitor reset halt
>   target halted due to debug-request, current mode: Thread
>   xPSR: 0x01000000 pc: 0x08000e14 msp: 0x20020000
> 
> Step by one instruction to re-read GDB register cache:
>   (gdb) stepi
> 
> Check registers, LR should be 0xffffffff after reset:
>   (gdb) info registers
>   ...
>   sp             0x20020000          0x20020000
>   lr             0xffffffff          -1
>   pc             0x8000e16           0x8000e16
>   xPSR           0x1000000           16777216
>   ...
> 
>   (gdb) set debug remote
> 
> Issue 'advance' command:
>   (gdb) advance main
>   [remote] Sending packet: $mfffffffe,2#fa
>   [remote] Packet received: 0000
>   [remote] Sending packet: $mfffffffe,2#fa
>   [remote] Packet received: 0000
>   [remote] Sending packet: $m8000526,2#30
>   [remote] Packet received: 2046
>   [remote] Sending packet: $Z1,8000526,2#7a
>   [remote] Packet received: OK
>   [remote] packet_ok: Packet Z1 (hardware-breakpoint) is supported
>   [remote] Sending packet: $Z0,fffffffe,2#43
>   [remote] Packet received: E0E
>   [remote] packet_ok: Packet Z0 (software-breakpoint) is supported
>   Warning:
>   Cannot insert breakpoint 0.
>   Cannot access memory at address 0xfffffffe
> 
>   Command aborted.
>   (gdb)
> 
> Relevant messages from OpenOCD:
>   Error: Failed to read memory at 0xfffff000
>   Error: can't add breakpoint: unknown reason
> 
> This patch adds skipping over frames that are not suitable for
> guarding with a breakpoint inspired by 'finish' command.
> If no suitable frame is found, a momentrary breakpoint is not set.

momentrary -> momentary

> ---
>   gdb/breakpoint.c | 22 +++++++++++++++++-----
>   1 file changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
> index f6591d4..bb85342 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
> @@ -10467,6 +10467,7 @@ enum async_reply_reason
>   until_break_command (const char *arg, int from_tty, int anywhere)
>   {
>     frame_info_ptr frame;
> +  frame_info_ptr caller_frame;
>     struct gdbarch *frame_gdbarch;
>     struct frame_id stack_frame_id;
>     struct frame_id caller_frame_id;
> @@ -10505,7 +10506,17 @@ enum async_reply_reason
>     frame = get_selected_frame (NULL);
>     frame_gdbarch = get_frame_arch (frame);
>     stack_frame_id = get_stack_frame_id (frame);
> -  caller_frame_id = frame_unwind_caller_id (frame);
> +
> +  caller_frame = get_prev_frame_always (frame);
> +
> +  while (caller_frame)
> +    {
> +      if (get_frame_type (caller_frame) != TAILCALL_FRAME
> +	  && gdbarch_code_of_frame_writable (get_frame_arch (caller_frame), caller_frame))
> +	break;
> +
> +      caller_frame = get_prev_frame_always (caller_frame);
> +    }
>   
>     /* Keep within the current frame, or in frames called by the current
>        one.  */
> @@ -10514,14 +10525,15 @@ enum async_reply_reason
>   
>     gdb::optional<delete_longjmp_breakpoint_cleanup> lj_deleter;
>   
> -  if (frame_id_p (caller_frame_id))
> +  if (caller_frame)
>       {
>         struct symtab_and_line sal2;
>         struct gdbarch *caller_gdbarch;
>   
> -      sal2 = find_pc_line (frame_unwind_caller_pc (frame), 0);
> -      sal2.pc = frame_unwind_caller_pc (frame);
> -      caller_gdbarch = frame_unwind_caller_arch (frame);
> +      sal2 = find_pc_line (get_frame_pc (caller_frame), 0);
> +      sal2.pc = get_frame_pc (caller_frame);
> +      caller_gdbarch = get_frame_arch (caller_frame);
> +      caller_frame_id = get_frame_id (caller_frame);
>   
>         breakpoint_up caller_breakpoint
>   	= set_momentary_breakpoint (caller_gdbarch, sal2,

If we use the magic value of 0xFFFFFFFF as a way to stop unwinding, doesn't the until_break_command code handle
this automatically? I mean, if there are no outer frames, then it won't attempt to insert a breakpoint.

Is that the case?

      reply	other threads:[~2022-10-21  9:48 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-17 19:39 Tomas Vanek
2022-10-21  9:47 ` Luis Machado [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bdd7ac1f-d817-5d9a-26ed-65608df4a725@arm.com \
    --to=luis.machado@arm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=torbjorn.svensson@foss.st.com \
    --cc=vanekt@fbl.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).