Bug 16992 - libQtGui linked with gold crashes all Qt programs on startup
Summary: libQtGui linked with gold crashes all Qt programs on startup
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.25
: P2 normal
Target Milestone: ---
Assignee: Cary Coutant
URL:
Keywords:
: 17895 (view as bug list)
Depends on:
Blocks:
 
Reported: 2014-05-28 09:48 UTC by Markus Trippelsdorf
Modified: 2015-02-17 07:07 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Trippelsdorf 2014-05-28 09:48:39 UTC
When I build libQtGui with gold, all Qt application crash during
startup on my system, e.g.:

 % gdb smplayer
...
This is SMPlayer v. 0.8.6 running on Linux

Program received signal SIGSEGV, Segmentation fault.
QDockWidgetLayout::minimumSize (this=0xb5da50) at widgets/qdockwidget.cpp:362

(gdb) bt
#0  QDockWidgetLayout::minimumSize (this=0xb5da50) at widgets/qdockwidget.cpp:362
#1  0x00007ffff6e5118d in QLayout::totalMinimumSize (this=this@entry=0xb5da50) at kernel/qlayout.cpp:821
#2  0x00007ffff6e52a48 in QLayout::activate (this=0xb5da50) at kernel/qlayout.cpp:1231
#3  0x00007ffff6e79954 in QWidget::setVisible (this=0xa8e930, visible=<optimized out>) at kernel/qwidget.cpp:7745
#4  0x00007ffff71ffa86 in show (this=0xa8e930) at ../../include/QtGui/../../src/gui/kernel/qwidget.h:497
#5  QDockWidgetPrivate::setWindowState (this=this@entry=0xb5d600, floating=floating@entry=false, unplug=unplug@entry=false, rect=...) at widgets/qdockwidget.cpp:1067
#6  0x00007ffff71ffdc9 in QDockWidget::setFloating (this=0xa8e930, floating=<optimized out>) at widgets/qdockwidget.cpp:1285
#7  0x00000000004c9d0a in BaseGuiPlus::BaseGuiPlus(QWidget*, QFlags<Qt::WindowType>) ()
#8  0x00000000004fdb6a in DefaultGui::DefaultGui(QWidget*, QFlags<Qt::WindowType>) ()
#9  0x0000000000501192 in SMPlayer::createGUI(QString) ()
#10 0x00000000005016ab in SMPlayer::gui() ()
#11 0x0000000000429cae in main ()

Then link command in question is:

x86_64-pc-linux-gnu-g++ -Wl,--hash-style=gnu,--as-needed,--gc-sections -Wl,--no-undefined -shared -Wl,-Bsymbolic-functions -Wl,--dynamic-list,/var/tmp/portage/dev-qt/qtgui-4.8.5-r2/work/qt-everywhere-opensource-src-4.8.5/src/gui/QtGui.dynlist -Wl,-soname,libQtGui.so.4 -o libQtGui.so.4.8.5 .obj/release-shared/qdrawhelper_mmx.o ...(tons of other object files)... -L/usr/lib64 -L/var/tmp/portage/dev-qt/qtgui-4.8.5-r2/work/qt-everywhere-opensource-src-4.8.5/lib -L/usr/X11R6/lib -L/usr/lib64/qt4 -lQtCore -L/usr/lib64 -lgthread-2.0 -lglib-2.0 -lpthread -lgthread-2.0 -pthread -lglib-2.0 -lpng -lz -lfreetype -lSM -lICE -lXi -lXrender -lXrandr -lXfixes -lXcursor -L/usr/lib -lfontconfig -lfreetype -lXext -lX11 -lm

When I use ld.bfd instead with the same link command above, everything works
fine without any crashes.

 # ld -v
GNU gold (GNU Binutils 2.24.51.20140508) 1.11
Comment 1 Markus Trippelsdorf 2014-05-28 09:52:03 UTC
 # cat /var/tmp/portage/dev-qt/qtgui-4.8.5-r2/work/qt-everywhere-opensource-src-4.8.5/src/gui/QtGui.dynlist
{
     extern "C++" {
         "qt_x11ft_convert_pattern(_FcPattern*, QByteArray*, int*, bool*)";
         "QApplication::x11ClientMessage(QWidget*, _XEvent*, bool)";
         "QApplication::notify(QObject*, QEvent*)";
         "QApplication::qwsEventFilter(QWSEvent*)";
     };
};
Comment 2 Markus Trippelsdorf 2014-05-28 10:22:41 UTC
When I delete "-Wl,--dynamic-list,/var/tmp/portage/dev-qt/qtgui-4.8.5-r2/work/qt-everywhere-opensource-src-4.8.5/src/gui/QtGui.dynlist" from the g++ invocation
the problem goes away.
Comment 3 Markus Trippelsdorf 2014-07-04 06:12:28 UTC
Cary, this is a nasty bug. Let me know if you need more information.

Marxin encountered a similar issue when testing gentoo with LTO:
http://marxin.github.io/blog/2014/04/24/gentoo-linux-packages-with-gcc-4-dot-9-lto/
Comment 4 Cary Coutant 2014-07-08 17:29:41 UTC
Please provide the complete link line and a tar file with all input objects and libraries.

If you keep the --dynamic-list option, but remove -Bsymbolic-functions, does it still crash?

What's at widgets/qdockwidget.cpp:362? Specifically, do you know what the instruction that segfaulted was trying to do?
Comment 5 Markus Trippelsdorf 2014-07-08 18:26:37 UTC
(In reply to Cary Coutant from comment #4)
> Please provide the complete link line and a tar file with all input objects
> and libraries.

 % wget trippelsdorf.de/testcase.tar.bz2 (90MB)
 % tar -xjf testcase.tar.bz2
 % x86_64-pc-linux-gnu-g++ -Wl,--hash-style=gnu,--as-needed,--gc-sections -Wl,--no-undefined -shared -Wl,-Bsymbolic-functions -Wl,--dynamic-list,.obj/QtGui.dynlist -Wl,-soname,libQtGui.so.4 -o libQtGui.so.4.8.5 .obj/release-shared/*.o -L/usr/lib64 -L/usr/X11R6/lib -L/usr/lib64/qt4 -lQtCore -L/usr/lib64 -lgthread-2.0 -lglib-2.0 -lpthread -lgthread-2.0 -pthread -lglib-2.0 -lpng -lz -lfreetype -lSM -lICE -lXi -lXrender -lXrandr -lXfixes -lXcursor -L/usr/lib -lfontconfig -lfreetype -lXext -lX11 -lm  

> If you keep the --dynamic-list option, but remove -Bsymbolic-functions, does
> it still crash?

Yes.

> What's at widgets/qdockwidget.cpp:362? Specifically, do you know what the
> instruction that segfaulted was trying to do?

 354 QSize QDockWidgetLayout::minimumSize() const
 355 {
 356     QDockWidget *w = qobject_cast<QDockWidget*>(parentWidget());
 357
 358     QSize content(0, 0);
 359     if (item_list[Content] != 0)
 360         content = item_list[Content]->minimumSize();
 361
 362     return sizeFromContent(content, w->isFloating());
 363 }

(gdb) p content
$1 = {
  wd = 0, 
  ht = 0
}
(gdb) p w
$2 = (QDockWidget *) 0x0
Comment 6 Cary Coutant 2014-07-09 18:31:19 UTC
On Tue, Jul 8, 2014 at 11:26 AM, markus at trippelsdorf dot de
<sourceware-bugzilla@sourceware.org> wrote:
>  % x86_64-pc-linux-gnu-g++ -Wl,--hash-style=gnu,--as-needed,--gc-sections
> -Wl,--no-undefined -shared -Wl,-Bsymbolic-functions
> -Wl,--dynamic-list,.obj/QtGui.dynlist -Wl,-soname,libQtGui.so.4 -o
> libQtGui.so.4.8.5 .obj/release-shared/*.o -L/usr/lib64 -L/usr/X11R6/lib
> -L/usr/lib64/qt4 -lQtCore -L/usr/lib64 -lgthread-2.0 -lglib-2.0 -lpthread
> -lgthread-2.0 -pthread -lglib-2.0 -lpng -lz -lfreetype -lSM -lICE -lXi
> -lXrender -lXrandr -lXfixes -lXcursor -L/usr/lib -lfontconfig -lfreetype -lXext
> -lX11 -lm

Thanks, but I still get:

ld: error: cannot find -lQtCore

I found the downloads for Qt 4.8.5, but it looks like I'd have to
download the sources and build it from scratch. Can you just send me
that one library?

-cary
Comment 7 Markus Trippelsdorf 2014-07-09 18:39:48 UTC
 % wget trippelsdorf.de/libQtCore.so.4.8.5
Comment 8 Cary Coutant 2014-07-09 21:59:19 UTC
While I still don't have enough to actually run the code (I had to
stub out png_set_longjmp_fn because my libpng is too old, and I don't
have an executable that uses the library), I've compared some obvious
things between gold output and Gnu ld output, and don't see any
differences. I'm using a trunk version of gold, and it has a --dynsym
fix (for PR gold/13577) that isn't in binutils 2.24:

   https://sourceware.org/ml/binutils/2014-02/msg00042.html

I thought I had ruled that out as a possibility when I asked you if
removing -Bsymbolic-functions made any difference, but I was
forgetting that that wasn't the only problem I fixed in that patch.

Can you get a gold built from trunk and give it a try?

If that fixes it, would you want that patch backported to the 2.24 branch?

-cary
Comment 9 Markus Trippelsdorf 2014-07-10 02:57:58 UTC
 % ld -v
GNU gold (Gentoo git 2.24.51.20140709) 1.11

I'm afraid that your "fix" actually introduced the issue at hand.
Comment 10 Markus Trippelsdorf 2014-07-10 06:06:16 UTC
And indeed, if I revert your commit fd834e57ffce2 the problem goes away.
Comment 11 Markus Trippelsdorf 2015-02-13 22:07:00 UTC
See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65057
For a small testcase.
Comment 12 Cary Coutant 2015-02-13 22:12:41 UTC
(In reply to Markus Trippelsdorf from comment #11)
> See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65057
> For a small testcase.

Thanks, I'll take a look.
Comment 13 Sourceware Commits 2015-02-17 06:15:52 UTC
The master branch has been updated by Cary Coutant <ccoutant@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e9c1bdad269c0c3352eebcc9481ed65144001b0b

commit e9c1bdad269c0c3352eebcc9481ed65144001b0b
Author: Cary Coutant <ccoutant@google.com>
Date:   Mon Feb 16 22:15:12 2015 -0800

    Fix --dynamic-list so that symbols not in the list are still exported.
    
    In PR 13577, the complaint was that -Bsymbolic was overriding the binding
    behavior for symbols listed in the --dynamic-list by setting the DT_SYMBOLIC
    tag in the dynamic table. In reading the Gnu ld manual, I decided that
    --dynamic-list should be mutually exclusive of -Bsymbolic, and modified
    gold so that --dynamic-list would treat symbols listed as preemptible,
    and all other symbols as internally bound. I was wrong.
    
    PR 16992 shows that with --dynamic-list (and not -Bsymbolic), a symbol
    not listed in the dynamic list is being internally bound within the
    shared library, but because it's still in the dynamic symbol table, we
    expose it to a COPY relocation, and things go really bad from there.
    
    (I can reproduce the same failure, simply by turning on -Bsymbolic-functions
    with the Gnu linker. Even though the symbol is bound internally, it's
    still exported to the dynamic symbol table, and is exposed to a COPY
    relocation.)
    
    I've backed out part of the fix for PR 13577, and -Bsymbolic (or
    -Bsymbolic-functions) can now be used with --dynamic-list, but if the
    two are used together, we do not set DT_SYMBOLIC or DF_SYMBOLIC
    (this matches Gnu ld behavior). We now treat symbols listed in the
    dynamic list as premptible, but we do not automatically treat symbols
    not listed there as non-premptible.
    
    gold/
    	PR gold/13577
    	PR gold/16992
    	* layout.cc (Layout::finish_dynamic_section): Don't set DT_SYMBOLIC or
    	DF_SYMBOLIC if --dynamic-list option is used.
    	* options.cc (General_options::finalize): --dynamic-list is not
    	mutually exclusive with -Bsymbolic.
    	* symtab.h (Symbol::is_preemptible): Don't exclude dynamic symbols not
    	listed in --dynamic-list.
    	* testsuite/Makefile.am (dynamic_list_lib2.so): Add
    	-Bsymbolic-functions.
    	* testsuite/Makefile.in: Regenerate.
Comment 14 Cary Coutant 2015-02-17 06:21:13 UTC
The problem looks like a COPY relocation to a symbol that was internally bound within the shared library (because it was not listed in the --dynamic-list option). My original interpretation of --dynamic-list was that symbols listed in the file should be preemptible, and by implication all other symbols should *not* be. Unfortunately, COPY relocations break that internal binding (if we make a symbol bound internally, we should change the visibility to protected to prevent COPY relocations). But my interpretation did not match Gnu ld, so I've fixed it to match more closely what Gnu ld does.
Comment 15 Markus Trippelsdorf 2015-02-17 07:07:26 UTC
*** Bug 17895 has been marked as a duplicate of this bug. ***