Bug 279364

Summary: routing profiles cause Marble to crash on exit
Product: [Applications] marble Reporter: Anton Chernov <chernov.anton.mail>
Component: generalAssignee: marble-bugs
Status: RESOLVED FIXED    
Severity: normal CC: chernov.anton.mail, hugh.kde.bugs, shentey
Priority: NOR    
Version: unspecified   
Target Milestone: 1.3 (KDE 4.8)   
Platform: Compiled Sources   
OS: All   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: This patch workaround this problem.

Description Anton Chernov 2011-08-04 10:40:56 UTC
Created attachment 62533 [details]
This patch workaround this problem.

Version:           unspecified
OS:                All

Segmentation fault error on quiting. 
The same problem was described in: 
https://bugs.kde.org/show_bug.cgi?id=274010
https://bugs.kde.org/show_bug.cgi?id=274558
https://bugs.kde.org/show_bug.cgi?id=274071

Affected versions:
Stable: 1.1.0
Development version from git.


Affected platforms:
Windows Vista (Nokia Qt SDK, mingw gcc-4.4, msvc2008 Pro)
Linux (gcc-4.4, Qt-4.6.2, Qt-4.7.0, Qt-4.7.3 )

The gdb backtrace is:

Program received signal SIGSEGV, Segmentation fault.
0x09c12146 in qDeleteAll<QHash<Marble::RunnerPlugin*, Marble::RunnerPlugin::Conf
igWidget*>::const_iterator> (begin={i = 0x1714f368}, end={i = 0x17148ed8})
    at C:/QtSDK/Desktop/Qt/4.7.3/mingw/include/QtCore/qalgorithms.h:322
322             delete *begin;
(gdb) ba
#0  0x09c12146 in qDeleteAll<QHash<Marble::RunnerPlugin*, Marble::RunnerPlugin::
ConfigWidget*>::const_iterator> (begin={i = 0x1714f368}, end=
      {i = 0x17148ed8})
    at C:/QtSDK/Desktop/Qt/4.7.3/mingw/include/QtCore/qalgorithms.h:322
#1  0x09c11acf in qDeleteAll<QHash<Marble::RunnerPlugin*, Marble::RunnerPlugin::
ConfigWidget*> > (c=@0x17119050)
    at C:/QtSDK/Desktop/Qt/4.7.3/mingw/include/QtCore/qalgorithms.h:330
#2  0x09be49d9 in ~RoutingProfileSettingsDialog (this=0x17119030)
    at D:\Development\marble-1.2\report\marble\src\lib\routing\RoutingProfileSet
tingsDialog.cpp:71
#3  0x6a213cea in QObjectPrivate::deleteChildren (this=0x17114990)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#4  0x00ca6184 in ~QWidget (this=0x17114950)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#5  0x09be2448 in ~RoutingProfilesWidget (this=0x17114950)
    at D:\Development\marble-1.2\report\marble\src\lib\routing\RoutingProfilesWi
dget.cpp:52
#6  0x6a213cea in QObjectPrivate::deleteChildren (this=0x1700f718)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#7  0x00ca6184 in ~QWidget (this=0x165f8450)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#8  0x010341f0 in ~QFrame (this=0x165f8450)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qframe.cpp:242
#9  0x01099d9c in ~QStackedWidget (this=0x165f8450)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qstackedwidget.cpp:151
#10 0x6a213cea in QObjectPrivate::deleteChildren (this=0x170ad348)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#11 0x00ca6184 in ~QWidget (this=0x10336128)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#12 0x010a4a6a in ~QTabWidget (this=0x10336128)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qtabwidget.cpp:357
#13 0x6a213cea in QObjectPrivate::deleteChildren (this=0x17060530)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#14 0x00ca6184 in ~QWidget (this=0x165f3148)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#15 0x010fcc24 in ~QDialog (this=0x165f3148)
    at c:\ndk_buildrepos\qt-desktop\src\gui\dialogs\qdialog.cpp:327
#16 0x09b52daa in ~QtMarbleConfigDialog (this=0x165f3148)
    at D:\Development\marble-1.2\report\marble\src\lib\QtMarbleConfigDialog.cpp:
196
#17 0x6a213cea in QObjectPrivate::deleteChildren (this=0x10335a40)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#18 0x00ca6184 in ~QWidget (this=0x10335930)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#19 0x01051ab4 in ~QMainWindow (this=0x10335930)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qmainwindow.cpp:391
#20 0x004222cc in ~MainWindow (this=0x10335930)
    at D:/Development/marble-1.2/report/marble/src//QtMainWindow.h:39
#21 0x6a217bcb in qDeleteInEventHandler (o=0x10335930)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:3986
#22 0x6a212b2c in QObject::event (this=0x10335930, e=0x1e1f9ee8)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1200
#23 0x00cb7e20 in QWidget::event (this=0x10335930, event=0x1e1f9ee8)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:8718
#24 0x01053970 in QMainWindow::event (this=0x10335930, event=0x1e1f9ee8)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qmainwindow.cpp:1480
#25 0x00c6bd88 in QApplicationPrivate::notify_helper (this=0x1032fca8,
    receiver=0x10335930, e=0x1e1f9ee8)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qapplication.cpp:4462
#26 0x00c6bc08 in QApplication::notify (this=0x22fe64, receiver=0x10335930,
    e=0x1e1f9ee8)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qapplication.cpp:4427
#27 0x6a201540 in QCoreApplication::notifyInternal (this=0x22fe64,
    receiver=0x10335930, event=0x1e1f9ee8)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qcoreapplication.cpp:731
#28 0x6a268258 in QCoreApplication::sendEvent (receiver=0x10335930,
    event=0x1e1f9ee8)
    at c:/ndk_buildrepos/qt-desktop/src/corelib/kernel//qcoreapplication.h:215
#29 0x6a2025eb in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0,
    event_type=0, data=0x3b4a40)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qcoreapplication.cpp:1372

#30 0x6a2248e7 in qt_internal_proc (hwnd=0xf059c, message=1025, wp=0, lp=0)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qeventdispatcher_win.cpp:
497
#31 0x77a2fd72 in USER32!GetWindowMinimizeRect ()
   from C:\Windows\system32\user32.dll
#32 0x000f059c in ?? ()
#33 0x00000401 in ?? ()
#34 0x00000000 in ?? ()


The problem is in RoutingProfileSettingsDialog.cpp
First of all we obuse to don't delete configWidget objects in destructor at line , because configWidget's are constracted by Plugin subsystem, not in RoutingProfileSettingsDialog.
But this step dont solve the problem, because we add configWidget's into m_ui->settingsStack (QStackedWidget in RoutingProfileSettingsDialog ui).
When we add widget to QStackedWidget the ownership of widget is passed on to the QStackedWidget. Look at QStackedWidget->addWidget(QWidget *) documentation here: http://doc.qt.nokia.com/latest/qstackedwidget.html#addWidget
In other words, when QStackedWidget will be destroyed all child widgets also will be destoryed. Actually, Plugins in Marble are not depended to ui so they may be destroyed early when ui, and when we call destructor for ui->setingsStack it will cause seg. fault the gdb backtrace for this case is:

Program received signal SIGSEGV, Segmentation fault.
0x6a213cdd in QObjectPrivate::deleteChildren (this=0x1711d698)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
1955    c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp: No such fi
e or directory.
        in c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp
(gdb) ba
#0  0x6a213cdd in QObjectPrivate::deleteChildren (this=0x1711d698)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#1  0x00c16184 in ~QWidget (this=0x1711d668)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#2  0x00fa41f0 in ~QFrame (this=0x1711d668)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qframe.cpp:242
#3  0x01009d9c in ~QStackedWidget (this=0x1711d668)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qstackedwidget.cpp:151
#4  0x6a213cea in QObjectPrivate::deleteChildren (this=0x17119190)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#5  0x00c16184 in ~QWidget (this=0x17119068)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#6  0x0106cc24 in ~QDialog (this=0x17119068)
    at c:\ndk_buildrepos\qt-desktop\src\gui\dialogs\qdialog.cpp:327
#7  0x09b549cc in ~RoutingProfileSettingsDialog (this=0x17119068)
    at D:\Development\marble-1.2\report\marble\src\lib\routing\RoutingProfileSe
tingsDialog.cpp:72
#8  0x6a213cea in QObjectPrivate::deleteChildren (this=0x171149a8)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#9  0x00c16184 in ~QWidget (this=0x17114968)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#10 0x09b52448 in ~RoutingProfilesWidget (this=0x17114968)
    at D:\Development\marble-1.2\report\marble\src\lib\routing\RoutingProfilesW
dget.cpp:52
#11 0x6a213cea in QObjectPrivate::deleteChildren (this=0x16548408)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#12 0x00c16184 in ~QWidget (this=0x101a60a0)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#13 0x00fa41f0 in ~QFrame (this=0x101a60a0)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qframe.cpp:242
#14 0x01009d9c in ~QStackedWidget (this=0x101a60a0)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qstackedwidget.cpp:151
#15 0x6a213cea in QObjectPrivate::deleteChildren (this=0x170752b8)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#16 0x00c16184 in ~QWidget (this=0x17061258)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#17 0x01014a6a in ~QTabWidget (this=0x17061258)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qtabwidget.cpp:357
#18 0x6a213cea in QObjectPrivate::deleteChildren (this=0x17061460)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#19 0x00c16184 in ~QWidget (this=0x17088300)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#20 0x0106cc24 in ~QDialog (this=0x17088300)
    at c:\ndk_buildrepos\qt-desktop\src\gui\dialogs\qdialog.cpp:327
#21 0x09ac2daa in ~QtMarbleConfigDialog (this=0x17088300)
    at D:\Development\marble-1.2\report\marble\src\lib\QtMarbleConfigDialog.cpp
196
#22 0x6a213cea in QObjectPrivate::deleteChildren (this=0x101a5a40)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1955
#23 0x00c16184 in ~QWidget (this=0x101a5930)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:1631
#24 0x00fc1ab4 in ~QMainWindow (this=0x101a5930)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qmainwindow.cpp:391
#25 0x004222cc in ~MainWindow (this=0x101a5930)
    at D:/Development/marble-1.2/report/marble/src//QtMainWindow.h:39
#26 0x6a217bcb in qDeleteInEventHandler (o=0x101a5930)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:3986
#27 0x6a212b2c in QObject::event (this=0x101a5930, e=0x19205718)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qobject.cpp:1200
#28 0x00c27e20 in QWidget::event (this=0x101a5930, event=0x19205718)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qwidget.cpp:8718
#29 0x00fc3970 in QMainWindow::event (this=0x101a5930, event=0x19205718)
    at c:\ndk_buildrepos\qt-desktop\src\gui\widgets\qmainwindow.cpp:1480
#30 0x00bdbd88 in QApplicationPrivate::notify_helper (this=0x1019fca8,
    receiver=0x101a5930, e=0x19205718)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qapplication.cpp:4462
#31 0x00bdbc08 in QApplication::notify (this=0x22fe64, receiver=0x101a5930,
    e=0x19205718)
    at c:\ndk_buildrepos\qt-desktop\src\gui\kernel\qapplication.cpp:4427
#32 0x6a201540 in QCoreApplication::notifyInternal (this=0x22fe64,
    receiver=0x101a5930, event=0x19205718)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qcoreapplication.cpp:731
#33 0x6a268258 in QCoreApplication::sendEvent (receiver=0x101a5930,
    event=0x19205718)
    at c:/ndk_buildrepos/qt-desktop/src/corelib/kernel//qcoreapplication.h:215
#34 0x6a2025eb in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0,
    event_type=0, data=0x274a40)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qcoreapplication.cpp:137

#35 0x6a2248e7 in qt_internal_proc (hwnd=0x605e0, message=1025, wp=0, lp=0)
    at c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qeventdispatcher_win.cpp
497
#36 0x77a2fd72 in USER32!GetWindowMinimizeRect ()
   from C:\Windows\system32\user32.dll
#37 0x000605e0 in ?? ()
#38 0x00000401 in ?? ()
#39 0x00000000 in ?? ()

So we need to somehow inform widgets about plugin destroying. The basic destoryed() signal is not sufficient because we need working pointer for destoryed object. My solution is add special signal to RunnerPlugin: pluginWillDeleted() and emit it in RunnerPlugin destructor. In RoutingProfileSettingsDialog we will connect to this signal and proceed information about plugin destruction in slot
runnerPluginDestroyed().
The magic is start here!
QStackedWidget has function to remove widget from stack, but for some reasons it does not do it correct - the ownership is stayed in QStackedWidget and we still get segfault in ~QStackedWidget().
I found only one workaround for this case - delete m_ui->settingsStack each time when plugin is deleted or unloaded and reconstruct part of RoutingProfileSettingsDialog ui after that.
I realize that it is not good thing, but it solve the problem.

So the patch is attached.

Sorry for inconvenience - it's my first bug report, but I like Marble very much and wanna to make it better.


Reproducible: Always

Steps to Reproduce:
Start Marble in Windows or Linux on Dual or MultiCore machine, wait while all modules are loaded. Exit Marble

Actual Results:  
Segmentation fault, application crashed.

Expected Results:  
Normal exiting
Comment 1 Bernhard Beschow 2011-08-05 18:07:37 UTC
*** Bug 275991 has been marked as a duplicate of this bug. ***
Comment 2 Bernhard Beschow 2011-08-06 00:39:36 UTC
*** Bug 269822 has been marked as a duplicate of this bug. ***
Comment 3 Bernhard Beschow 2011-08-19 19:37:13 UTC
Git commit 868b8e701e60f7c799ab4a724db1607909dbcd9c by Bernhard Beschow.
Committed on 19/08/2011 at 20:43.
Pushed by beschow into branch 'master'.

do not crash on exit due to routing profile config widgets being still around

Only create temporary objects of RoutingProfileSettingsDialog, such that the profile runner's config widgets are destroyed before all plugins are unloaded.

Credits to Anton Chernov for figuring out the root cause of the bug.

BUG: 279364

M  +1    -2    src/lib/routing/RoutingProfilesWidget.h
M  +7    -5    src/lib/routing/RoutingProfilesWidget.cpp

http://commits.kde.org/marble/868b8e701e60f7c799ab4a724db1607909dbcd9c
Comment 4 Bernhard Beschow 2011-08-19 20:07:19 UTC
Git commit ccb5ca1d9c32e34c9fb2b5296e1add21a1432631 by Bernhard Beschow.
Committed on 19/08/2011 at 20:43.
Pushed by beschow into branch 'kde-4.7'.

do not crash on exit due to routing profile config widgets being still around

Only create temporary objects of RoutingProfileSettingsDialog, such that the profile runner's config widgets are destroyed before all plugins are unloaded.

Credits to Anton Chernov for figuring out the root cause of the bug.

BUG: 279364
(cherry picked from commit 868b8e701e60f7c799ab4a724db1607909dbcd9c)

M  +1    -2    src/lib/routing/RoutingProfilesWidget.h
M  +7    -5    src/lib/routing/RoutingProfilesWidget.cpp

http://commits.kde.org/marble/ccb5ca1d9c32e34c9fb2b5296e1add21a1432631