Discussion:
[Bug gdb/23101] New: gdb get insane when there are several c++ classes linked with the same name but different scope
apovalyaev at gmail dot com
2018-04-20 22:06:50 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=23101

Bug ID: 23101
Summary: gdb get insane when there are several c++ classes
linked with the same name but different scope
Product: gdb
Version: 7.11.1
Status: UNCONFIRMED
Severity: critical
Priority: P2
Component: gdb
Assignee: unassigned at sourceware dot org
Reporter: apovalyaev at gmail dot com
Target Milestone: ---

Three .cpp files are linked. Each of them has a TryDuplicate class declared.
So, all these three classes have the same name, but don't conflict each other.
Each of these class has a single virtual function, but the virtual function
names differ (let it be VirtualFunc, VirtualFunc2 and VirtualFunc3). Each of
.cpp files have a code calling an appropriate function inside. And this code is
executed for all these three files once a program run.

GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1 (x64)


First.cpp:

class TryDuplicate
{
public:
virtual void VirtualFunc() {}
};
...
// code which calls virtual function
TryDuplicate * c = new TryDuplicate();
c->VirtualFunc();


Second.cpp:

class TryDuplicate
{
public:
virtual void VirtualFunc2() {}
};
...
// code which calls virtual function
TryDuplicate * c = new TryDuplicate();
c->VirtualFunc2();

Third.cpp:

class TryDuplicate
{
public:
virtual void VirtualFunc3() {}
};
...
// code which calls virtual function
TryDuplicate * c = new TryDuplicate();
c->VirtualFunc3();


Once all these .cpp files are compiled and linked, issues with breakpoint
appears:
BUG1) When all these functions have breakpoint set up on it, only one can be
reached.
step1) (gdb) b TryDuplicate::VirtualFunc
step2) (gdb) b TryDuplicate::VirtualFunc2
step3) (gdb) b TryDuplicate::VirtualFunc3
step4) <run program>
step5) breakpoint on TryDuplicate::VirtualFunc is reached
step6) breakpoints on TryDuplicate::VirtualFunc2 and
TryDuplicate::VirtualFunc3 are not reached

NOTE: on another linkage it might be the case that only breakpoint on
TryDuplicate::VirtualFunc2 is reached and
TryDuplicate::VirtualFunc, TryDuplicate::VirtualFunc3 are not.
The essense is that only one of three breakpoints is reached.

BUG2) If you set up a breakpoint on line where TryDuplicate::VirtualFunc2 is
called, the breakpoint can be reached but after "Step in" gdb command
you will be inside TryDuplicate::VirtualFunc (not VirtualFunc2)

NOTE: the same logic as writte in NOTE for BUG1
--
You are receiving this mail because:
You are on the CC list for the bug.
apovalyaev at gmail dot com
2018-04-20 22:07:13 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=23101

Aleksandr Povaliaev <apovalyaev at gmail dot com> changed:

What |Removed |Added
----------------------------------------------------------------------------
CC| |apovalyaev at gmail dot com
--
You are receiving this mail because:
You are on the CC list for the bug.
palves at redhat dot com
2018-04-23 10:23:55 UTC
Permalink
https://sourceware.org/bugzilla/show_bug.cgi?id=23101

Pedro Alves <palves at redhat dot com> changed:

What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
CC| |palves at redhat dot com
Resolution|--- |INVALID

--- Comment #1 from Pedro Alves <palves at redhat dot com> ---
(In reply to Aleksandr Povaliaev from comment #0)
Post by apovalyaev at gmail dot com
Three .cpp files are linked. Each of them has a TryDuplicate class declared.
So, all these three classes have the same name, but don't conflict each other.
That's incorrect; it's a violation of the One Definition Rule (ODR).

https://en.wikipedia.org/wiki/One_Definition_Rule
Post by apovalyaev at gmail dot com
Once all these .cpp files are compiled and linked, issues with breakpoint
BUG1) When all these functions have breakpoint set up on it, only one can be
reached.
step1) (gdb) b TryDuplicate::VirtualFunc
step2) (gdb) b TryDuplicate::VirtualFunc2
step3) (gdb) b TryDuplicate::VirtualFunc3
step4) <run program>
step5) breakpoint on TryDuplicate::VirtualFunc is reached
step6) breakpoints on TryDuplicate::VirtualFunc2 and
TryDuplicate::VirtualFunc3 are not reached
NOTE: on another linkage it might be the case that only breakpoint on
TryDuplicate::VirtualFunc2 is reached and
TryDuplicate::VirtualFunc, TryDuplicate::VirtualFunc3 are not.
The essense is that only one of three breakpoints is reached.
BUG2) If you set up a breakpoint on line where TryDuplicate::VirtualFunc2 is
called, the breakpoint can be reached but after "Step in" gdb command
you will be inside TryDuplicate::VirtualFunc (not VirtualFunc2)
NOTE: the same logic as writte in NOTE for BUG1
Most probably if you add some printf to the different
VirtualFunc/VirtualFunc2/VirtualFunc3 functions, you'll see the same same print
multiple times.

What's very likely happening is that the compiler/linker assumed all the
TryDuplicate classes are the same and merged all the vtables into one.

See e.g.,:
http://hubicka.blogspot.pt/2014/09/devirtualization-in-c-part-6-enforcing.html
(Particularly "Detecting virtual table ODR violations").

Compiling and linking with with "-flto -Wodr" helps find some problems like
these.

There's nothing GDB can do here.
--
You are receiving this mail because:
You are on the CC list for the bug.
Loading...