Bug 135440 - Crash when a plugin is missing
Summary: Crash when a plugin is missing
Status: RESOLVED FIXED
Alias: None
Product: kst
Classification: Applications
Component: general (show other bugs)
Version: 1.x
Platform: unspecified Solaris
: VHI crash
Target Milestone: ---
Assignee: kst
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-10-11 10:20 UTC by Nicolas Brisset
Modified: 2006-10-16 23:12 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
Testcase (6.09 KB, text/plain)
2006-10-12 12:32 UTC, Nicolas Brisset
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nicolas Brisset 2006-10-11 10:20:56 UTC
Version:           1.3.1_devel (using KDE 3.4.0, compiled sources)
Compiler:          gcc version 3.4.3
OS:                SunOS (sun4u) release 5.8

Imagine the following scenario (which just happened !): a group of people is working on a project and using kst to analyze data. Someone writes a custom plugin and uses it in a (shared) .kst file. Once he has interesting results, he informs someone else and forgets to mention/send the plugin. The second user tries to load the .kst file and gets a bad crash, without understanding why since it worked just the day before when the new plugin wasn't used.
Of course, the new plugin can be made available to other users, but I think it would be nicer if kst didn't crash in such a case.

To reproduce, just create a .kst file using any available plugin, then change the plugin name in the .kst file by hand and reload it (or alternatively, uninstall the plugin before reloading)
Comment 1 George Staikos 2006-10-11 23:59:51 UTC
SVN commit 594648 by staikos:

don't crash on loading invalid plugins
BUG: 135440


 M  +6 -2      kstplugin.cpp  


--- trunk/extragear/graphics/kst/src/libkstmath/kstplugin.cpp #594647:594648
@@ -426,9 +426,13 @@
 
 QString KstPlugin::label(int precision) const {
   QString label;
-  
+ 
+  if (!plugin()) {
+    return label;
+  }
+
   label = i18n("%1: %2").arg(plugin()->data()._readableName).arg(tagName());
-  if ((outputVectors())["Parameters"]) {
+  if (outputVectors()["Parameters"]) {
     QString strParamName;
     QString strValue;
     int length = (outputVectors())["Parameters"]->length();
Comment 2 Nicolas Brisset 2006-10-12 12:31:51 UTC
Hum, it still crashes here when I load a file referencing a plugin that does not exist. Unclean build ? Wrong fix ? Misunderstanding ?
I will attach the test file here jsut to make sure. I created it by loading data from gyrodata.dat, creating a shift filter plugin and editing the .kst to change the plugin name.
Comment 3 Nicolas Brisset 2006-10-12 12:32:57 UTC
Created attachment 18097 [details]
Testcase

Testcase, put the file in kst/misc/tutorial so that it finds gyrodata.dat and
load with "kst test.kst"
Comment 4 George Staikos 2006-10-12 15:38:09 UTC
Please paste in a backtrace.
Comment 5 Nicolas Brisset 2006-10-12 15:44:49 UTC
Strangely, Dr Konqui says the backtrace is not usable even though I compiled with --enable-debug ? However, catching the process with the debugger here is what I get:

#0  0xff19db5c in KstViewFitsDialogI::hasContent (this=0x0) at kstviewfitsdialog_i.cpp:63
#1  0xff1bfc34 in KstApp::updateDataDialogs (this=0x120428, dm=true, vm=true) at kst.cpp:2109
#2  0xff1cb58c in KstApp::qt_invoke (this=0x120428, _id=237, _o=0xffbebb80) at kst.moc:629
#3  0xfd69c5c4 in QObject::activate_signal () from /usr/local/kde/lib/libqt-mt.so.3
#4  0xfd69ced8 in QObject::activate_signal () from /usr/local/kde/lib/libqt-mt.so.3
#5  0xff1b7930 in KstDoc::event (this=0x17d0a0, e=0x646718) at kstdoc.cpp:1053
#6  0xfd643024 in QApplication::internalNotify () from /usr/local/kde/lib/libqt-mt.so.3
#7  0xfd6432f0 in QApplication::notify () from /usr/local/kde/lib/libqt-mt.so.3
#8  0xfe0bd6d0 in KApplication::notify () from /usr/local/kde/V3.4.0/lib/libkdecore.so.4
#9  0xfd644474 in QApplication::sendPostedEvents () from /usr/local/kde/lib/libqt-mt.so.3
#10 0xfd5f1ec8 in QEventLoop::processEvents () from /usr/local/kde/lib/libqt-mt.so.3
#11 0xfd658e7c in QEventLoop::enterLoop () from /usr/local/kde/lib/libqt-mt.so.3
#12 0xfd658d64 in QEventLoop::exec () from /usr/local/kde/lib/libqt-mt.so.3
#13 0xfd641fb8 in QApplication::exec () from /usr/local/kde/lib/libqt-mt.so.3
#14 0x0001f4e4 in main (argc=1, argv=0xffbec84c) at main.cpp:819
Comment 6 George Staikos 2006-10-12 15:59:24 UTC
This backtrace doesn't make any sense to me.  The null value could never be 
null and the line numbers don't correlate.
Comment 7 Nicolas Brisset 2006-10-12 16:22:19 UTC
From your comments, I assume you don't get the same crash ?
I compiled this from a fresh checkout (1.3 branch) this morning. I was also surprised to see the fits dialog in there as "shift" is a filter (not fit) plugin. And yet, the crash is always there and very reproducible :-(
I don't know what to do next ?
Comment 8 Nicolas Brisset 2006-10-12 16:35:18 UTC
It seems to crash the first time it enters the for() line, and content seems to have a value of 112, 160, 248 or other integer values *after*
bool content = false; 
Very strange actually, I don't know where the problem lies nor how to identify it. I'll try under Linux to make sure...
 
Comment 9 Nicolas Brisset 2006-10-12 17:08:12 UTC
FYI I just finished compiling a fresh checkout under Linux and I get the same crash in the same file (I forgot --enable-debug so I don't have the line number, but I guess it's the same)
Comment 10 George Staikos 2006-10-12 17:31:17 UTC
  I really can't reproduce this with trunk and your .kst file.  It even comes 
up valgrind clean.  Maybe it's purely a 1.3.x bug?
Comment 11 Nicolas Brisset 2006-10-12 17:40:29 UTC
I thought you had a 1.3 checkout lying around for the backports, but maybe you don't need one because you know how to use svn merge :-) ?
May I suggest trying a 1.3 checkout just to confirm ? (and a quick svn merge tutorial: how you apply a fix done in trunk to 1.3)
Comment 12 George Staikos 2006-10-12 17:54:15 UTC
On Thursday 12 October 2006 09:44, Nicolas Brisset wrote:
> #0  0xff19db5c in KstViewFitsDialogI::hasContent (this=0x0) at
> kstviewfitsdialog_i.cpp:63
> #1  0xff1bfc34 in KstApp::updateDataDialogs (this=0x120428, dm=true, 

vm=true) at kst.cpp:2109

   You really have something quite broken here because:

1) kst.cpp line 2109 is not realted to the view fits dialog
2) KstApp never calls KstViewFitsDialogI::hasContent
3) hasContent() was only added to trunk.  It's not in 1.3 branch.

   I suspect you have mismatched .so files.
Comment 13 George Staikos 2006-10-12 17:56:50 UTC
Mismatched .so files.
Comment 14 Adam Treat 2006-10-12 18:20:15 UTC
Uhm...

* Backport commit# 593050 to 1.3 branch

I think this was backported...

On Thursday 12 October 2006 11:54 am, George Staikos wrote:
[bugs.kde.org quoted mail]
Comment 15 George Staikos 2006-10-12 18:27:58 UTC
I see
Comment 16 George Staikos 2006-10-12 18:32:56 UTC
I don't think we can load a plugin object that is invalid.  We will just have to throw the object away.
Comment 17 Adam Treat 2006-10-12 18:39:30 UTC
I'm trying to reproduce with 1.3 and trunk.  I still think this is a case of mismatched .so files...
Comment 18 George Staikos 2006-10-12 18:44:29 UTC
  Yes I can't reproduce it in trunk, but I -can- see how it can happen too.  
I'm working on a fix.
Comment 19 George Staikos 2006-10-12 19:02:20 UTC
SVN commit 594867 by staikos:

don't load invalid plugins at all
BUG: 135440


 M  +4 -2      kstdoc.cpp  


--- trunk/extragear/graphics/kst/src/libkstapp/kstdoc.cpp #594866:594867
@@ -381,8 +381,10 @@
         KST::addVectorToList(KstVectorPtr(avector));
       } else if (e.tagName() == "plugin") {
         KstDataObjectPtr p = new KstPlugin(e);
-        KstWriteLocker dowl(&KST::dataObjectList.lock());
-        KST::dataObjectList.append(p);
+        if (p->isValid()) {
+          KstWriteLocker dowl(&KST::dataObjectList.lock());
+          KST::dataObjectList.append(p);
+        }
       } else if (e.tagName() == "curve") {
         KstDataObjectPtr p = new KstVCurve(e);
         KstWriteLocker dowl(&KST::dataObjectList.lock());
Comment 20 Nicolas Brisset 2006-10-13 09:45:39 UTC
YES ! That time you caught it, thanks :-)
I'm still wondering whether I have .so chaos, though. Since I have installed many versions in parallel and I use KDEDIRS/PATH/LD_LIBRARY_PATH vars to switch between them, mismatches and wrong libraries being picked up is not completely improbable...
Comment 21 Nicolas Brisset 2006-10-16 10:30:07 UTC
Hum, I rejoiced a bit too quickly. The test case I mentioned works better indeed, in the way that it does not crash. However, loading valid plugins does not work now, at least in some cases. For example:
1) load col 1 from gyrodata.dat vs INDEX
2) create a "cumulative_sum" plugin in a new plot
3) save, exit and reload: there is an error message and all plugin objects are gone :-(

This is CRITICAL: the minimum before 1.3.1 is to remove the change and accept that kst crashes in some cases of missing plugins, the best would be to find the right fix, though...
Comment 22 Adam Treat 2006-10-16 22:55:27 UTC
I do not get a crash here.  Instead, the plugin does not load when I restart.  The plugin must be invalid.  Here is KstPlugin::isValid() for you:

bool KstPlugin::isValid() const {
  return _inputVectors.count() == _inArrayCnt &&
         _inputScalars.count() == _inScalarCnt - _inPid &&
         _inputStrings.count() == _inStringCnt &&
         _plugin.data() != 0L;
}

Doing a little digging, the problem is that _inputVectors and _inputScalars are not set at the time of plugin loading.  Instead they are put in load queues and only become active when data is loaded by kstdoc.

Patch forthcoming.
Comment 23 Adam Treat 2006-10-16 23:12:27 UTC
SVN commit 596190 by treat:

* Fix problem with plugin loading where they don't
become valid until after the data is loaded.

BUGS: 135440


 M  +3 -0      kstdataobject.cpp  
 M  +1 -0      kstdataobject.h  
 M  +11 -4     kstplugin.cpp  


--- trunk/extragear/graphics/kst/src/libkstmath/kstdataobject.cpp #596189:596190
@@ -36,12 +36,14 @@
 KstDataObject::KstDataObject() : KstObject() {
   //kstdDebug() << "+++ CREATING DATA OBJECT: " << (void*)this << endl;
   _curveHints = new KstCurveHintList;
+  _isInputLoaded = false;
 }
 
 KstDataObject::KstDataObject(const QDomElement& e) : KstObject() {
   Q_UNUSED(e)
   //kstdDebug() << "+++ CREATING DATA OBJECT: " << (void*)this << endl;
   _curveHints = new KstCurveHintList;
+  _isInputLoaded = false;
 }
 
 
@@ -159,6 +161,7 @@
   
   setDirty();
 
+  _isInputLoaded = true;
   return rc;
 }
 
--- trunk/extragear/graphics/kst/src/libkstmath/kstdataobject.h #596189:596190
@@ -112,6 +112,7 @@
 
     QString _typeString, _type;
 
+    bool _isInputLoaded;
     QValueList<QPair<QString,QString> > _inputVectorLoadQueue;
     QValueList<QPair<QString,QString> > _inputScalarLoadQueue;
     QValueList<QPair<QString,QString> > _inputStringLoadQueue;
--- trunk/extragear/graphics/kst/src/libkstmath/kstplugin.cpp #596189:596190
@@ -505,10 +505,17 @@
 
 
 bool KstPlugin::isValid() const {
-  return _inputVectors.count() == _inArrayCnt &&
-         _inputScalars.count() == _inScalarCnt - _inPid &&
-         _inputStrings.count() == _inStringCnt &&
-         _plugin.data() != 0L;
+  if (_isInputLoaded) {
+    return _inputVectors.count() == _inArrayCnt &&
+           _inputScalars.count() == _inScalarCnt - _inPid &&
+           _inputStrings.count() == _inStringCnt &&
+           _plugin.data() != 0L;
+  } else {
+    return _inputVectorLoadQueue.count() == _inArrayCnt &&
+           _inputScalarLoadQueue.count() == _inScalarCnt - _inPid &&
+           _inputStringLoadQueue.count() == _inStringCnt &&
+           _plugin.data() != 0L;
+  }
 }