|
Bugzilla – Full Text Bug Listing |
| Summary: | yast2-qt segfault at program end if no Qt style is defined | ||
|---|---|---|---|
| Product: | [openSUSE] SUSE LINUX 10.0 | Reporter: | Andreas Klein <asklein> |
| Component: | YaST2 | Assignee: | Stefan Hundhammer <shundhammer> |
| Status: | RESOLVED FIXED | QA Contact: | Klaus Kämpf <kkaempf> |
| Severity: | Major | ||
| Priority: | P5 - None | CC: | coolo, erik.jacobson, matz, mistinie, vetter |
| Version: | Final | ||
| Target Milestone: | --- | ||
| Hardware: | Other | ||
| OS: | All | ||
| Whiteboard: | |||
| Found By: | Other | Services Priority: | |
| Business Priority: | Blocker: | --- | |
| Marketing QA Status: | --- | IT Deployment: | --- |
| Attachments: |
yast2 logs
output from valgrind from y2base TextEntry1.ycp qt with segfault output from valgrind from y2base HelloWorld.ycp qt terminating OK Diff between the valgrind outputs (edited - cut off irrelevant parts like diff only in different addresses) |
||
|
Description
Andreas Klein
2005-10-09 12:16:25 UTC
Created attachment 52039 [details]
yast2 logs
Cannot reproduce this here. Please try removing "yast2-storage-evms.rpm" and retry "/sbin/yast2 lvm_config". Additionally the output of rpm -q yast2-storage-lib yast2-storage yast2-storage-evms might be helpful. Meanwhile I could reproduce it. It seems to happen in von LVM VG is present. This seems to be a problem with the Qt framework. The crash does not happen with ncurses UI but only with Qt. Gdb catches the crash at It seems Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 1083044512 (LWP 15313)] 0x419e7a8d in QLibraryPrivate::freeLibrary () from /usr/lib/qt3/lib/libqt-mt.so.3 (gdb) where #0 0x419e7a8d in QLibraryPrivate::freeLibrary () from /usr/lib/qt3/lib/libqt-mt.so.3 Cannot access memory at address 0x419e7a60 (gdb) quit The program is running. Quit anyway (and detach it)? (y or n) y Detaching from program: /usr/lib/YaST2/bin/y2base, process 15313 e184:/var/log/YaST2 # No idea how to debug the Qt stuff. Problem can be reproduced easily on my test machine e184.suse.de That sounds much more like a memory corruption problem to me. The Qt libs on that level are very stable; I have yet to see the first segfault caused by them. Much more likely at some completely unrelated place some other part of the core binaries overwrite some piece of memory. If that happens at some "freeXXX()" call this points to a heap corruption - pointers to the next allocated block on the heap may have been overwritten. If this changes when some path of some other code (like LVM VGs in comment #4) is being used, I would suspect that to happen in that code. Did anybody try to track this down with a tool like "valgrind" yet? As for how to debug the Qt part: It is usually a lot easier to start y2base with the "--nothreads" option for debbugging; then you don't have to take multiple threads into account. That's the downside of using C/C++ code - no longer "core free" happy living... The crash can be reproduce it with a minimal ycp code where libstorage or anything using lvm is not involved at all. Just log into e184.suse.de and start "/sbin/yast2 minimal_lvm_config". No idea which library used in yast2 is the culprit for the crash, but certainly a library that is not loaded at all (like libstorage in the case of minimal_lvm_config) cannot be made responsible for this crash. BTW: on e184.suse.de the crash happens reproducible with yast2-qt-2.12.11-2 and yast2-core-2.12.27-2. On my development system I have a slightly oder version of yast2-qt-2.12.9-2 with the same version of yast2-core and the crash does not happen. Hm - when I start it without threads in GDB, I get a backtrace with #40 0x40783cd0 in ?? () from /usr/lib/libstdc++.so.6 #41 0x081d9118 in ?? () #42 0x00000040 in ?? () #43 0x00000010 in ?? () #44 0x417ef80c in ?? () #45 0x081d9118 in ?? () #46 0x41806868 in ?? () #47 0xbfa0d7c8 in ?? () #48 0x4166561a in ?? () #49 0x081d942c in ?? () #50 0x417ef80c in ?? () #51 0x081d942c in ?? () #52 0xbfa0d9a4 in ?? () #53 0xbfa0d7e8 in ?? () #54 0x4000b2c0 in _dl_runtime_resolve () from /lib/ld-linux.so.2 #55 0x415862af in ?? () #56 0x081d9400 in ?? () #57 0xbfa0d9a4 in ?? () #58 0xbfa0d7e8 in ?? () #59 0x415775e0 in ?? () #60 0x408d9ff4 in ?? () from /lib/tls/libc.so.6 #61 0xbfa0da04 in ?? () #62 0xbfa0d808 in ?? () #63 0x407e91c4 in exit () from /lib/tls/libc.so.6 so it must clearly be a GLIBC problem according to that reasoning... With a lot of slash & burn (removing code) I found that even an absolutely
trivial UI example can produce that kind of segfault at program exit:
{
UI::OpenDialog(
`VBox(
`TextEntry("Name:"),
`PushButton("&OK")
)
);
UI::CloseDialog();
}
(with or without the UI::CloseDialog())
Further tests with the UI examples show that it segfaults at the end of the
program (i.e. probably in some destructor) when there is one of these widgets:
- TextEntry
- ComboBox (editable) - non-editable ComboBox works flawlessly
- MultiLineEdit
- PackageSelector (also contains QLineEdit)
There is no segfault with these examples:
HelloWorld.ycp
SelectionBox*.ycp
Tree*.ycp
Wizard*.ycp
There is no segfault when using the NCurses UI.
But OTOH this cannot be a general problem with all Qt-UI-TextEntry related
dialogs, otherwise not one of the installation dialogs would work.
So what triggers this?
It might still be some constructor or destructor code somewhere else overwriting
some memory. The fact that no code of that library is used does not necessarily
mean that none of its startup or exit code is ever called.
Created attachment 53638 [details]
output from valgrind from y2base TextEntry1.ycp qt with segfault
Created attachment 53639 [details]
output from valgrind from y2base HelloWorld.ycp qt terminating OK
Created attachment 53640 [details]
Diff between the valgrind outputs (edited - cut off irrelevant parts like diff only in different addresses)
After many tests it looks like it makes a difference if there is a widget style
defined in ~/.qt/qtrc :
I get a segfault on program end if there is no line
style=xxx
in the [General] section in ~/.qt/qtrc .
The segfault can also be avoided if a style is supplied on the command line with
-style=xxx
To me this sounds like some initialization problem if Qt needs to fall back to
its default style.
Will try to experiment with low-level Qt examples. I think this is a Qt bug.
BTW Andreas: As a workaround, the problem should disappear if you invoke
/usr/lib/qt3/bin/qconfig
and select a widget style there.
I don't know why, but I can't reproduce this problem with the Qt examples. IMHO it should appear there, too. Maybe there is a connection to bug #127825. Sorry, forget comment #16 - wrong bug ID. Correct: Maybe there is a connection to bug #121870. *** Bug 144974 has been marked as a duplicate of this bug. *** I tried to debug this with gdb, strace and of course with our normal y2logging, but it remains a mystery to me.
There does not seem a problem until YQUI::~YQUI() (the Qt UI's destructor). Even all the agents are unloaded allright. Only when exit() is called in liby2/genericfrontend.cc, there is a segfault:
497 y2milestone ("Finished YaST2 component '%s'", progname);
(gdb)
334 bool isNull() const { return element == 0; }
(gdb)
499 if( !result.isNull () && result->isBoolean() )
(gdb)
502 exit (EXIT_SUCCESS);
(gdb)
warning: Temporarily disabling breakpoints for unloaded shared library "/usr/lib/YaST2/plugin/libpy2qt.so.2"
Program received signal SIGSEGV, Segmentation fault.
The stack is always corrupted at this point - "bt" in gdb only displays garbage.
But OTOH if this is a problem of the liby2 plugin mechanism, why does adding or removing a Qt style in ~/.qt/qtrc change anything?
Michael Matz had enough patience to debug this in depth (while I was sitting by, amazed at what gdb can do if used by a true expert): Static destructors of the Qt libs cause a premature dlclose() for the Qt lib while it is still active. Qt does not seem to be designed for use in plugin libs. It loads some add-on libs dynamically with dlopen() and unloads them at program exit (QGPluginManager). Unfortunately, since they all depend on the Qt master lib (libqt-mt) themselves, when they are unloading the last call to dlclose() for them causes the last reference to libqt-mt to vanish as well. Since libqt-mt is already in the process of destruction there is no more reference from the caller of libqt-mt, and the GLIBC decides that libqt-mt is not needed any more (zero references) and unmaps libqt-mt. When the static destructor of libqt-mt that triggered the cleanup in QGPluginManager returns, the code it is to return to is already unmapped, causing a segfault. Workaround: Keep one more reference to libqt-mt open - dlopen() it here and make sure there is no corresponding dlclose(). *** Bug 159745 has been marked as a duplicate of this bug. *** (Yes, that workaround IS an ugly hack, but it works) The reason why setting a Qt widget style changes this seems to be that in this case another plugin library is loaded that has a dependency on libqt-mt. Only using a widget style that is not built into Qt (i.e., not "motif", "windows", "platinum" etc., but one of the KDE styles, like "plastik", "thinkeramik") worked around that problem: Another part of Qt that handles those widget theme plugin libs did not automatically dlclose() those libs, thus keeping a reference to libqt-mt alive. |