public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Pedro Alves <palves@redhat.com>
To: Joel Brobecker <brobecker@adacore.com>,
	gdb-patches@sourceware.org,        qemu-devel@nongnu.org
Subject: Re: [RFA] Always consider infcall breakpoints as non-permanent.
Date: Fri, 21 Nov 2014 11:38:00 -0000	[thread overview]
Message-ID: <546F241D.6060903@redhat.com> (raw)
In-Reply-To: <1416501685-12457-1-git-send-email-brobecker@adacore.com>

[Adding qemu-devel@, so folks over there are aware of this.
Original thread at https://sourceware.org/ml/gdb-patches/2014-11/msg00478.html]

On 11/20/2014 04:41 PM, Joel Brobecker wrote:
> A recent change...
> 
>     commit 1a853c5224e2b8fedfac6d029365522b83080b40
>     Date:   Wed Nov 12 10:10:49 2014 +0000
>     Subject: make "permanent breakpoints" per location and disableable
> 
> ... broke function calls on sparc-elf when running over QEMU. Any
> function call should demonstrate the problem.
> 
> For instance, seen from the debugger:
> 
>     (gdb) call pn(1234)
>     [Inferior 1 (Remote target) exited normally]
>     The program being debugged exited while in a function called from GDB.
>     Evaluation of the expression containing the function
> 
> And seen from QEMU:
> 
>     qemu: fatal: Trap 0x02 while interrupts disabled, Error state
>     [register dump removed]

Bah.  Do you know whether this happens only on SPARC QEMU, or
is this an issue for all QEMU ports?

Basically, it sounds like with QEMU, GDB can't ever poke
breakpoint instructions to memory.  It must always set breakpoints
with the Z0 packet.

> 
> What happens in this case is that GDB sets the inferior function call
> by not only creating the dummy frame, but also writing a breakpoint
> instruction at the return address for our funcation call. See infcall.c:

"funcation"

> 
>         /* Write a legitimate instruction at the point where the infcall
>            breakpoint is going to be inserted.  While this instruction
>            is never going to be executed, a user investigating the
>            memory from GDB would see this instruction instead of random
>            uninitialized bytes.  We chose the breakpoint instruction
>            as it may look as the most logical one to the user and also
>            valgrind 3.7.0 needs it for proper vgdb inferior calls.
> 
>            If software breakpoints are unsupported for this target we
>            leave the user visible memory content uninitialized.  */
> 
>         bp_addr_as_address = bp_addr;
>         bp_bytes = gdbarch_breakpoint_from_pc (gdbarch, &bp_addr_as_address,
>                                                &bp_size);
>         if (bp_bytes != NULL)
>           write_memory (bp_addr_as_address, bp_bytes, bp_size);
> 
> This instruction triggers a change introduced by the commit above,
> where we consider bp locations as being permanent breakpoints
> if there is already a breakpoint instruction at that address:
> 
>         +  if (bp_loc_is_permanent (loc))
>         +    {
>         +      loc->inserted = 1;
>         +      loc->permanent = 1;
>         +    }
> 
> As a result, when resuming the program's execution for the inferior
> function call, GDB decides that it does not need to insert a breakpoint
> at this address, expecting the target to just report a SIGTRAP when
> trying to execute that instruction.
> 
> But unfortunately for us, at least some versions of QEMU for SPARC
> just terminate the execution entirely instead of reporting a breakpoint,
> thus producing the behavior reported here.
> 
> Although it appears like QEMU might be misbehaving and should therefore
> be fixed (to be verified) from the user's point of view, the recent
> change does introduce a regression. So this patch tries to mitigate
> a bit the damage by handling such infcall breakpoints as special and
> making sure that they are never considered permanent, thus restoring
> the previous behavior specifically for those breakpoints.
> 
> The option of not writing the breakpoint instructions ini the first

"ini"

> place was considered, and would probably work also. But the comment
> associated to it seems to indicate that there is still reason to
> keep it.
> 
> gdb/ChangeLog:
> 
>         * breakpoint.c (bp_loc_is_permanent): Return 0 if LOC corresponds
>         to a bp_call_dummy breakpoint type.
> 
> Tested on x86_64-linux. Also testing on sparc-elf/QEMU using
> AdaCore's testsuite.
> ---
>  gdb/breakpoint.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
> index 1c0a417..e22ac92 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
> @@ -9289,6 +9289,19 @@ bp_loc_is_permanent (struct bp_location *loc)
>  
>    gdb_assert (loc != NULL);
>  
> +  /* bp_call_dummy breakpoint locations are usually memory locations where
> +     GDB just wrote a breakpoint instruction, making it look as if there is
> +     a permanent breakpoint at that location.  Considering it permanent makes
> +     GDB rely on that breakpoint instruction to stop the program, thus removing
> +     the need to insert its own breakpoint there.  This is normally expected to
> +     work, except that some versions of QEMU (Eg: QEMU 2.0.0 for SPARC) just
> +     report a fatal problem (Trap 0x02 while interrupts disabled, Error state)
> +     intead of reporting a SIGTRAP.  QEMU should probably be fixed, but in

"intead"

> +     the interest of compatibility with versions that behave this way, we always
> +     consider bp_call_dummy breakpoint locations as non-permanent.  */
> +  if (loc->owner->type == bp_call_dummy)
> +    return 0;
> +
>    addr = loc->address;
>    bpoint = gdbarch_breakpoint_from_pc (loc->gdbarch, &addr, &len);

Patch is OK.  Thanks Joel.

Thanks,
Pedro Alves

  reply	other threads:[~2014-11-21 11:38 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-04 19:03 [PATCH 0/3] fix permanent breakpoints Pedro Alves
2014-11-04 19:03 ` [PATCH 1/3] add a default method for gdbarch_skip_permanent_breakpoint Pedro Alves
2014-11-04 19:03 ` [PATCH 2/3] make "permanent breakpoints" per location and disableable Pedro Alves
2014-11-05  6:37   ` Yao Qi
2014-11-12 10:55     ` Pedro Alves
2014-11-20 16:41       ` [RFA] Always consider infcall breakpoints as non-permanent Joel Brobecker
2014-11-21 11:38         ` Pedro Alves [this message]
2014-11-23 10:44           ` Joel Brobecker
2014-11-04 19:03 ` [PATCH 3/3] fix skipping permanent breakpoints Pedro Alves
2014-11-05 12:26   ` Yao Qi
2014-11-07 19:53     ` Pedro Alves
2014-11-12  0:54       ` Yao Qi
2014-11-12 10:53         ` Pedro Alves

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=546F241D.6060903@redhat.com \
    --to=palves@redhat.com \
    --cc=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    --cc=qemu-devel@nongnu.org \
    /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).