Solved Can't find linker symbol for virtual table
-
Hello,
I have a very simple class hierarchy in my example, which generates can't find linker symbol for virtual table warning in gdb. I do not understand why.
Main:#include <QApplication> #include "classa.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); ClassA *pA = new ClassA(); return a.exec(); }
ClassA
#ifndef CLASSA_H #define CLASSA_H #include <QObject> #include "classb.h" #include "classc.h" #include "classd.h" #include "classe.h" #include "classf.h" class ClassA : public QObject { Q_OBJECT public: explicit ClassA(QObject *parent = nullptr); private: ClassB *pB; ClassC *pC; ClassD *pD; ClassE *pE; ClassF *pF; signals: public slots: }; #endif // CLASSA_H
ClassB, C, D, E and F looks exactly the same so only B below
#ifndef CLASSB_H #define CLASSB_H #include <QObject> class ClassB : public QObject { Q_OBJECT public: explicit ClassB(QObject *parent = nullptr); signals: public slots: }; #endif // CLASSB_H
and class A cpp
#include "classa.h" ClassA::ClassA(QObject *parent) : QObject(parent) { pB = new ClassB(); pC = new ClassC(); pD = new ClassD(); pE = new ClassE(); pF = new ClassF(); }
Now when I set a breakpoint in line 5 in ClassA.cpp press 11 (step into) I get warning from gdb. The same from other classes.
Can enybody give me a hint where is the problem?
Best regards -
Hi
If everything seems ok, and you get virtual table warnings, then its time
to complete delete all of the build folder and rebuild all. -
Is this the code that really generates the error or some stripped down version? You can get this if you overrun the buffer and overwrite the virtual table, or you have some sort of mismatch between library/executable when linking.
-
Hi,
This is exactly this code. Cleaning, deleting build directory doesn't help.
@kshegunov do you know how to check if there is some mismatch? -
@wojj said in Can't find linker symbol for virtual table:
@kshegunov do you know how to check if there is some mismatch?
Let's start by clarifying if this whole code is in one binary (i.e. one executable) or is split over more than one binary (i.e. one executable and one library)?
-
There is one executable file.
-
Then that point is moot. Try initializing the members with an initializer list, the message may be a red herring after all. That is, something like this:
ClassA::ClassA(QObject * parent) : QObject(parent), pB(new ClassB()), pC(new ClassC()), pD(new ClassD()), pE(new ClassE()), pF(new ClassF()) { }
-
@kshegunov Didn't help. Still the same warning.
-
Then the only other thing I can think of is the
vtable
not being emitted due to a missing definition of a non-inline function (constructor) in one of the classes. Aside from that I have no clue. -
@kshegunov I ran ldd for this application and it looks there is missing one libraby
linux-vdso.so.1 => (0x00007ffeae25a000) -
@wojj can you upload code somewhere so we can try to reproduce that issue?
-
@casdevel All code is in my first post. It's very simple example.
-
We need to see one of [b,c,d,e].cpp, where is the constructor ?
-
@mranger90 Constructors are empty. All for ClassB,C,D,E,F looks the same
ClassB::ClassB(QObject *parent) : QObject(parent) { }
-
All code is in my first post. It's very simple example.
It's part of the code, not all. Maybe example is simple but problem is obviously not, otherwise it would already be solved.
I think your best bet for solving this would be to upload complete project. -
@casdevel All code below. In my first post I described how to get gdb warning.
Main#include <QApplication> #include "classa.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); ClassA *pA = new ClassA(); return a.exec(); }
H files
#ifndef CLASSA_H #define CLASSA_H #include <QObject> #include "classb.h" #include "classc.h" #include "classd.h" #include "classe.h" #include "classf.h" class ClassA : public QObject { Q_OBJECT public: explicit ClassA(QObject *parent = nullptr); ~ClassA(); private: ClassB *pB; ClassC *pC; ClassD *pD; ClassE *pE; ClassF *pF; signals: public slots: }; #endif // CLASSA_H #ifndef CLASSB_H #define CLASSB_H #include <QObject> class ClassB : public QObject { Q_OBJECT public: explicit ClassB(QObject *parent = nullptr); ~ClassB(); signals: public slots: }; #endif // CLASSB_H #ifndef CLASSC_H #define CLASSC_H #include <QObject> class ClassC : public QObject { Q_OBJECT public: explicit ClassC(QObject *parent = nullptr); ~ClassC(); signals: public slots: }; #endif // CLASSC_H #ifndef CLASSD_H #define CLASSD_H #include <QObject> class ClassD : public QObject { Q_OBJECT public: explicit ClassD(QObject *parent = nullptr); ~ClassD(); signals: public slots: }; #endif // CLASSD_H #ifndef CLASSE_H #define CLASSE_H #include <QObject> class ClassE : public QObject { Q_OBJECT public: explicit ClassE(QObject *parent = nullptr); ~ClassE(); signals: public slots: }; #endif // CLASSE_H #ifndef CLASSF_H #define CLASSF_H #include <QObject> class ClassF : public QObject { Q_OBJECT public: explicit ClassF(QObject *parent = nullptr); ~ClassF(); signals: public slots: }; #endif // CLASSF_H
cpp files
#include "classa.h" ClassA::ClassA(QObject *parent) : QObject(parent), pB(nullptr), pC(nullptr), pD(nullptr), pE(nullptr), pF(nullptr) { pB = new ClassB(); pC = new ClassC(); pD = new ClassD(); pE = new ClassE(); pF = new ClassF(); } ClassA::~ClassA() { } #include "classb.h" ClassB::ClassB(QObject *parent) : QObject(parent) { } ClassB::~ClassB() { } #include "classc.h" ClassC::ClassC(QObject *parent) : QObject(parent) { } ClassC::~ClassC() { } #include "classd.h" ClassD::ClassD(QObject *parent) : QObject(parent) { } ClassD::~ClassD() { } #include "classe.h" ClassE::ClassE(QObject *parent) : QObject(parent) { } ClassE::~ClassE() { } #include "classf.h" ClassF::ClassF(QObject *parent) : QObject(parent) { } ClassF::~ClassF() { }
-
And .pro file
#------------------------------------------------- # # Project created by QtCreator 2018-02-09T17:35:19 # #------------------------------------------------- QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = Test TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. #DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ classa.cpp \ classb.cpp \ classc.cpp \ classd.cpp \ classe.cpp \ classf.cpp HEADERS += \ classa.h \ classb.h \ classc.h \ classd.h \ classe.h \ classf.h
-
OK, I get the same warning as you if I use Qt 5.10.0, but with older Qt 5.5.1 there is no warning. I didn't investigate why since
app is running fine and debugging also working correctly (apart from that warning) with both Qt versions.I think that you can safely ignore this warning since everything is working correctly.
-
@casdevel @wojj Would be worth to file a bug report to get rid of this warning.
And sometimes warnings actually point to real issues :-) -
Thank you for help. The problem seems to be related to Qt version in that case.
Best regards.