[RFA] Recognize ggc_free'd memory in pretty-printers.

Message ID 20190607211125.29618-1-jason@redhat.com
State New
Headers show
Series
  • [RFA] Recognize ggc_free'd memory in pretty-printers.
Related show

Commit Message

Jason Merrill June 7, 2019, 9:11 p.m.
A tree node that has been poisoned by ggc_free is easily recognizable by the
TREE_CODE 0xa5a5; let's look for that rather than access some random memory off
the end of the array.

OK for trunk?

	* gdbhooks.py (TreePrinter.to_string): Recognize ggc_free'd memory.
	* tree.c (get_tree_code_name): Likewise.
	* print-tree.c (print_node): Only briefly print a node with an
	invalid code.
---
 gcc/print-tree.c | 16 +++++++++-------
 gcc/tree.c       |  6 +++++-
 gcc/gdbhooks.py  |  3 +++
 gcc/ChangeLog    |  7 +++++++
 4 files changed, 24 insertions(+), 8 deletions(-)


base-commit: 5f93e2e757ba1dfd0514b3661b6d737ea5492fa9
-- 
2.20.1

Comments

Richard Biener June 11, 2019, 12:34 p.m. | #1
On Fri, Jun 7, 2019 at 11:11 PM Jason Merrill <jason@redhat.com> wrote:
>

> A tree node that has been poisoned by ggc_free is easily recognizable by the

> TREE_CODE 0xa5a5; let's look for that rather than access some random memory off

> the end of the array.

>

> OK for trunk?


OK.

Richard.

>         * gdbhooks.py (TreePrinter.to_string): Recognize ggc_free'd memory.

>         * tree.c (get_tree_code_name): Likewise.

>         * print-tree.c (print_node): Only briefly print a node with an

>         invalid code.

> ---

>  gcc/print-tree.c | 16 +++++++++-------

>  gcc/tree.c       |  6 +++++-

>  gcc/gdbhooks.py  |  3 +++

>  gcc/ChangeLog    |  7 +++++++

>  4 files changed, 24 insertions(+), 8 deletions(-)

>

> diff --git a/gcc/print-tree.c b/gcc/print-tree.c

> index 81b66a1891b..f69a2c26679 100644

> --- a/gcc/print-tree.c

> +++ b/gcc/print-tree.c

> @@ -233,6 +233,15 @@ print_node (FILE *file, const char *prefix, tree node, int indent,

>      return;

>

>    code = TREE_CODE (node);

> +

> +  /* It is unsafe to look at any other fields of a node with ERROR_MARK or

> +     invalid code.  */

> +  if (code == ERROR_MARK || code >= MAX_TREE_CODES)

> +    {

> +      print_node_brief (file, prefix, node, indent);

> +      return;

> +    }

> +

>    tclass = TREE_CODE_CLASS (code);

>

>    /* Don't get too deep in nesting.  If the user wants to see deeper,

> @@ -251,13 +260,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent,

>        return;

>      }

>

> -  /* It is unsafe to look at any other fields of an ERROR_MARK node.  */

> -  if (code == ERROR_MARK)

> -    {

> -      print_node_brief (file, prefix, node, indent);

> -      return;

> -    }

> -

>    /* Allow this function to be called if the table is not there.  */

>    if (table)

>      {

> diff --git a/gcc/tree.c b/gcc/tree.c

> index 43ce44fcee4..4ba0135dfbb 100644

> --- a/gcc/tree.c

> +++ b/gcc/tree.c

> @@ -13444,7 +13444,11 @@ get_tree_code_name (enum tree_code code)

>    const char *invalid = "<invalid tree code>";

>

>    if (code >= MAX_TREE_CODES)

> -    return invalid;

> +    {

> +      if (code == 0xa5a5)

> +       return "ggc_freed";

> +      return invalid;

> +    }

>

>    return tree_code_name[code];

>  }

> diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py

> index 39f5c4772f9..e08208e1533 100644

> --- a/gcc/gdbhooks.py

> +++ b/gcc/gdbhooks.py

> @@ -222,6 +222,9 @@ class TreePrinter:

>          # extern const enum tree_code_class tree_code_type[];

>          # #define TREE_CODE_CLASS(CODE)        tree_code_type[(int) (CODE)]

>

> +        if val_TREE_CODE == 0xa5a5:

> +            return '<ggc_freed 0x%x>' % intptr(self.gdbval)

> +

>          val_tree_code_type = gdb.parse_and_eval('tree_code_type')

>          val_tclass = val_tree_code_type[val_TREE_CODE]

>

> diff --git a/gcc/ChangeLog b/gcc/ChangeLog

> index fa7a5adefb2..8a083599c99 100644

> --- a/gcc/ChangeLog

> +++ b/gcc/ChangeLog

> @@ -1,3 +1,10 @@

> +2019-06-07  Jason Merrill  <jason@redhat.com>

> +

> +       * gdbhooks.py (TreePrinter.to_string): Recognize ggc_free'd memory.

> +       * tree.c (get_tree_code_name): Likewise.

> +       * print-tree.c (print_node): Only briefly print a node with an

> +       invalid code.

> +

>  2019-06-07  Jakub Jelinek  <jakub@redhat.com>

>

>         * Makefile.in (genprogerr): Add condmd.

>

> base-commit: 5f93e2e757ba1dfd0514b3661b6d737ea5492fa9

> --

> 2.20.1

>

Patch

diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 81b66a1891b..f69a2c26679 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -233,6 +233,15 @@  print_node (FILE *file, const char *prefix, tree node, int indent,
     return;
 
   code = TREE_CODE (node);
+
+  /* It is unsafe to look at any other fields of a node with ERROR_MARK or
+     invalid code.  */
+  if (code == ERROR_MARK || code >= MAX_TREE_CODES)
+    {
+      print_node_brief (file, prefix, node, indent);
+      return;
+    }
+
   tclass = TREE_CODE_CLASS (code);
 
   /* Don't get too deep in nesting.  If the user wants to see deeper,
@@ -251,13 +260,6 @@  print_node (FILE *file, const char *prefix, tree node, int indent,
       return;
     }
 
-  /* It is unsafe to look at any other fields of an ERROR_MARK node.  */
-  if (code == ERROR_MARK)
-    {
-      print_node_brief (file, prefix, node, indent);
-      return;
-    }
-
   /* Allow this function to be called if the table is not there.  */
   if (table)
     {
diff --git a/gcc/tree.c b/gcc/tree.c
index 43ce44fcee4..4ba0135dfbb 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -13444,7 +13444,11 @@  get_tree_code_name (enum tree_code code)
   const char *invalid = "<invalid tree code>";
 
   if (code >= MAX_TREE_CODES)
-    return invalid;
+    {
+      if (code == 0xa5a5)
+	return "ggc_freed";
+      return invalid;
+    }
 
   return tree_code_name[code];
 }
diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
index 39f5c4772f9..e08208e1533 100644
--- a/gcc/gdbhooks.py
+++ b/gcc/gdbhooks.py
@@ -222,6 +222,9 @@  class TreePrinter:
         # extern const enum tree_code_class tree_code_type[];
         # #define TREE_CODE_CLASS(CODE)	tree_code_type[(int) (CODE)]
 
+        if val_TREE_CODE == 0xa5a5:
+            return '<ggc_freed 0x%x>' % intptr(self.gdbval)
+
         val_tree_code_type = gdb.parse_and_eval('tree_code_type')
         val_tclass = val_tree_code_type[val_TREE_CODE]
 
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa7a5adefb2..8a083599c99 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@ 
+2019-06-07  Jason Merrill  <jason@redhat.com>
+
+	* gdbhooks.py (TreePrinter.to_string): Recognize ggc_free'd memory.
+	* tree.c (get_tree_code_name): Likewise.
+	* print-tree.c (print_node): Only briefly print a node with an
+	invalid code.
+
 2019-06-07  Jakub Jelinek  <jakub@redhat.com>
 
 	* Makefile.in (genprogerr): Add condmd.