LLDB Not Stepping into Multiple Inheritance Virtual Functions · Issue #43413 · llvm/llvm-project (original) (raw)

Bugzilla Link 44068
Version 9.0
OS Linux
Attachments Reproducer program.
CC @rdtscp,@JDevlieghere,@jimingham

Extended Description

Overview:

Using LLDB to debug polymorphic objects that have multiple inheritance will not step into virtual functions.

Steps to Reproduce:

$ clang++ -std=c++11 -g -O0 reproducer.cpp -o clang.out
$ lldb clang.out
(lldb) target create "clang.out"
Current executable set to 'clang.out' (x86_64).
(lldb) b 36                                                                                                                                                                       Breakpoint 1: where = clang.out`main + 103 at reproducer.cpp:36:16, address = 0x0000000000400d67
(lldb) r
Process 2764 launched: '/home/rdtscp/Documents/lldb_reproducer/clang.out' (x86_64)
Process 2764 stopped
* thread #​1, name = 'clang.out', stop reason = breakpoint 1.1
    frame #​0: 0x0000000000400d67 clang.out`main(argc=1, argv=0x00007fffffffe808) at reproducer.cpp:36:16
   33  	int main(int argc, char **argv) {
   34  	  using namespace Test;
   35  	  std::shared_ptr<Interface> object = std::shared_ptr<Concrete>(new Concrete());
-> 36  	  int output = object->vFun();
   37  	  std::cout << output << std::endl;
   38  	  return output;
   39  	}
(lldb) s
Process 2764 stopped
* thread #&#8203;1, name = 'clang.out', stop reason = step in
    frame #&#8203;0: 0x0000000000400d86 clang.out`main(argc=1, argv=0x00007fffffffe808) at reproducer.cpp:37:16
   34  	  using namespace Test;
   35  	  std::shared_ptr<Interface> object = std::shared_ptr<Concrete>(new Concrete());
   36  	  int output = object->vFun();
-> 37  	  std::cout << output << std::endl;
   38  	  return output;
   39  	}
(lldb)

Altering the Concrete class to be:

class Concrete : // public Base,
         public Interface {
public:
  virtual int vFun() override {
    volatile int x = rand();
    if (x > 0)
      return x;
    else
      return 0;
  }
};

Will result in:

$ clang++ -std=c++11 -g -O0 reproducer.cpp -o clang.out
$ lldb clang.out
(lldb) target create "clang.out"
Current executable set to 'clang.out' (x86_64).
(lldb) b 36
Breakpoint 1: where = clang.out`main + 104 at reproducer.cpp:36:16, address = 0x0000000000400cf8
(lldb) r
Process 2869 launched: '/home/rdtscp/Documents/lldb_reproducer/clang.out' (x86_64)
Process 2869 stopped
* thread #&#8203;1, name = 'clang.out', stop reason = breakpoint 1.1
    frame #&#8203;0: 0x0000000000400cf8 clang.out`main(argc=1, argv=0x00007fffffffe808) at reproducer.cpp:36:16
   33  	int main(int argc, char **argv) {
   34  	  using namespace Test;
   35  	  std::shared_ptr<Interface> object = std::shared_ptr<Concrete>(new Concrete());
-> 36  	  int output = object->vFun();
   37  	  std::cout << output << std::endl;
   38  	  return output;
   39  	}
(lldb) s
Process 2869 stopped
* thread #&#8203;1, name = 'clang.out', stop reason = step in
    frame #&#8203;0: 0x0000000000400fec clang.out`Test::Concrete::vFun(this=0x0000000000615c20) at reproducer.cpp:23:24
   20  			   public Interface {
   21  	  public:
   22  	    virtual int vFun() override {
-> 23  	      volatile int x = rand();
   24  	      if (x > 0)
   25  		return x;
   26  	      else
(lldb)

The above shows that making the Concrete class inherit from the Base class prevents us from stepping into vFun().

System Settings:

OS: Debian GNU/Linux 9.11 (stretch) x86_64
Model: VirtualBox 1.2
Kernel: 4.9.0-11-amd64
Uptime: 1 hour, 3 minutes
Packages: 1722
Shell: zsh 5.3.1
CPU: Intel i5-7360U (1) @ 2.3GHz
GPU: VMware SVGA II Adapter
Memory: 219MB / 996MB
$ clang++ --version
clang version 9.0.0-svn364966-1~exp1+0~20190702204433.1332~1.gbpb44072 (trunk)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ lldb --version
lldb version 9.0.0

Additional Information:
I tried using:

g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git

To see if my code was incorrect, but g++ and gdb were able to step into "vFun()" fun.