public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Luis Machado <luis.machado@linaro.org>
To: gdb-patches@sourceware.org
Subject: [PATCH] Fix printing of non pointer types when memory tagging is enabled
Date: Mon, 21 Jun 2021 22:37:19 -0300	[thread overview]
Message-ID: <20210622013719.3750766-1-luis.machado@linaro.org> (raw)
In-Reply-To: <20210518202004.3492036-1-luis.machado@linaro.org>

Updates on v2:

- Guard against thrown exceptions in the gdbarch_tagged_address_p hook as
  opposed to doing it at a higher scope.

--

When the architecture supports memory tagging, we handle pointer types
in a special way, so we can validate tags and show mismatches.

I noticed some errors while printing composite types, floats, references,
member functions and other things that implicitly get dereferenced by GDB to
show the contents rather than the pointer.

Vector registers:

(gdb) p $v0
Value can't be converted to integer.

Non-existent internal variables:

(gdb) p $foo
Value can't be converted to integer.

The same happens for complex types and printing struct/union types.

There are a couple problems. The first one is that we try to evaluate the
expression to print and eventually call value_as_address (...) before making
sure we have a suitable TYPE_CODE_PTR type. That may throw for some types. We
fix this by making sure we have a TYPE_CODE_PTR first, and then proceed to
check if we need to validate tags.

The second problem is that the evaluation process may naturally throw an
error.  One such case is when we have an optimized out variable. Thus we
guard the evaluation path with a try/catch.

If the evaluation throws, we want to resume the default expression printing
path instead of erroring out and printing nothing useful.

This isn't ideal, but GDB does some magic, internally, in order to provide an
improved user experience. This allows users to print the contents of some types
without having to use the dereference operator.

With the patch, printing works correctly again:

(gdb) p $v0
$1 = {d = {f = {2.0546950501119882e-81, 2.0546950501119882e-81}, u = {3399988123389603631, 3399988123389603631}, s = {
      3399988123389603631, 3399988123389603631}}, s = {f = {1.59329203e-10, 1.59329203e-10, 1.59329203e-10, 1.59329203e-10}, u = {
      791621423, 791621423, 791621423, 791621423}, s = {791621423, 791621423, 791621423, 791621423}}, h = {bf = {1.592e-10,
      1.592e-10, 1.592e-10, 1.592e-10, 1.592e-10, 1.592e-10, 1.592e-10, 1.592e-10}, f = {0.11224, 0.11224, 0.11224, 0.11224, 0.11224,
      0.11224, 0.11224, 0.11224}, u = {12079, 12079, 12079, 12079, 12079, 12079, 12079, 12079}, s = {12079, 12079, 12079, 12079,
      12079, 12079, 12079, 12079}}, b = {u = {47 <repeats 16 times>}, s = {47 <repeats 16 times>}}, q = {u = {
      62718710765820030520700417840365121327}, s = {62718710765820030520700417840365121327}}}
(gdb) p $foo
$2 = void
(gdb) p 2 + 2i
$3 = 2 + 2i

gdb/ChangeLog

YYYY-MM-DD  Luis Machado  <luis.machado@linaro.org>

	* gdbarch.sh: Updated documentation for gdbarch_tagged_address_p.
	* gdbarch.h: Regenerate.
	* printcmd.c (should_validate_memtags): Reorder comparisons and only
	validate tags for TYPE_CODE_PTR types.
	* aarch64-linux-tdep.c (aarch64_linux_tagged_address_p): Guard call
	to value_as_address with a try/catch block.
---
 gdb/aarch64-linux-tdep.c | 14 +++++++++++++-
 gdb/gdbarch.h            |  3 ++-
 gdb/gdbarch.sh           |  3 ++-
 gdb/printcmd.c           | 20 ++++++++++----------
 4 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index e9761ed2189..84ef616ee35 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -1559,7 +1559,19 @@ aarch64_linux_tagged_address_p (struct gdbarch *gdbarch, struct value *address)
 {
   gdb_assert (address != nullptr);
 
-  CORE_ADDR addr = value_as_address (address);
+  CORE_ADDR addr;
+
+  /* value_as_address may throw if, for example, the value is optimized
+     out.  Make sure we handle that gracefully.  */
+  try
+    {
+      addr = value_as_address (address);
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      /* Give up and assume the address is untagged.  */
+      return false;
+    }
 
   /* Remove the top byte for the memory range check.  */
   addr = address_significant (gdbarch, addr);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 7157e5596fd..4118e6c37ef 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -730,7 +730,8 @@ typedef std::string (gdbarch_memtag_to_string_ftype) (struct gdbarch *gdbarch, s
 extern std::string gdbarch_memtag_to_string (struct gdbarch *gdbarch, struct value *tag);
 extern void set_gdbarch_memtag_to_string (struct gdbarch *gdbarch, gdbarch_memtag_to_string_ftype *memtag_to_string);
 
-/* Return true if ADDRESS contains a tag and false otherwise. */
+/* Return true if ADDRESS contains a tag and false otherwise.  The
+   implementation of this hook should never throw an exception. */
 
 typedef bool (gdbarch_tagged_address_p_ftype) (struct gdbarch *gdbarch, struct value *address);
 extern bool gdbarch_tagged_address_p (struct gdbarch *gdbarch, struct value *address);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 43e51341f97..77088228d9a 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -608,7 +608,8 @@ v;int;significant_addr_bit;;;;;;0
 # Return a string representation of the memory tag TAG.
 m;std::string;memtag_to_string;struct value *tag;tag;;default_memtag_to_string;;0
 
-# Return true if ADDRESS contains a tag and false otherwise.
+# Return true if ADDRESS contains a tag and false otherwise.  The
+# implementation of this hook should never throw an exception.
 m;bool;tagged_address_p;struct value *address;address;;default_tagged_address_p;;0
 
 # Return true if the tag from ADDRESS matches the memory tag for that
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 22fa5c074d1..cd7d002c503 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1266,18 +1266,18 @@ print_value (value *val, const value_print_options &opts)
 static bool
 should_validate_memtags (struct value *value)
 {
-  if (target_supports_memory_tagging ()
-      && gdbarch_tagged_address_p (target_gdbarch (), value))
-    {
-      gdb_assert (value != nullptr && value_type (value) != nullptr);
+  if (value == nullptr)
+    return false;
 
-      enum type_code code = value_type (value)->code ();
+  enum type_code code = value_type (value)->code ();
+
+  /* Only validate memory tags if we have a pointer type and if the address
+     is within a tagged memory area.  */
+  if (code == TYPE_CODE_PTR
+      && target_supports_memory_tagging ()
+      && gdbarch_tagged_address_p (target_gdbarch (), value))
+	return true;
 
-      return (code == TYPE_CODE_PTR
-	      || code == TYPE_CODE_REF
-	      || code == TYPE_CODE_METHODPTR
-	      || code == TYPE_CODE_MEMBERPTR);
-    }
   return false;
 }
 
-- 
2.25.1


  parent reply	other threads:[~2021-06-22  1:37 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-18 20:20 Luis Machado
2021-05-27 11:31 ` [PING] " Luis Machado
2021-05-28 19:08 ` John Baldwin
2021-05-28 19:18   ` Luis Machado
2021-05-28 22:11     ` John Baldwin
2021-05-29  1:26 ` Simon Marchi
2021-05-29  6:26   ` Luis Machado
2021-06-20 16:19     ` Joel Brobecker
2021-06-21 13:28       ` Luis Machado
2021-06-22  1:37 ` Luis Machado [this message]
2021-07-01 13:50   ` [PING][PATCH] " Luis Machado
2021-07-01 19:52   ` [PATCH] " Pedro Alves
2021-07-02 12:47     ` Luis Machado
2021-07-02 13:19       ` Pedro Alves
2021-07-02 13:45         ` Luis Machado
2021-07-02 15:14           ` Pedro Alves
2021-07-05 14:32             ` Luis Machado
2021-07-05 23:06               ` Pedro Alves
2021-07-06 16:32                 ` Luis Machado
2021-07-07 10:49                   ` [PATCH v3] Fix printing of non-address " Pedro Alves
2021-07-17 18:53                     ` Joel Brobecker
2021-07-19  9:37                       ` Luis Machado
2021-07-19 18:50                     ` Luis Machado

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=20210622013719.3750766-1-luis.machado@linaro.org \
    --to=luis.machado@linaro.org \
    --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).