Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Sergio Durigan Junior <sergiodj@redhat.com>
To: Pedro Alves <palves@redhat.com>
Cc: Yao Qi <yao@codesourcery.com>, GDB Patches <gdb-patches@sourceware.org>
Subject: Re: [PATCH] Fix gdb.trace/mi-traceframe-changed.exp to check for target trace support
Date: Fri, 10 Jan 2014 20:41:00 -0000	[thread overview]
Message-ID: <m31u0fmuxv.fsf@redhat.com> (raw)
In-Reply-To: <52D04291.2000901@redhat.com> (Pedro Alves's message of "Fri, 10	Jan 2014 18:57:21 +0000")

On Friday, January 10 2014, Pedro Alves wrote:

> Hmm, OK, I think I see.  I don't think the register block
> size in the header needs to be correct for this test -- tfile.c
> portability sounds like a red herring to me.  (I don't think 500
> is correct for x86/x86_64 either?)  There's no register block
> in the trace file anyway.  Only memory blocks.
>
> tfile knows to infer the PC from the tracepoint's address if
> the PC wasn't collected (tfile_fetch_registers) but,
> (guessing) the issue is that PC register in s390 is a
> pseudo-register.  tfile_fetch_registers guesses the PC from the
> tracepoint's address and stores it in the regcache, but
> when reading a (non-readonly) pseudo register from a regcache,
> we never use the stored value in the cache -- we always
> recompute it.  In fact, writing the pseudo PC to the regcache
> in tfile_fetch_registers with regcache_raw_supply seems reachable
> when regnum==-1, and I'm surprised this isn't triggering the assertion
> that makes sure the regnum being written to is a raw register
> (as the regcache's buffer only holds the raw registers -- see
> regcache_xmalloc_1 and regcache_raw_write).

Thanks for the investigation.

By debugging it a little more, I see that we don't write the pseudo PC
to the regcache.  You are probably talking about this loop:

  /* We get here if no register data has been found.  Mark registers
     as unavailable.  */
  for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
    regcache_raw_supply (regcache, regn, NULL);

The pseudo PC register number on s390x is 90, and "gdbarch_num_regs
(gdbarch)" returns exactly 90.

What happens is that when one requests the pseudo PC on s390x, it reads
S390_PSWM_REGNUM, which is 1:

  static enum register_status
  s390_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
                             int regnum, gdb_byte *buf)
  {
    struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
    int regsize = register_size (gdbarch, regnum);
    ULONGEST val;

    if (regnum == tdep->pc_regnum)
      {
        enum register_status status;

        status = regcache_raw_read_unsigned (regcache, S390_PSWA_REGNUM, &val);

Then, this check on tfile_fetch_registers evaluates to false:

  /* We can often usefully guess that the PC is going to be the same
     as the address of the tracepoint.  */
  pc_regno = gdbarch_pc_regnum (gdbarch);
  if (pc_regno >= 0 && (regno == -1 || regno == pc_regno))

Because regno == 1 and pc_regno == 90.  Maybe you knew all that, but I
thought it would be better to explicitly mention.

> When debugging a live traceframe, i.e., with gdbserver,
> it's gdbserver itself that does this same PC guessing.  And
> of course, that also only works when the PC isn't a pseudo
> register, as the target backend only ever sees raw registers
> accesses.
>
> Seems like this PC guessing should move out of
> target_fetch_registers to somewhere higher level...
>
> I.e., this is not a bug specific to s390, but to the
> tracing/unavailable machinery itself, for all targets
> whose PC is a pseudo register.

I see.  I haven't had the chance to test on other targets where PC is a
pseud register.

> It's fine with me to skip the test on targets with pseudo
> register PCs for now, though probably we should record this
> info somewhere, probably in the code, like in the patch below.

Nice, I like the comments, though your patch doesn't really change
anything for s390x because of what I explained above (regno == 1 and
pc_regno == 90), but I like to make things more explicit and your patch
does that.

I can push both our patches if you wish, btw.

>> There is also another error before, but it was already failing for
>> 7.6.2.
>
> Hard to say anything about it if you don't show it.  :-)

The same error:

&"tfind 0\n"^M
&"PC not available\n"^M
~"Found trace frame 0, tracepoint 1\n"^M
~"#-1 <unavailable> in ?? ()\n"^M
^done^M
(gdb) ^M
FAIL: gdb.trace/mi-traceframe-changed.exp: tfile: tfind 0 again

So I think the same explanation is valid.

> -------
> Subject: [PATCH] tfile: Don't infer the PC from the tracepoint if the PC is a
>  pseudo-register.
>
> This PC guessing can't work when the PC is a pseudo-register.
> Pseudo-register values don't end up stored in the regcache, they're
> always recomputed.  And, it's actually wrong to try to write a
> pseudo-register with regcache_raw_supply.  Skip it and add a comment.
>
> gdb/
> 2014-01-10  Pedro Alves  <palves@redhat.com>
>
> 	* tracepoint.c (tfile_fetch_registers): Don't infer the PC from
> 	the tracepoint if the PC is a pseudo-register.
> ---
>  gdb/tracepoint.c | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
> index 582c284..4b47282 100644
> --- a/gdb/tracepoint.c
> +++ b/gdb/tracepoint.c
> @@ -5060,7 +5060,17 @@ tfile_fetch_registers (struct target_ops *ops,
>    /* We can often usefully guess that the PC is going to be the same
>       as the address of the tracepoint.  */
>    pc_regno = gdbarch_pc_regnum (gdbarch);
> -  if (pc_regno >= 0 && (regno == -1 || regno == pc_regno))
> +
> +  /* XXX This guessing code below only works if the PC register isn't
> +     a pseudo-register.  The value of a pseudo-register isn't stored
> +     in the (non-readonly) regcache -- instead it's recomputed
> +     (probably from some other cached raw register) whenever the
> +     register is read.  This guesswork should probably move to some
> +     higher layer.  */
> +  if (pc_regno < 0 || pc_regno >= gdbarch_num_regs (gdbarch))
> +    return;
> +
> +  if (regno == -1 || regno == pc_regno)
>      {
>        struct tracepoint *tp = get_tracepoint (tracepoint_number);
>
> -- 
> 1.7.11.7

-- 
Sergio


  reply	other threads:[~2014-01-10 20:41 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-09 21:21 Sergio Durigan Junior
2014-01-10  1:23 ` Yao Qi
2014-01-10  2:17   ` Yao Qi
2014-01-10  3:58     ` Sergio Durigan Junior
2014-01-10 10:57       ` Pedro Alves
2014-01-10 17:31         ` Sergio Durigan Junior
2014-01-10 18:57           ` Pedro Alves
2014-01-10 20:41             ` Sergio Durigan Junior [this message]
2014-01-13 17:12               ` Pedro Alves
2014-01-15 20:37                 ` Sergio Durigan Junior
2014-01-16 18:20                   ` 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=m31u0fmuxv.fsf@redhat.com \
    --to=sergiodj@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=palves@redhat.com \
    --cc=yao@codesourcery.com \
    /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