public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: Luis Machado <luis.machado@arm.com>, gdb-patches@sourceware.org
Subject: Re: [PATCHv2 3/6] gdb/arm: avoid undefined behaviour in arm_frame_is_thumb
Date: Fri, 10 Jun 2022 16:49:59 +0100	[thread overview]
Message-ID: <87zgikecwo.fsf@redhat.com> (raw)
In-Reply-To: <fa2d7713-c6f4-a191-c8ac-52b10eae3940@arm.com>

Luis Machado via Gdb-patches <gdb-patches@sourceware.org> writes:

> On 6/10/22 14:08, Andrew Burgess via Gdb-patches wrote:
>> This commit fixes real undefined behaviour in GDB which I spotted when
>> working on a later patch in this series.  The later patch in this
>> series detects when the result of gdbarch_tdep() is cast to the wrong
>> type.
>> 
>> The issue is revealed by the gdb.multi/multi-arch.exp test.
>> 
>> In this test we setup two inferiors, an AArch64 process, and an ARM
>> process, then at one point we have inferior 1 selected (the AArch64
>> inferior), and we place a breakpoint on a symbol present in the other
>> inferior (the ARM inferior).
>> 
>> During the process of creating the breakpoint we call arm_pc_is_thumb,
>> the GDBARCH passed into this function is correct, that is, represents
>> the ARM process.
>> 
>> For whatever reason we are unable to figure out if the address in
>> question is thumb or not throughout most of arm_pc_is_thumb, and so we
>> get to this code at the end of the function:
>> 
>>    /* If we couldn't find any symbol, but we're talking to a running
>>       target, then trust the current value of $cpsr.  This lets
>>       "display/i $pc" always show the correct mode (though if there is
>>       a symbol table we will not reach here, so it still may not be
>>       displayed in the mode it will be executed).  */
>>    if (target_has_registers ())
>>      return arm_frame_is_thumb (get_current_frame ());
>> 
>> Which I guess is a last attempt to figure out the thumb status of an
>> address.  However, remember, we the AArch64 inferior is current at
>> this time, so the current frame is an AArch64 frame.
>
> If we're trying to insert a breakpoint into a 32-bit inferior,
> we should really have the 32-bit arm gdbarch at hand, not the AArch64
> gdbarch.

We do.

>
> I think the bug is somewhere else, in whoever passed the current inferior's gdbarch
> as opposed to the gdbarch of the inferior that contains the symbol
> we've found.

We do pass in the gdbarch of the inferior containing the breakpoint location.

If I change the condition to an assert, then run
gdb.multi/multi-arch.exp and catch the assertion, the stack looks like
this:

  #0  internal_error (file=0x55834840c8 "../../src/gdb/arm-tdep.c", line=551, 
      fmt=0x5583483d70 "%s: Assertion `%s' failed.") at ../../src/gdbsupport/errors.cc:51
  #1  0x0000005582b0e6a4 in arm_frame_is_thumb (frame=0x55c0849a00) at ../../src/gdb/arm-tdep.c:551
  #2  0x0000005582b0eb70 in arm_pc_is_thumb (gdbarch=0x55c0937080, memaddr=4195692) at ../../src/gdb/arm-tdep.c:687
  #3  0x0000005582b17e70 in arm_adjust_breakpoint_address (gdbarch=0x55c0937080, bpaddr=4195692)
      at ../../src/gdb/arm-tdep.c:4925
  #4  0x0000005582af0a60 in gdbarch_adjust_breakpoint_address (gdbarch=0x55c0937080, bpaddr=4195692)
      at ../../src/gdb/gdbarch.c:2840
  #5  0x0000005582b73c90 in adjust_breakpoint_address (gdbarch=0x55c0937080, bpaddr=4195692, bptype=bp_breakpoint)
      at ../../src/gdb/breakpoint.c:7147
  #6  0x0000005582b76854 in code_breakpoint::add_location (this=0x55c088e340, sal=...)
      at ../../src/gdb/breakpoint.c:8100
  #7  0x0000005582b773b8 in code_breakpoint::code_breakpoint (this=0x55c088e340, gdbarch_=0x55c089c050, 
      type_=bp_breakpoint, sals=..., location_=..., filter_=std::unique_ptr<char> = {...}, 
      cond_string_=std::unique_ptr<char> = {...}, extra_string_=std::unique_ptr<char> = {...}, 
      disposition_=disp_donttouch, thread_=-1, task_=0, ignore_count_=0, from_tty=1, enabled_=1, flags=0, 
      display_canonical_=0) at ../../src/gdb/breakpoint.c:8329
  #8  0x0000005582b90c00 in ordinary_breakpoint::code_breakpoint (this=0x55c088e340) at ../../src/gdb/breakpoint.c:266
  #9  0x0000005582b88758 in new_breakpoint_from_type<gdb::array_view<symtab_and_line const>&, std::unique_ptr<event_location, event_location_deleter>, std::unique_ptr<char, gdb::xfree_deleter<char> >, std::unique_ptr<char, gdb::xfree_deleter<char> >, std::unique_ptr<char, gdb::xfree_deleter<char> >, bpdisp&, int&, int&, int&, int&, int&, unsigned int&, int&> (gdbarch=0x55c089c050, type=bp_breakpoint) at ../../src/gdb/breakpoint.c:1303
  #10 0x0000005582b77710 in create_breakpoint_sal (gdbarch=0x55c089c050, sals=..., location=..., 
      filter=std::unique_ptr<char> = {...}, cond_string=std::unique_ptr<char> = {...}, 
      extra_string=std::unique_ptr<char> = {...}, type=bp_breakpoint, disposition=disp_donttouch, thread=-1, task=0, 
      ignore_count=0, from_tty=1, enabled=1, internal=0, flags=0, display_canonical=0)
      at ../../src/gdb/breakpoint.c:8395
  #11 0x0000005582b779d8 in create_breakpoints_sal (gdbarch=0x55c089c050, canonical=0x7fd8d196c0, 
      cond_string=std::unique_ptr<char> = {...}, extra_string=std::unique_ptr<char> = {...}, type=bp_breakpoint, 
      disposition=disp_donttouch, thread=-1, task=0, ignore_count=0, from_tty=1, enabled=1, internal=0, flags=0)
      at ../../src/gdb/breakpoint.c:8438
  #12 0x0000005582b78d94 in create_breakpoint (gdbarch=0x55c089c050, location=0x55c0979750, cond_string=0x0, thread=-1, 
      extra_string=0x0, force_condition=false, parse_extra=1, tempflag=0, type_wanted=bp_breakpoint, ignore_count=0, 
      pending_break_support=AUTO_BOOLEAN_AUTO, ops=0x558389c650 <code_breakpoint_ops>, from_tty=1, enabled=1, 
      internal=0, flags=0) at ../../src/gdb/breakpoint.c:8923
  #13 0x0000005582b792d8 in break_command_1 (arg=0x55c0732fc2 "", flag=0, from_tty=1) at ../../src/gdb/breakpoint.c:8994
  #14 0x0000005582b79578 in break_command (arg=0x55c0732fb6 "hangout_loop", from_tty=1)
      at ../../src/gdb/breakpoint.c:9065

In frame #6 we select a gdbarch based on the location of the breakpoint,
its at this point that we select the bfd_arch_arm gdbarch.

For frames #5, #4, #3, and #2 we are passing in a bfd_arch_arm gdbarch,
which is correct, and what you are asking for.

The problem is that in frame #2 we fail to find any of the special hints
that indicate if the code is thumb or not.  Now, _maybe_ you could argue
that one of the conditions in arm_pc_is_thumb should trigger, but, for
me, the very fact that there is a "catch all" case at the end of the
function means we have to be open to the possibility that non of the
special symbols, or bottom bit of the address set cases might trigger.

And so, we get to this code in arm_pc_is_thumb:

  if (target_has_registers ())
    return arm_frame_is_thumb (get_current_frame ());

At this point GDBARCH _is_ a bfd_arch_arm architecture.

But, the current frame is bfd_arch_aarch64.

And so, we enter frame #1, arm_frame_is_thumb, passing in a frame that
is not bfd_arch_arm.

So, are you are suggesting we should switch frames as part of the
breakpoint setting process?  Because I'm not sure how you'd pick even a
suitable inferior, multiple ARM inferiors might share a single program
space, so we could have a single gdbarch, but multiple inferiors, each
with multiple threads, and each thread with multiple frames...

I guess we could push the architecture check out of arm_frame_is_thumb
back to arm_pc_is_thumb, and only call arm_frame_is_thumb for the case
where the architecture is ARM... that doesn't make sense to me, but
maybe, I guess...

Anyway, let me know if the above makes any more sense.  If it does I can
update the commit message.

Thanks,
Andrew


  reply	other threads:[~2022-06-10 15:50 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-31 14:30 [PATCH 0/5] Handle trying to use a native target with the wrong binary Andrew Burgess
2022-05-31 14:30 ` [PATCH 1/5] gdb/arm: move fetch of arm_gdbarch_tdep to a more inner scope Andrew Burgess
2022-06-01  7:58   ` Luis Machado
2022-05-31 14:30 ` [PATCH 2/5] gdb/mips: rewrite show_mask_address Andrew Burgess
2022-05-31 14:30 ` [PATCH 3/5] gdb: move the type cast into gdbarch_tdep Andrew Burgess
2022-06-01  8:01   ` Luis Machado
2022-05-31 14:30 ` [PATCH 4/5] gdb: ensure the cast in gdbarch_tdep is valid Andrew Burgess
2022-05-31 16:04   ` John Baldwin
2022-05-31 17:22     ` Andrew Burgess
2022-05-31 14:30 ` [PATCH 5/5] gdb: native target invalid architecture detection Andrew Burgess
2022-05-31 16:08   ` John Baldwin
2022-05-31 16:51     ` Andrew Burgess
2022-06-01  8:25       ` Luis Machado
2022-06-01 21:06         ` John Baldwin
2022-06-01 21:21           ` Christophe Lyon
2022-06-02 14:56             ` John Baldwin
2022-06-06 14:38         ` Andrew Burgess
2022-06-06 17:48           ` Andrew Burgess
2022-06-07 11:03             ` Luis Machado
2022-06-07 18:42               ` Pedro Alves
2022-06-07 20:15                 ` Pedro Alves
2022-06-08  8:18                   ` Luis Machado
2022-06-08 10:17                     ` Pedro Alves
2022-06-08  7:54                 ` Luis Machado
2022-06-08 10:12                   ` Pedro Alves
2022-06-08 11:20                     ` [PATCH v2] aarch64: Add fallback if ARM_CC_FOR_TARGET not set (was: Re: [PATCH 5/5] gdb: native target invalid architecture detection) Pedro Alves
2022-06-08 12:50                       ` Luis Machado
2022-06-08 13:23                         ` Pedro Alves
2022-06-08 13:38                       ` Andrew Burgess
2022-06-08 19:01                       ` John Baldwin
2022-06-08 21:48                         ` Pedro Alves
2022-06-09 16:31                           ` John Baldwin
2022-06-10 13:08 ` [PATCHv2 0/6] Handle trying to use a native target with the wrong binary Andrew Burgess
2022-06-10 13:08   ` [PATCHv2 1/6] gdb/arm: move fetch of arm_gdbarch_tdep to a more inner scope Andrew Burgess
2022-06-10 13:08   ` [PATCHv2 2/6] gdb/mips: rewrite show_mask_address Andrew Burgess
2022-06-10 13:08   ` [PATCHv2 3/6] gdb/arm: avoid undefined behaviour in arm_frame_is_thumb Andrew Burgess
2022-06-10 15:21     ` Luis Machado
2022-06-10 15:49       ` Andrew Burgess [this message]
2022-06-10 16:29         ` Luis Machado
2022-06-10 13:08   ` [PATCHv2 4/6] gdb: move the type cast into gdbarch_tdep Andrew Burgess
2022-06-10 16:35     ` Luis Machado
2022-06-10 13:08   ` [PATCHv2 5/6] gdb: ensure the cast in gdbarch_tdep is valid Andrew Burgess
2022-06-10 13:08   ` [PATCHv2 6/6] gdb: native target invalid architecture detection Andrew Burgess
2022-06-10 16:20     ` John Baldwin
2022-06-10 16:31     ` Luis Machado
2022-06-13 16:15   ` [PATCHv3 0/6] Handle trying to use a native target with the wrong binary Andrew Burgess
2022-06-13 16:15     ` [PATCHv3 1/6] gdb/arm: move fetch of arm_gdbarch_tdep to a more inner scope Andrew Burgess
2022-06-13 16:15     ` [PATCHv3 2/6] gdb/mips: rewrite show_mask_address Andrew Burgess
2022-06-13 16:15     ` [PATCHv3 3/6] gdb: select suitable thread for gdbarch_adjust_breakpoint_address Andrew Burgess
2022-06-14  9:45       ` Luis Machado
2022-06-14 14:05         ` Andrew Burgess
2022-06-24 16:58       ` Pedro Alves
2022-06-13 16:15     ` [PATCHv3 4/6] gdb: move the type cast into gdbarch_tdep Andrew Burgess
2022-06-13 16:15     ` [PATCHv3 5/6] gdb: ensure the cast in gdbarch_tdep is valid Andrew Burgess
2022-06-24 18:15       ` Pedro Alves
2022-06-13 16:15     ` [PATCHv3 6/6] gdb: native target invalid architecture detection Andrew Burgess
2022-06-24 19:23       ` Pedro Alves
2022-06-27 16:27         ` Andrew Burgess
2022-06-27 21:38           ` Pedro Alves
2022-06-28 10:37             ` Andrew Burgess
2022-06-28 12:42               ` [PATCH v2] gdb+gdbserver/Linux: avoid reading registers while going through shell (was: Re: [PATCHv3 6/6] gdb: native target invalid architecture detection) Pedro Alves
2022-06-28 14:21                 ` Andrew Burgess
2022-06-29 15:17                 ` Simon Marchi
2022-06-29 16:22                   ` [PATCH] Fix GDBserver regression due to change to avoid reading shell registers Pedro Alves
2022-06-29 16:38                     ` Simon Marchi
2022-06-30  9:33             ` [PATCHv3 6/6] gdb: native target invalid architecture detection Andrew Burgess
2022-06-30 11:44               ` Pedro Alves
2022-07-11 10:47                 ` Andrew Burgess
2022-06-24 10:15     ` [PATCHv3 0/6] Handle trying to use a native target with the wrong binary Andrew Burgess
2022-06-28 14:28     ` [PATCHv4 0/6] Detect invalid casts of gdbarch_tdep structures Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 1/6] gdb/arm: move fetch of arm_gdbarch_tdep to a more inner scope Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 2/6] gdb/mips: rewrite show_mask_address Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 3/6] gdb: select suitable thread for gdbarch_adjust_breakpoint_address Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 4/6] gdb: move the type cast into gdbarch_tdep Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 5/6] gdbsupport: add checked_static_cast Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 6/6] gdb: ensure the cast in gdbarch_tdep is valid Andrew Burgess
2022-07-11 10:46       ` [PATCHv4 0/6] Detect invalid casts of gdbarch_tdep structures Andrew Burgess
2022-07-21 18:21         ` Andrew Burgess
2022-07-22  0:50           ` Luis Machado
2022-07-23  0:02             ` [PATCH] Rename gdbarch_tdep template function to gdbarch_tdep_cast for g++ 4.8 Mark Wielaard
2022-07-25 11:19               ` Andrew Burgess
2022-07-25 11:27                 ` Mark Wielaard
2022-07-26 11:05                   ` Andrew Burgess

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=87zgikecwo.fsf@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=luis.machado@arm.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).