mark
mark

Reputation: 62866

Why gcc linker does not see my destructor?

I am trying to compile wkhtmltopdf-qt on a Linux machine following the instructions from https://code.google.com/p/wkhtmltopdf/wiki/compilation.

Now I am stuck with linker refusing to link. It prints several errors, but the one that caught my eyes is this:

/home/ubuntu/wkhtmltopdf-qt/lib/libwebcore.a(AccessibilityRenderObject.o): In function `WebCore::AccessibilityRenderObject::~AccessibilityRenderObject()':
AccessibilityRenderObject.cpp:(.text._ZN7WebCore25AccessibilityRenderObjectD0Ev+0x5): undefined reference to `WebCore::AccessibilityRenderObject::~AccessibilityRenderObject()'

This is strange to say the least. First, because the linker claims that the destructor attempts to reference itself and next - because it fails to do so! Crazy stuff... Anyway, everything seems to be defined. Please, observe:

ubuntu@ip-10-245-78-162:~$ nm --defined-only -C -A /home/ubuntu/wkhtmltopdf-qt/lib/libwebcore.a | grep ~AccessibilityRenderObject
/home/ubuntu/wkhtmltopdf-qt/lib/libwebcore.a:AccessibilityRenderObject.o:0000000000000000 T WebCore::AccessibilityRenderObject::~AccessibilityRenderObject()
/home/ubuntu/wkhtmltopdf-qt/lib/libwebcore.a:AccessibilityRenderObject.o:0000000000000000 T WebCore::AccessibilityRenderObject::~AccessibilityRenderObject()
/home/ubuntu/wkhtmltopdf-qt/lib/libwebcore.a:AccessibilityRenderObject.o:0000000000000000 T WebCore::AccessibilityRenderObject::~AccessibilityRenderObject()
ubuntu@ip-10-245-78-162:~/wkhtmltopdf-qt/src/3rdparty/webkit/Source/WebCore/accessibility$

Next, in the file AccessibilityRenderObject.cpp:

#include <wtf/unicode/CharacterNames.h>

using namespace std;

namespace WebCore {

using namespace HTMLNames;

AccessibilityRenderObject::AccessibilityRenderObject(RenderObject* renderer)
    : AccessibilityObject()
    , m_renderer(renderer)
    , m_ariaRole(UnknownRole)
    , m_childrenDirty(false)
    , m_roleForMSAA(UnknownRole)
{
    m_role = determineAccessibilityRole();

#ifndef NDEBUG
    m_renderer->setHasAXObject(true);
#endif
}

AccessibilityRenderObject::~AccessibilityRenderObject()
{
    ASSERT(isDetached());
}

So, the destructor is defined just fine. But I went even further - I compiled AccessibilityRenderObject.cpp again, this time stopping at the preprocessor. Sure as hell the destructor is there:

class AccessibilityRenderObject : public AccessibilityObject {
protected:
    AccessibilityRenderObject(RenderObject*);
public:
    static PassRefPtr<AccessibilityRenderObject> create(RenderObject*);
    virtual ~AccessibilityRenderObject();
.
.
.
AccessibilityRenderObject::~AccessibilityRenderObject()
{
    ((void)0);
}

The compilation line used to compile that file (as well as many others) is this:

g++ -c -m64 -pipe -Wall -Wextra -Wreturn-type -fno-strict-aliasing -Wcast-align -Wchar-subscripts -Wformat-security -Wreturn-type -Wno-unused-parameter -Wno-sign-compare -Wno-switch -Wno-switch-enum -Wundef -Wmissing-noreturn -Winit-self -Wno-c++0x-compat -ffunction-sections -fdata-sections -O2 -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -D_REENTRANT -DNDEBUG -DBUILDING_QT__=1 -DNDEBUG -DQT_ASCII_CAST_WARNINGS -DENABLE_XSLT=0 -DENABLE_WEB_TIMING=0 -DENABLE_JAVASCRIPT_DEBUGGER=1 -DENABLE_DATABASE=1 -DENABLE_EVENTSOURCE=1 -DENABLE_OFFLINE_WEB_APPLICATIONS=1 -DENABLE_DOM_STORAGE=1 -DENABLE_ICONDATABASE=1 -DENABLE_CHANNEL_MESSAGING=1 -DENABLE_DIRECTORY_UPLOAD=0 -DENABLE_FILE_SYSTEM=0 -DENABLE_QUOTA=0 -DENABLE_SQLITE=1 -DENABLE_DASHBOARD_SUPPORT=0 -DENABLE_FILTERS=1 -DENABLE_XPATH=1 -DENABLE_WCSS=0 -DENABLE_SHARED_WORKERS=1 -DENABLE_WORKERS=1 -DENABLE_XHTMLMP=0 -DENABLE_DETAILS=1 -DENABLE_METER_TAG=1 -DENABLE_PROGRESS_TAG=1 -DENABLE_BLOB=1 -DENABLE_NOTIFICATIONS=1 -DENABLE_INPUT_SPEECH=0 -DENABLE_INSPECTOR=1 -DENABLE_3D_RENDERING=1 -DENABLE_WEB_AUDIO=0 -DENABLE_WEBGL=0 -DENABLE_MEDIA_STATISTICS=0 -DENABLE_VIDEO_TRACK=0 -DENABLE_TOUCH_ICON_LOADING=0 -DENABLE_ANIMATION_API=0 -DENABLE_SVG=1 -DENABLE_SVG_FONTS=1 -DENABLE_SVG_FOREIGN_OBJECT=1 -DENABLE_SVG_ANIMATION=1 -DENABLE_SVG_AS_IMAGE=1 -DENABLE_SVG_USE=1 -DENABLE_DATALIST=1 -DENABLE_TILED_BACKING_STORE=1 -DENABLE_NETSCAPE_PLUGIN_API=1 -DENABLE_WEB_SOCKETS=1 -DWTF_USE_QT_BEARER=1 -DENABLE_TOUCH_EVENTS=1 -DENABLE_VIDEO=0 -DENABLE_VIDEO=0 -DSQLITE_CORE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_OMIT_COMPLETE -DXP_UNIX -DENABLE_NETSCAPE_PLUGIN_METADATA_CACHE=1 -DBUILDING_JavaScriptCore -DBUILDING_WTF -DBUILDING_WEBKIT -DQT_MAKEDLL -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I../../../../../mkspecs/linux-g++-64 -I. -I../../../../../include/QtCore -I../../../../../include/QtNetwork -I../../../../../include/QtGui -I../../../../../include -I../JavaScriptCore -I../../Source -I../ThirdParty -I../JavaScriptCore/assembler -I../JavaScriptCore/bytecode -I../JavaScriptCore/bytecompiler -I../JavaScriptCore/heap -I../JavaScriptCore/dfg -I../JavaScriptCore/debugger -I../JavaScriptCore/interpreter -I../JavaScriptCore/jit -I../JavaScriptCore/parser -I../JavaScriptCore/profiler -I../JavaScriptCore/runtime -I../JavaScriptCore/wtf -I../JavaScriptCore/wtf/gobject -I/home/ubuntu/wkhtmltopdf-qt/src/3rdparty/webkit/Source/JavaScriptCore/wtf/symbian -I../JavaScriptCore/wtf/unicode -I../JavaScriptCore/yarr -I../JavaScriptCore/API -I../JavaScriptCore/ForwardingHeaders -I../JavaScriptCore/generated -Ibridge/qt -Ipage/qt -Iplatform/graphics/qt -Iplatform/network/qt -Iplatform/qt -I../WebKit/qt/Api -I../WebKit/qt/WebCoreSupport -I. -Iaccessibility -Ibindings -Ibindings/generic -Ibridge -Icss -Idom -Idom/default -Iediting -Ifileapi -Ihistory -Ihtml -Ihtml/canvas -Ihtml/parser -Ihtml/shadow -Iinspector -Iloader -Iloader/appcache -Iloader/archive -Iloader/cache -Iloader/icon -Imathml -Inotifications -Ipage -Ipage/animation -Iplatform -Iplatform/animation -Iplatform/audio -Iplatform/graphics -Iplatform/graphics/filters -Iplatform/graphics/filters/arm -Iplatform/graphics/texmap -Iplatform/graphics/transforms -Iplatform/image-decoders -Iplatform/leveldb -Iplatform/mock -Iplatform/network -Iplatform/sql -Iplatform/text -Iplatform/text/transcoder -Iplugins -Irendering -Irendering/mathml -Irendering/style -Irendering/svg -Istorage -Isvg -Isvg/animation -Isvg/graphics -Isvg/graphics/filters -Isvg/properties -Itesting -Iwebaudio -Iwebsockets -I/home/ubuntu/wkhtmltopdf-qt/src/3rdparty/webkit/Source/WebCore/wml -Iworkers -Ixml -Ibridge/jsc -Ibindings/js -I/home/ubuntu/wkhtmltopdf-qt/src/3rdparty/webkit/Source/WebCore/bindings/js/specialization -Ibridge/c -Itesting/js -Igenerated -I../../Source -I../../include -I../include/QtWebKit -I../include -I../../../sqlite -I/usr/X11R6/include -I.moc/release-static -o .obj/release-static/AccessibilityRenderObject.o accessibility/AccessibilityRenderObject.cpp

Finally, the linker command line that fails is this:

g++ -Wl,-rpath-link,/home/ubuntu/wkhtmltopdf-qt/lib -m64 -Wl,-O1 -Wl,-rpath,/home/ubuntu/wkhtmltopdf-qt/src/3rdparty/webkit/Source/lib -Wl,-rpa
th,/home/ubuntu/wkqt/lib -Wl,-rpath,/home/ubuntu/wkqt/lib -o tst_qwebframe .obj/release-static/tst_qwebframe.o .obj/release-static/qrc_tst_qweb
frame.o    -L/home/ubuntu/wkhtmltopdf-qt/lib -L/usr/X11R6/lib64 -L/home/ubuntu/wkhtmltopdf-qt/lib -lQtWebKit -L../../WebCore/release -L../../Ja
vaScriptCore/release -L/usr/X11R6/lib64 -Wl,--start-group -lwebcore -lQtWebKit -Wl,--end-group -ljscore -lQtTest -lQtGui -lXrender -lXext -lX11
 -lQtNetwork -lQtCore -lm -ldl -lrt -lpthread -lXrender -lXext -lX11 -lm

And all the linker errors referring to the aforementioned destructor are:

/home/ubuntu/wkhtmltopdf-qt/lib/libwebcore.a(AccessibilityRenderObject.o): In function `WebCore::AccessibilityRenderObject::~AccessibilityRenderObject()':
AccessibilityRenderObject.cpp:(.text._ZN7WebCore25AccessibilityRenderObjectD2Ev+0x3): undefined reference to `vtable for WebCore::AccessibilityRenderObject'
/home/ubuntu/wkhtmltopdf-qt/lib/libwebcore.a(AccessibilityRenderObject.o): In function `WebCore::AccessibilityRenderObject::~AccessibilityRenderObject()':
AccessibilityRenderObject.cpp:(.text._ZN7WebCore25AccessibilityRenderObjectD0Ev+0x5): undefined reference to `WebCore::AccessibilityRenderObject::~AccessibilityRenderObject()'

There are many suspicious linker errors, like:

/home/ubuntu/wkhtmltopdf-qt/lib/libwebcore.a(AccessibilityMenuList.o):(.data.rel.ro._ZTIN7WebCore21AccessibilityMenuListE[typeinfo for WebCore:
:AccessibilityMenuList]+0x10): undefined reference to `typeinfo for WebCore::AccessibilityRenderObject'

But as far as I can see all the virtual functions are properly declared and defined and no makefile in all of the source tree mentions rtti at all.

Can anyone explain to me what is going on?

Upvotes: 2

Views: 1627

Answers (1)

Brett Hale
Brett Hale

Reputation: 22358

The compilation command includes the options: -ffunction-sections -fdata-sections (documented here). -ffunction-sections puts each function in its own section of the object file, rather than simply placing them all in a single .text section. Similarly, -fdata-sections applies to global / static data.

The idea is that, by specifying --gc-sections (garbage collection of unused input sections), the linker can discard 'unreachable' sections before coalescing them into the final .text section of the binary. In short, to reduce code size without using separate compilation units for each function.

So that was the hunch. I would have expected it to work without the --gc-sections option regardless. Obviously there would be no benefit, since nothing gets discarded. Why does it fail?

When a destructor is implemented, the C++ ABI used by gcc, clang, etc., typically generates 3 destructor variants, ending with: D0Ev, D1Ev, D2Ev, as well as vtable and typeinfo data for that class. My guess is that these separate sections are not being coalesced correctly. Whether this is a bug, or a limitation of the linker (or link spec), I don't know.


This is also useless when building shared libraries, since there's no way of knowing in advance which symbols will be used. The compiler is invoked with -fPIC, which should be ok, since the objects are simply being archived. The -fvisibility options might be complicating the issue, however.

Upvotes: 6

Related Questions