public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <aburgess@redhat.com>
Subject: [PATCHv2 5/6] gdb: ensure the cast in gdbarch_tdep is valid
Date: Fri, 10 Jun 2022 14:08:13 +0100	[thread overview]
Message-ID: <957b89f452fffb7c88b9bfae65625cddc93e6d00.1654866188.git.aburgess@redhat.com> (raw)
In-Reply-To: <cover.1654866187.git.aburgess@redhat.com>

This commit builds on the previous commit and modifies the
gdbarch_tdep function to ensure that the cast being performed is
valid.

To do this I make use of dynamic_cast to ensure that the generic
gdbarch_tdep pointer that we have is of the correct type.

The only problem with this approach is that, in order to use
dynamic_cast, we need RTTI information, which requires the class to
have a vtable, which currently, is not something the various tdep
classes have.

And so, in this commit, I add a virtual destructor to the gdbarch_tdep
class.

With this change I can now add an assert in the gdbarch_tdep function.

Obviously, this change comes at a cost, creation of the tdep classes
is now slightly more expensive (due to vtable initialisation),
however, this only happens when a new gdbarch is created, which is not
that frequent, so I don't see that as a huge concern.

Then, there is an increased cost each time the tdep is accessed.  This
is much more frequent, but I don't believe the cost is excessive (a
vtable pointer comparison), at least, no worse than many of our other
asserts.

If we consider the motivating example that was discussed in the
previous commit; build GDB for all targets on an x86-64 GNU/Linux
system, and then attempt to "run" a RISC-V binary using the native
x86-64 Linux target.  Previously this would trigger an assert while
accessing fields within a i386_gdbarch_tdep, like this:

  ../../src/gdb/i387-tdep.c:596: internal-error: i387_supply_fxsave: Assertion `tdep->st0_regnum >= I386_ST0_REGNUM' failed.

But with the changes from this commit in place, we now see an
assertion failure like this:

  ../../src/gdb/gdbarch.h:166: internal-error: gdbarch_tdep: Assertion `dynamic_cast<TDepType *> (tdep) != nullptr' failed.

On the face of it, this might not seem like much of an improvement,
but I think it is.

The previous assert was triggered by undefined behaviour.  There's no
guarantee that we would see an assertion at all, a different
combination of native target and binary format might not trigger an
assert (and just do the wrong thing), or might crash GDB completely.

In contrast, the new assert is based on defined behaviour, we'll
always assert if GDB goes wrong, and we assert early, at the point the
mistake is being made (casting the result of gdbarch_tdep to the wrong
type), rather than at some later point after the incorrect cast has
completed.

Obviously, when we consider the original example, trying to run a
binary of the wrong architecture on a native target, having GDB fail
with an assertion is not a real solution.  No user action should be
able to trigger an assertion failure.  In a later commit I will offer
a real solution to this architecture mismatch problem.
---
 gdb/gdbarch.h | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index b2c91db0c4f..a47aa8cc8fa 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -58,7 +58,13 @@ struct inferior;
 
 #include "regcache.h"
 
-struct gdbarch_tdep {};
+/* The base class for every architecture's tdep sub-class.  We include a
+   virtual destructor so that sub-classes will have RTTI information.  */
+
+struct gdbarch_tdep
+{
+  virtual ~gdbarch_tdep() = default;
+};
 
 /* The architecture associated with the inferior through the
    connection to the target.
@@ -156,8 +162,9 @@ template<typename TDepType>
 static inline TDepType *
 gdbarch_tdep (struct gdbarch *gdbarch)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep_1 (gdbarch);
-  return static_cast<TDepType *> (tdep);
+  TDepType *tdep = dynamic_cast<TDepType *> (gdbarch_tdep_1 (gdbarch));
+  gdb_assert (tdep != nullptr);
+  return tdep;
 }
 
 /* Mechanism for co-ordinating the selection of a specific
-- 
2.25.4


  parent reply	other threads:[~2022-06-10 13:08 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
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   ` Andrew Burgess [this message]
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=957b89f452fffb7c88b9bfae65625cddc93e6d00.1654866188.git.aburgess@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.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).