Spurious warnings about construction vtables.

Message ID CAEdUDV_Z7TyMb5h6U0WXF75bv0utSYqt8AMT=hr9WLv4V7VoKA@mail.gmail.com
State New, archived
Headers

Commit Message

Chris Dodd April 18, 2017, 4:20 a.m. UTC
  If you put a breakpoint in a C++ constructor, you often get a spurious
warning about the "construction vtable for CLASS".  If you have a
condition on the breakpoint (becuase you only want a specific call of
the ctor and want to skip many up that point), you get a huge spew of
these warnings.

Here's a small patch that avoids the warning when it not actually
anything wrong happening:

index 0090990..2bd8d9a 100644
               TYPE_SAFE_NAME (values_type));
@@ -336,7 +353,6 @@ gnuv3_rtti_type (struct value *value,
        warning (_("  found `%s' instead"), vtable_symbol_name);
       return NULL;
     }
-  class_name = vtable_symbol_name + 11;

   /* Strip off @plt and version suffixes.  */
   atsign = strchr (class_name, '@');

Chris Dodd
cdodd@acm.org
  

Comments

Pedro Alves April 18, 2017, 3:43 p.m. UTC | #1
Hi Chris,

Thanks for the patch.

On 04/18/2017 05:20 AM, Chris Dodd wrote:
> If you put a breakpoint in a C++ constructor, you often get a spurious
> warning about the "construction vtable for CLASS".  If you have a
> condition on the breakpoint (becuase you only want a specific call of
> the ctor and want to skip many up that point), you get a huge spew of
> these warnings.
> 
> Here's a small patch that avoids the warning when it not actually
> anything wrong happening:

Can you provide some small reproducer?
A snippet of a gdb session showing the warning in question
would help, I think.  Ideally, we'd convert it to a GDB
testsuite testcase.

Thanks,
Pedro Alves
  
Chris Dodd April 18, 2017, 4:54 p.m. UTC | #2
Here's a (fairly small) reproducer:

class A {
 public:
    A() { }
    virtual ~A() { }
};


class B : virtual public A {
    int id;
    static int counter;
    virtual void traceCreation() { }
 public:
    B() : id(++counter) { traceCreation(); }
};

int B::counter = 0;

class C : public B, virtual public A {
 public:
    C() : A() { }
};

int main() {
    C c;
}


Compile with -O0 (any optimization will dead-code elim the whole
program), and run with gdb.  Put a breakpoint in B::traceCreation, and
try to print *this or anything in it:

$ /usr/bin/gdb tdb
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from tdb...done.
(gdb) break B::traceCreation
Breakpoint 1 at 0x4006c2: file tdb.cpp, line 11.
(gdb) run
Starting program: /home/cdodd/test/tdb

Breakpoint 1, B::traceCreation (this=0x7fffffffddf0) at tdb.cpp:11
11    virtual void traceCreation() { }
(gdb) p id
warning: can't find linker symbol for virtual table for `B' value
warning:   found `construction vtable for B-in-C' instead
$1 = 1
(gdb) p *this
warning: can't find linker symbol for virtual table for `B' value
warning:   found `construction vtable for B-in-C' instead
$2 = warning: can't find linker symbol for virtual table for `B' value
warning:   found `construction vtable for B-in-C' instead
{<A> = {_vptr.A = 0x400940 <construction vtable for B-in-C+32>}, id = 1}
(gdb)


The warnings seem to be innocuous as the construction vtable is
expected to be present as we are looking at a partly constructed
object.  I'm not completely sure when construction vtables are created
and used by gcc -- it seems to require virtual inheritance somewhere
in the hierarchy.

                       -chris




On Tue, Apr 18, 2017 at 8:43 AM, Pedro Alves <palves@redhat.com> wrote:
> Hi Chris,
>
> Thanks for the patch.
>
> On 04/18/2017 05:20 AM, Chris Dodd wrote:
>> If you put a breakpoint in a C++ constructor, you often get a spurious
>> warning about the "construction vtable for CLASS".  If you have a
>> condition on the breakpoint (becuase you only want a specific call of
>> the ctor and want to skip many up that point), you get a huge spew of
>> these warnings.
>>
>> Here's a small patch that avoids the warning when it not actually
>> anything wrong happening:
>
> Can you provide some small reproducer?
> A snippet of a gdb session showing the warning in question
> would help, I think.  Ideally, we'd convert it to a GDB
> testsuite testcase.
>
> Thanks,
> Pedro Alves
>
  

Patch

--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -327,8 +327,25 @@  gnuv3_rtti_type (struct value *value,
      type_info object itself to get the class name.  But this way
      should work just as well, and doesn't read target memory.  */
   vtable_symbol_name = MSYMBOL_DEMANGLED_NAME (vtable_symbol);
-  if (vtable_symbol_name == NULL
-      || !startswith (vtable_symbol_name, "vtable for "))
+  if (vtable_symbol_name && startswith (vtable_symbol_name, "vtable for "))
+    class_name = vtable_symbol_name + 11;
+  else if (vtable_symbol_name && startswith (vtable_symbol_name,
"construction vtable for "))
+    {
+      const char *tail;
+
+      class_name = vtable_symbol_name + 24;
+      tail = strstr(class_name, "-in-");
+      if (tail != NULL)
+        {
+          char *copy;
+
+          copy = (char *) alloca (tail - class_name + 1);
+          memcpy (copy, class_name, tail - class_name);
+          copy[tail - class_name] = '\0';
+          class_name = copy;
+        }
+    }
+  else
     {
       warning (_("can't find linker symbol for virtual table for `%s' value"),