public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] c++/24367: Infinite recursion of typedef substitution
@ 2019-04-11 19:19 Keith Seitz
  2019-04-14 19:02 ` Kevin Buettner
  0 siblings, 1 reply; 3+ messages in thread
From: Keith Seitz @ 2019-04-11 19:19 UTC (permalink / raw)
  To: gdb-patches

This is asking for official review of a previous RFC:

https://sourceware.org/ml/gdb-patches/2019-03/msg00720.html

Revisions from original series:
- double check whitespace

-----

This bug finds another usage where we end up segfaulting while
normalizing user input.  inspect_type and replace_type recurse,
attempting to substitute the "real" symbol name for the typedef name.
However, since the both these names are the same, they keep calling
each other until the stack overflows.

A simple reproducer for it is given by

  typedef struct foo foo;
  int qux (foo *f) { return 0; }

  (gdb) b qux(foo*)
  Segmentation fault

inspect_type already contains some special handling to prevent a
similar situation from occurring with namespaces.  I wonder, however,
whether we need be so pedantic about the exact nature of the substitution.

This patch implements this rather more aggressive assumption that these
substitutions should be avoided whenever the replacement symbol's name is
exactly the same as the one we're trying to substitute.  [In the above
example, we're trying to substitute the tyepdef named "foo" with the symbol
named "foo" (a struct).]

gdb/ChangeLog:

	PR c++/24367
	* cp-support.c (inspect_type): Don't attempt substitutions
	of symbol with the same name.

gdb/testsuite/ChangeLog:

	PR c++/24367
	* gdb.cp/meth-typedefs.cc (incomplete_struct)
	(another_incomplete_struct, test_incomplete): New definitions.
	(main): Use new definitions.
	* gdb.cp/meth-typedefs.exp: Add new tests for `test_incomplete'
	functions.
---
 gdb/cp-support.c                       | 16 +++++++++++++---
 gdb/testsuite/gdb.cp/meth-typedefs.cc  | 13 +++++++++++++
 gdb/testsuite/gdb.cp/meth-typedefs.exp |  5 +++++
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index b79dd5c086..dc807b5292 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -191,10 +191,20 @@ inspect_type (struct demangle_parse_info *info,
 	  /* Get the real type of the typedef.  */
 	  type = check_typedef (otype);
 
-	  /* If the symbol is a namespace and its type name is no different
+	  /* If the symbol name is the same as the original type name,
+	     don't substitute.  That would cause infinite recursion in
+	     symbol lookups, as the typedef symbol is often the first
+	     found symbol in the symbol table.
+
+	     However, this can happen in a number of situations, such as:
+
+	     If the symbol is a namespace and its type name is no different
 	     than the name we looked up, this symbol is not a namespace
-	     alias and does not need to be substituted.  */
-	  if (TYPE_CODE (otype) == TYPE_CODE_NAMESPACE
+	     alias and does not need to be substituted.
+
+	     If the symbol is typedef and its type name is the same
+	     as the symbol's name, e.g., "typedef struct foo foo;".  */
+	  if (TYPE_NAME (type) != nullptr
 	      && strcmp (TYPE_NAME (type), name) == 0)
 	    return 0;
 
diff --git a/gdb/testsuite/gdb.cp/meth-typedefs.cc b/gdb/testsuite/gdb.cp/meth-typedefs.cc
index 0c4d095c7f..f65478e8c0 100644
--- a/gdb/testsuite/gdb.cp/meth-typedefs.cc
+++ b/gdb/testsuite/gdb.cp/meth-typedefs.cc
@@ -36,6 +36,13 @@ typedef void (*fptr2) (fptr1, my_other_type_2);
 typedef void (*fptr3) (fptr2, my_other_type);
 typedef void (*fptr4) (anon_enum a, anon_struct const& b, anon_union const*** c);
 
+// For c++/24367 testing
+typedef struct incomplete_struct incomplete_struct;
+typedef struct _incomplete_struct another_incomplete_struct;
+int test_incomplete (incomplete_struct *p) { return 0; } // test_incomplete(incomplete_struct*)
+int test_incomplete (another_incomplete_struct *p) { return 1; } // test_incomplete(another_incomplete_struct*)
+int test_incomplete (int *p) { return -1; } // test_incomplete(int*)
+
 namespace A
 {
   class foo
@@ -147,5 +154,11 @@ main (void)
 
   fptr4 f4;
 
+  // Tests for c++/24367
+  int *i = nullptr;
+  incomplete_struct *is = nullptr;
+  another_incomplete_struct *ais = nullptr;
+  int result = (test_incomplete (i) + test_incomplete (is)
+		+ test_incomplete (ais));
   return 0;
 }
diff --git a/gdb/testsuite/gdb.cp/meth-typedefs.exp b/gdb/testsuite/gdb.cp/meth-typedefs.exp
index b9c383bb25..76a8fc9780 100644
--- a/gdb/testsuite/gdb.cp/meth-typedefs.exp
+++ b/gdb/testsuite/gdb.cp/meth-typedefs.exp
@@ -137,6 +137,11 @@ foreach t $typedefs(_BAR_) {
     add methods "test" "$t&" {_BAR_&}
 }
 
+# Tests for c++/24367
+foreach t {int incomplete_struct another_incomplete_struct} {
+    add methods "test_incomplete" "${t}*" [string_to_regexp "${t}*"]
+}
+
 gdb_test_no_output "set listsize 1" ""
 
 # Finally, for each method in the list METHODS, check whether
-- 
2.20.1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] c++/24367: Infinite recursion of typedef substitution
  2019-04-11 19:19 [PATCH] c++/24367: Infinite recursion of typedef substitution Keith Seitz
@ 2019-04-14 19:02 ` Kevin Buettner
  2019-04-25 20:08   ` Keith Seitz
  0 siblings, 1 reply; 3+ messages in thread
From: Kevin Buettner @ 2019-04-14 19:02 UTC (permalink / raw)
  To: gdb-patches; +Cc: Keith Seitz

On Thu, 11 Apr 2019 12:19:21 -0700
Keith Seitz <keiths@redhat.com> wrote:
 
> gdb/ChangeLog:
> 
> 	PR c++/24367
> 	* cp-support.c (inspect_type): Don't attempt substitutions
> 	of symbol with the same name.
> 
> gdb/testsuite/ChangeLog:
> 
> 	PR c++/24367
> 	* gdb.cp/meth-typedefs.cc (incomplete_struct)
> 	(another_incomplete_struct, test_incomplete): New definitions.
> 	(main): Use new definitions.
> 	* gdb.cp/meth-typedefs.exp: Add new tests for `test_incomplete'
> 	functions.

Okay.

Kevin

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] c++/24367: Infinite recursion of typedef substitution
  2019-04-14 19:02 ` Kevin Buettner
@ 2019-04-25 20:08   ` Keith Seitz
  0 siblings, 0 replies; 3+ messages in thread
From: Keith Seitz @ 2019-04-25 20:08 UTC (permalink / raw)
  To: gdb-patches

On 4/14/19 12:02 PM, Kevin Buettner wrote:
> On Thu, 11 Apr 2019 12:19:21 -0700
> Keith Seitz <keiths@redhat.com> wrote:
>  
>> gdb/ChangeLog:
>>
>> 	PR c++/24367
>> 	* cp-support.c (inspect_type): Don't attempt substitutions
>> 	of symbol with the same name.
>>
>> gdb/testsuite/ChangeLog:
>>
>> 	PR c++/24367
>> 	* gdb.cp/meth-typedefs.cc (incomplete_struct)
>> 	(another_incomplete_struct, test_incomplete): New definitions.
>> 	(main): Use new definitions.
>> 	* gdb.cp/meth-typedefs.exp: Add new tests for `test_incomplete'
>> 	functions.
> 
> Okay.
> 

And pushed. Thank you for the review, Kevin.

Keith

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-04-25 20:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-11 19:19 [PATCH] c++/24367: Infinite recursion of typedef substitution Keith Seitz
2019-04-14 19:02 ` Kevin Buettner
2019-04-25 20:08   ` Keith Seitz

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).