diff mbox

[PR,c++/18141,c++/18417] std::iostream is a typedef

Message ID 089e014946b284ccdb0516256040@google.com
State New
Headers show

Commit Message

Doug Evans May 15, 2015, 9:17 p.m. UTC
Hi.

This patch fixes 18141, 18417.

gnuv3_rtti_type/cp_lookup_rtti_type make the assumption that the name being
lookup up is a class (after all, gnuv3_rtti_type calls check_typedef).
This assumption breaks for std::iostream.

 From 18417:

"p std::cerr" can give the following:

warning: RTTI symbol for class 'std::iostream' has bad type

this is because the minsym for the vtable is a typedef.

gnuv3_rtti_type calls check_typedef on the value's type,
and then does a minsym lookup by pc for the vtable
which returns "_ZTVSo" which demangles as
"vtable for std::ostream", and "std::iostream" is a typedef.

For 18141, this is another classic case of .gdb_index saying the
symbol is present but upon expansion symbol lookup doesn't find it.
So we end up expanding one (or more) CUs in potentially 1000s of
shared libraries.  The cost is 10s of GB of memory and an untold
number of minutes (I gave up waiting for it to finish).

My gmonster perf testcase will have a test to cover this.

2015-05-15  Doug Evans  <dje@google.com>

	PR c++/18141, c++/18417.
	* cp-support.c (cp_lookup_rtti_type): Handle the case of NAME being
	a typedef.

	testsuite/
	* gdb.cp/iostream.cc: New file.
	* gdb.cp/iostream.exp: New file.

Comments

Doug Evans May 27, 2015, 12:24 a.m. UTC | #1
On Fri, May 15, 2015 at 2:17 PM, Doug Evans <dje@google.com> wrote:
> Hi.
>
> This patch fixes 18141, 18417.
>
> gnuv3_rtti_type/cp_lookup_rtti_type make the assumption that the name being
> lookup up is a class (after all, gnuv3_rtti_type calls check_typedef).
> This assumption breaks for std::iostream.
>
> From 18417:
>
> "p std::cerr" can give the following:
>
> warning: RTTI symbol for class 'std::iostream' has bad type
>
> this is because the minsym for the vtable is a typedef.
>
> gnuv3_rtti_type calls check_typedef on the value's type,
> and then does a minsym lookup by pc for the vtable
> which returns "_ZTVSo" which demangles as
> "vtable for std::ostream", and "std::iostream" is a typedef.
>
> For 18141, this is another classic case of .gdb_index saying the
> symbol is present but upon expansion symbol lookup doesn't find it.
> So we end up expanding one (or more) CUs in potentially 1000s of
> shared libraries.  The cost is 10s of GB of memory and an untold
> number of minutes (I gave up waiting for it to finish).
>
> My gmonster perf testcase will have a test to cover this.
>
> 2015-05-15  Doug Evans  <dje@google.com>
>
>         PR c++/18141, c++/18417.
>         * cp-support.c (cp_lookup_rtti_type): Handle the case of NAME being
>         a typedef.
>
>         testsuite/
>         * gdb.cp/iostream.cc: New file.
>         * gdb.cp/iostream.exp: New file.

Committed.
diff mbox

Patch

diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 4bbee94..3db9751 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -1453,7 +1453,9 @@  cp_lookup_rtti_type (const char *name, struct block  
*block)
    struct symbol * rtti_sym;
    struct type * rtti_type;

-  rtti_sym = lookup_symbol (name, block, STRUCT_DOMAIN, NULL);
+  /* Use VAR_DOMAIN here as NAME may be a typedef.  PR 18141, 18417.
+     Classes "live" in both STRUCT_DOMAIN and VAR_DOMAIN.  */
+  rtti_sym = lookup_symbol (name, block, VAR_DOMAIN, NULL);

    if (rtti_sym == NULL)
      {
@@ -1467,7 +1469,7 @@  cp_lookup_rtti_type (const char *name, struct block  
*block)
        return NULL;
      }

-  rtti_type = SYMBOL_TYPE (rtti_sym);
+  rtti_type = check_typedef (SYMBOL_TYPE (rtti_sym));

    switch (TYPE_CODE (rtti_type))
      {
diff --git a/gdb/testsuite/gdb.cp/iostream.cc  
b/gdb/testsuite/gdb.cp/iostream.cc
new file mode 100644
index 0000000..2e78599
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/iostream.cc
@@ -0,0 +1,27 @@ 
+/* Code to go along with tests in rtti.exp.
+
+   Copyright 2015 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.   
*/
+
+#include <iostream>
+
+int
+main ()
+{
+  std::cerr << "cerr\n";
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.cp/iostream.exp  
b/gdb/testsuite/gdb.cp/iostream.exp
new file mode 100644
index 0000000..3b864a8
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/iostream.exp
@@ -0,0 +1,44 @@ 
+# Copyright 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.
+# It tests various aspects of iostream that have caused problems for gdb.
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+    return -1
+}
+
+if ![runto_main] {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+# PR 18417
+# std::iostream is problematic because the minimal symbol for its vtable is
+# "_ZTVSo" which demangles as "vtable for std::ostream" and std::iostream
+# a typedef.
+set test "p std::cerr"
+gdb_test_multiple $test $test {
+    -re "warning: RTTI symbol for class '.*' has bad type.*$gdb_prompt $" {
+	fail $test
+    }
+    -re ".*$gdb_prompt $" {
+	pass $test
+    }
+}