[lldb-dev] lldb showing wrong type structure for virtual pointer type

Dmitry Antipov via lldb-dev lldb-dev at lists.llvm.org
Wed Feb 28 02:19:16 PST 2018


On 02/28/2018 11:31 AM, jonas echterhoff via lldb-dev wrote:

> I'm using lldb-900.0.64.
             ^^^^^^^^^^^^^^
             ??????????????
Latest official release is 5.0.1; also there are 6.0.0 (at -rc3, the next release)
and 7.0.0 (a.k.a SVN trunk). What's the 'version' output of your LLDB prompt?

> Unfortunately, I have not yet succeeded in coming up with a small, independent repro case which shows this problem.

IIUC this is it:

struct A {
   int id0;
   A () { id0 = 111; }
   virtual int f (int x) { return x + 1; }
   int g (int x) { return x + 11; }
};

struct B: A {
   int id1;
   B () { id1 = 222; }
   virtual int f (int x) { return x + 2; }
   int g (int x) { return x + 12; }
};

namespace S {
   struct AS {
     int id0;
     AS () { id0 = 333; }
     virtual int f (int x) { return x + 3; }
     int g (int x) { return x + 13; }
   };
   struct B: AS {
     int id1;
     B () { id1 = 444; }
     virtual int f (int x) { return x + 4; }
     int g (int x) { return x + 14; }
   };
}

int main (int argc, char *argv[])
{
   B obj1;
   S::B obj2;
   return
     obj1.f (argc) +
     obj2.f (argc) +
     obj1.g (argc) +
     obj2.g (argc);
}

And in gdb, it is:

$ gdb -q t-class2
Reading symbols from t-class2...done.
(gdb) b S::B::f
Breakpoint 1 at 0x400775: file t-class2.cc, line 25.
(gdb) b S::B::g
Breakpoint 2 at 0x400789: file t-class2.cc, line 26.
(gdb) r
Starting program: /home/dantipov/tmp/t-class2

Breakpoint 1, S::B::f (this=0x7fffffffdb50, x=1) at t-class2.cc:25
25	    virtual int f (int x) { return x + 4; }
(gdb) bt
#0  S::B::f (this=0x7fffffffdb50, x=1) at t-class2.cc:25
#1  0x0000000000400643 in main (argc=1, argv=0x7fffffffdc68) at t-class2.cc:36
(gdb) p this
$1 = (S::B * const) 0x7fffffffdb50
(gdb) p *this
$2 = {<S::AS> = {_vptr.AS = 0x400840 <vtable for S::B+16>, id0 = 333}, id1 = 444}
(gdb) c
Continuing.

Breakpoint 2, S::B::g (this=0x7fffffffdb50, x=1) at t-class2.cc:26
26	    int g (int x) { return x + 14; }
(gdb) bt
#0  S::B::g (this=0x7fffffffdb50, x=1) at t-class2.cc:26
#1  0x0000000000400669 in main (argc=1, argv=0x7fffffffdc68) at t-class2.cc:38
(gdb) p this
$3 = (S::B * const) 0x7fffffffdb50
(gdb) p *this
$4 = {<S::AS> = {_vptr.AS = 0x400840 <vtable for S::B+16>, id0 = 333}, id1 = 444}

E.g. in calls to obj2.f () and obj2.g (), 'this' is 0x7fffffffdb50, and the object
itself is {333, 444}.

With lldb, it is:

$ /home/dantipov/.local/llvm-6.0.0/bin/lldb t-class2
(lldb) target create "t-class2"
Current executable set to 't-class2' (x86_64).
(lldb) breakpoint set -n S::B::f
Breakpoint 1: where = t-class2`S::B::f(int) at t-class2.cc:25, address = 0x000000000040076a
(lldb) breakpoint set -n S::B::g
Breakpoint 2: where = t-class2`S::B::g(int) + 11 at t-class2.cc:26, address = 0x0000000000400789
(lldb) run
Process 5180 launched: '/home/dantipov/tmp/t-class2' (x86_64)
Process 5180 stopped
* thread #1, name = 't-class2', stop reason = breakpoint 1.1
     frame #0: 0x000000000040076a t-class2`S::B::f(this=0x00007fffffffdb50, x=1) at t-class2.cc:25
    22  	  struct B: AS {
    23  	    int id1;
    24  	    B () { id1 = 444; }
-> 25  	    virtual int f (int x) { return x + 4; }
    26  	    int g (int x) { return x + 14; }
    27  	  };
    28  	}
(lldb) bt
* thread #1, name = 't-class2', stop reason = breakpoint 1.1
   * frame #0: 0x000000000040076a t-class2`S::B::f(this=0x00007fffffffdb50, x=1) at t-class2.cc:25
     frame #1: 0x0000000000400643 t-class2`main(argc=1, argv=0x00007fffffffdc58) at t-class2.cc:36
     frame #2: 0x00007ffff712000a libc.so.6`__libc_start_main(main=(t-class2`main at t-class2.cc:31), argc=1, argv=0x00007fffffffdc58, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, 
stack_end=0x00007fffffffdc48) at libc-start.c:308
     frame #3: 0x000000000040054a t-class2`_start + 42
(lldb) p this
(S::B *) $0 = 0x00007fffffffdb50
(lldb) p *this
(S::B) $1 = {
   S::AS = (id0 = 111)
   id1 = 222
}
(lldb) c
Process 5180 resuming
Process 5180 stopped
* thread #1, name = 't-class2', stop reason = breakpoint 2.1
     frame #0: 0x0000000000400789 t-class2`S::B::g(this=0x00007fffffffdb40, x=1) at t-class2.cc:26
    23  	    int id1;
    24  	    B () { id1 = 444; }
    25  	    virtual int f (int x) { return x + 4; }
-> 26  	    int g (int x) { return x + 14; }
    27  	  };
    28  	}
    29  	
(lldb) bt
* thread #1, name = 't-class2', stop reason = breakpoint 2.1
   * frame #0: 0x0000000000400789 t-class2`S::B::g(this=0x00007fffffffdb40, x=1) at t-class2.cc:26
     frame #1: 0x0000000000400669 t-class2`main(argc=1, argv=0x00007fffffffdc58) at t-class2.cc:38
     frame #2: 0x00007ffff712000a libc.so.6`__libc_start_main(main=(t-class2`main at t-class2.cc:31), argc=1, argv=0x00007fffffffdc58, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, 
stack_end=0x00007fffffffdc48) at libc-start.c:308
     frame #3: 0x000000000040054a t-class2`_start + 42
(lldb) p this
(S::B *) $2 = 0x00007fffffffdb40
(lldb) p *this
(S::B) $3 = {
   S::AS = (id0 = 333)
   id1 = 444
}

Here 'this' is different between calls to obj2.f () and obj2.g () (0x00007fffffffdb50 vs.
0x00007fffffffdb40), and objects are shown as different as well - {111, 222} vs. {333, 444}.

Dmitry

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------


More information about the lldb-dev mailing list