Bug 121872 - yast2-qt segfault at program end if no Qt style is defined
Summary: yast2-qt segfault at program end if no Qt style is defined
Status: RESOLVED FIXED
: 159745 (view as bug list)
Alias: None
Product: SUSE LINUX 10.0
Classification: openSUSE
Component: YaST2 (show other bugs)
Version: Final
Hardware: Other All
: P5 - None : Major
Target Milestone: ---
Assignee: Stefan Hundhammer
QA Contact: Klaus Kämpf
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-10-09 12:16 UTC by Andreas Klein
Modified: 2006-03-29 18:58 UTC (History)
5 users (show)

See Also:
Found By: Other
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
yast2 logs (572.46 KB, application/x-compressed-tar)
2005-10-09 12:21 UTC, Andreas Klein
Details
output from valgrind from y2base TextEntry1.ycp qt with segfault (19.55 KB, text/plain)
2005-10-11 14:27 UTC, Stefan Hundhammer
Details
output from valgrind from y2base HelloWorld.ycp qt terminating OK (17.33 KB, text/plain)
2005-10-11 14:28 UTC, Stefan Hundhammer
Details
Diff between the valgrind outputs (edited - cut off irrelevant parts like diff only in different addresses) (4.86 KB, text/plain)
2005-10-11 14:33 UTC, Stefan Hundhammer
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Klein 2005-10-09 12:16:25 UTC
Command: /sbin/yast2 lvm_config &
Segmentation fault at /usr/share/YaST2/clients/lvm_config.ycp:121
/sbin/yast2: line 207: 13767 Segmentation fault      $ybindir/y2base $module
"$@" qt -geometry "$Y2_GEOMETRY" $Y2QT_ARGS
Command: /sbin/yast2 lvm_config &
Segmentation fault at /usr/share/YaST2/clients/lvm_config.ycp:121
/sbin/yast2: line 207: 14160 Segmentation fault      $ybindir/y2base $module
"$@" qt -geometry "$Y2_GEOMETRY" $Y2QT_ARGS

Will attach the YaST2 logs.
Comment 1 Andreas Klein 2005-10-09 12:21:06 UTC
Created attachment 52039 [details]
yast2 logs
Comment 2 Thomas Fehr 2005-10-10 09:58:40 UTC
Cannot reproduce this here.
Please try removing "yast2-storage-evms.rpm" and retry "/sbin/yast2 lvm_config".
Comment 3 Thomas Fehr 2005-10-10 10:08:58 UTC
Additionally the output of 
   rpm -q yast2-storage-lib yast2-storage yast2-storage-evms
might be helpful.
Comment 4 Thomas Fehr 2005-10-10 10:15:00 UTC
Meanwhile I could reproduce it. 
It seems to happen in von LVM VG is present.
Comment 5 Thomas Fehr 2005-10-10 10:38:07 UTC
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
Comment 6 Stefan Hundhammer 2005-10-11 09:56:21 UTC
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... 
Comment 7 Thomas Fehr 2005-10-11 10:29:32 UTC
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.
Comment 8 Stefan Hundhammer 2005-10-11 12:13:27 UTC
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... 
Comment 9 Stefan Hundhammer 2005-10-11 13:58:51 UTC
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. 
  
Comment 10 Stefan Hundhammer 2005-10-11 14:27:13 UTC
Created attachment 53638 [details]
output from valgrind from y2base TextEntry1.ycp qt with segfault
Comment 11 Stefan Hundhammer 2005-10-11 14:28:10 UTC
Created attachment 53639 [details]
output from valgrind from y2base HelloWorld.ycp qt terminating OK
Comment 12 Stefan Hundhammer 2005-10-11 14:33:38 UTC
Created attachment 53640 [details]
Diff between the valgrind outputs (edited - cut off irrelevant parts like diff only in different addresses)
Comment 13 Stefan Hundhammer 2005-10-11 16:08:03 UTC
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. 
Comment 14 Stefan Hundhammer 2005-10-11 16:09:43 UTC
BTW Andreas: As a workaround, the problem should disappear if you invoke 
 
    /usr/lib/qt3/bin/qconfig 
 
and select a widget style there. 
 
Comment 15 Stefan Hundhammer 2005-10-11 16:24:25 UTC
I don't know why, but I can't reproduce this problem with the Qt examples. IMHO 
it should appear there, too. 
Comment 16 Stefan Hundhammer 2005-10-24 14:17:23 UTC
Maybe there is a connection to bug #127825.
Comment 17 Stefan Hundhammer 2005-10-24 14:19:42 UTC
Sorry, forget comment #16 - wrong bug ID.

Correct:

Maybe there is a connection to bug #121870.
Comment 18 Stefan Hundhammer 2006-01-24 10:49:53 UTC
*** Bug 144974 has been marked as a duplicate of this bug. ***
Comment 19 Stefan Hundhammer 2006-03-29 15:45:06 UTC
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?
Comment 20 Stefan Hundhammer 2006-03-29 18:51:51 UTC
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().
Comment 21 Stefan Hundhammer 2006-03-29 18:53:35 UTC
*** Bug 159745 has been marked as a duplicate of this bug. ***
Comment 22 Stefan Hundhammer 2006-03-29 18:54:33 UTC
(Yes, that workaround IS an ugly hack, but it works)
Comment 23 Stefan Hundhammer 2006-03-29 18:58:17 UTC
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.