Bug 256282 - Floating point crash importing gnucash file
Summary: Floating point crash importing gnucash file
Status: RESOLVED FIXED
Alias: None
Product: kmymoney
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Fedora RPMs Linux
: NOR crash
Target Milestone: ---
Assignee: KMyMoney Devel Mailing List
URL:
Keywords:
: 264312 264313 274656 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-11-07 09:09 UTC by Bradley Baetz
Modified: 2011-06-01 22:22 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Minimal test case (5.94 KB, application/xml)
2010-11-15 13:57 UTC, Bradley Baetz
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bradley Baetz 2010-11-07 09:09:29 UTC
Application: kmymoney (4.5.0)
KDE Platform Version: 4.5.2 (KDE 4.5.2)
Qt Version: 4.7.0
Operating System: Linux 2.6.35.6-48.fc14.x86_64 x86_64
Distribution: "Fedora release 14 (Laughlin)"

-- Information about the crash:
Imported gnucash file. Crashes at the end of import, before the GUI allows any other options.

The crash can be reproduced every time.

-- Backtrace:
Application: KMyMoney (kmymoney), signal: Floating point exception
82	T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
[Current thread is 1 (Thread 0x7fac276b9840 (LWP 8112))]

Thread 2 (Thread 0x7fac129de700 (LWP 8113)):
#0  0x00007fac22172883 in __poll (fds=<value optimized out>, nfds=<value optimized out>, timeout=<value optimized out>) at ../sysdeps/unix/sysv/linux/poll.c:87
#1  0x00007fac1d0c2374 in g_main_context_poll (context=0x28e8a40, block=1, dispatch=1, self=<value optimized out>) at gmain.c:3093
#2  g_main_context_iterate (context=0x28e8a40, block=1, dispatch=1, self=<value optimized out>) at gmain.c:2775
#3  0x00007fac1d0c2c82 in g_main_loop_run (loop=0x28e8b20) at gmain.c:2988
#4  0x00007fac12ef7774 in gdbus_shared_thread_func (data=<value optimized out>) at gdbusprivate.c:277
#5  0x00007fac1d0e9446 in g_thread_create_proxy (data=0x28e8b40) at gthread.c:1897
#6  0x00007fac23ae0d5b in start_thread (arg=0x7fac129de700) at pthread_create.c:301
#7  0x00007fac2217c27d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

Thread 1 (Thread 0x7fac276b9840 (LWP 8112)):
[KCrash Handler]
#6  0x00007fac272675ce in MyMoneyMoney::convert (this=0x7fff8da28ac0, _denom=10000, how=MyMoneyMoney::RndRound) at /usr/src/debug/kmymoney-4.5/kmymoney/mymoney/mymoneymoney.cpp:653
#7  0x0000000000781532 in AccountsModel::Private::value(MyMoneyAccount const&, MyMoneyMoney const&) ()
#8  0x0000000000781fa5 in AccountsModel::Private::setAccountData(QStandardItemModel*, QModelIndex const&, MyMoneyAccount const&) ()
#9  0x00000000007840b8 in AccountsModel::Private::loadInstitution(QStandardItemModel*, MyMoneyAccount const&) ()
#10 0x000000000077c1eb in loadSubAccounts (this=0x2c3bbb0) at /usr/src/debug/kmymoney-4.5/kmymoney/models/accountsmodel.cpp:67
#11 AccountsModel::load (this=0x2c3bbb0) at /usr/src/debug/kmymoney-4.5/kmymoney/models/accountsmodel.cpp:550
#12 0x00000000007857a0 in Models::qt_metacall (this=0xbb3cb0, _c=QMetaObject::InvokeMetaMethod, _id=<value optimized out>, _a=<value optimized out>) at /usr/src/debug/kmymoney-4.5/x86_64-redhat-linux-gnu/kmymoney/models/moc_models.cpp:73
#13 0x00007fac23e6702f in QMetaObject::activate (sender=0x7fac274ef600, m=<value optimized out>, local_signal_index=<value optimized out>, argv=0x0) at kernel/qobject.cpp:3272
#14 0x00000000004bea6e in forceDataChanged (this=0x2c255e0) at /usr/src/debug/kmymoney-4.5/kmymoney/mymoney/mymoneyfile.h:1366
#15 KMyMoneyView::initializeStorage (this=0x2c255e0) at /usr/src/debug/kmymoney-4.5/kmymoney/views/kmymoneyview.cpp:990
#16 0x00000000004c004c in KMyMoneyView::readFile (this=0x2c255e0, url=<value optimized out>) at /usr/src/debug/kmymoney-4.5/kmymoney/views/kmymoneyview.cpp:803
#17 0x0000000000483f88 in KMyMoneyApp::slotGncImport (this=0x2add9f0) at /usr/src/debug/kmymoney-4.5/kmymoney/kmymoney.cpp:2191
#18 0x000000000049ac6d in KMyMoneyApp::qt_metacall (this=0x2add9f0, _c=QMetaObject::InvokeMetaMethod, _id=35, _a=0x7fff8da2b810) at /usr/src/debug/kmymoney-4.5/x86_64-redhat-linux-gnu/kmymoney/kmymoney.moc:438
#19 0x00007fac23e6702f in QMetaObject::activate (sender=0x2b203a0, m=<value optimized out>, local_signal_index=<value optimized out>, argv=0x7fff8da2b810) at kernel/qobject.cpp:3272
#20 0x00007fac22d8b4e2 in QAction::triggered (this=<value optimized out>, _t1=false) at .moc/release-shared/moc_qaction.cpp:263
#21 0x00007fac22d8b6da in QAction::activate (this=0x2b203a0, event=<value optimized out>) at kernel/qaction.cpp:1256
#22 0x00007fac231c19a3 in QMenuPrivate::activateCausedStack (this=0x2ba31a0, causedStack=..., action=0x2b203a0, action_e=QAction::Trigger, self=true) at widgets/qmenu.cpp:993
#23 0x00007fac231c793a in QMenuPrivate::activateAction (this=0x2ba31a0, action=0x2b203a0, action_e=QAction::Trigger, self=true) at widgets/qmenu.cpp:1085
#24 0x00007fac25e1308d in KMenu::mouseReleaseEvent (this=0x2ba3060, e=<value optimized out>) at /usr/src/debug/kdelibs-4.5.2/kdeui/widgets/kmenu.cpp:471
#25 0x00007fac22de3228 in QWidget::event (this=0x2ba3060, event=0x7fff8da2c490) at kernel/qwidget.cpp:8187
#26 0x00007fac231c8b2b in QMenu::event (this=0x2ba3060, e=0x7fff8da2c490) at widgets/qmenu.cpp:2410
#27 0x00007fac22d91b64 in QApplicationPrivate::notify_helper (this=0x2899aa0, receiver=0x2ba3060, e=0x7fff8da2c490) at kernel/qapplication.cpp:4396
#28 0x00007fac22d96e5a in QApplication::notify (this=<value optimized out>, receiver=0x2ba3060, e=0x7fff8da2c490) at kernel/qapplication.cpp:3959
#29 0x00007fac25d43416 in KApplication::notify (this=0x28999d0, receiver=0x2ba3060, event=0x7fff8da2c490) at /usr/src/debug/kdelibs-4.5.2/kdeui/kernel/kapplication.cpp:310
#30 0x00007fac23e527ac in QCoreApplication::notifyInternal (this=0x28999d0, receiver=0x2ba3060, event=0x7fff8da2c490) at kernel/qcoreapplication.cpp:732
#31 0x00007fac22d92b65 in sendEvent (receiver=0x2ba3060, event=0x7fff8da2c490, alienWidget=0x0, nativeWidget=0x2ba3060, buttonDown=0x7fac2385f658, lastMouseReceiver=..., spontaneous=true) at ../../src/corelib/kernel/qcoreapplication.h:215
#32 QApplicationPrivate::sendMouseEvent (receiver=0x2ba3060, event=0x7fff8da2c490, alienWidget=0x0, nativeWidget=0x2ba3060, buttonDown=0x7fac2385f658, lastMouseReceiver=..., spontaneous=true) at kernel/qapplication.cpp:3058
#33 0x00007fac22e0ffb4 in QETWidget::translateMouseEvent (this=0x2ba3060, event=<value optimized out>) at kernel/qapplication_x11.cpp:4337
#34 0x00007fac22e0e4b9 in QApplication::x11ProcessEvent (this=0x28999d0, event=0x7fff8da2cde0) at kernel/qapplication_x11.cpp:3536
#35 0x00007fac22e35a52 in x11EventSourceDispatch (s=0x289d840, callback=0, user_data=0x0) at kernel/qguieventdispatcher_glib.cpp:146
#36 0x00007fac1d0c1e33 in g_main_dispatch (context=0x289c520) at gmain.c:2149
#37 g_main_context_dispatch (context=0x289c520) at gmain.c:2702
#38 0x00007fac1d0c2610 in g_main_context_iterate (context=0x289c520, block=1, dispatch=1, self=<value optimized out>) at gmain.c:2780
#39 0x00007fac1d0c28ad in g_main_context_iteration (context=0x289c520, may_block=1) at gmain.c:2843
#40 0x00007fac23e7d8af in QEventDispatcherGlib::processEvents (this=0x287a370, flags=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:415
#41 0x00007fac22e356ee in QGuiEventDispatcherGlib::processEvents (this=<value optimized out>, flags=<value optimized out>) at kernel/qguieventdispatcher_glib.cpp:204
#42 0x00007fac23e51b42 in QEventLoop::processEvents (this=<value optimized out>, flags=...) at kernel/qeventloop.cpp:149
#43 0x00007fac23e51d8c in QEventLoop::exec (this=0x7fff8da2d0f0, flags=...) at kernel/qeventloop.cpp:201
#44 0x00007fac23e5620b in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1009
#45 0x00000000004534be in main (argc=1, argv=0x7fff8da2dcc8) at /usr/src/debug/kmymoney-4.5/kmymoney/main.cpp:260

Reported using DrKonqi
Comment 1 Cristian Oneț 2010-11-15 12:08:55 UTC
Could you attach a GNUCash test file to reproduce this. If it happens every time it should be easy to reproduce it with a test file.
Comment 2 Bradley Baetz 2010-11-15 13:57:14 UTC
Created attachment 53433 [details]
Minimal test case

Minimal file attached - taken by cutting down my actual file as much as possible. 

Removing the 'price' that has a value of zero fixes this, both on the test case and my original file
Comment 3 Cristian Oneț 2010-11-15 14:32:26 UTC
The bug is caused by the price having the value 0. The price is used later on in a conversion to the base currency which causes the crash.
There are two ways to fix this:
1) Don't allow the import of a price that has the value 0 because it doesn't really make sense to have a conversion rate of 0 (KMyMoney's UI does not allow entering a price with the value 0 - I wonder about other price sources though such as online quotes).
2) Skip the conversion if the rate is 0; But with what kind of result? If let's say 1 A = 0 B then how many A's would 1 B value?

Personally I prefer solution 1. I posted this here so the others can have their say on how to fix this. Thanks for the file.
Comment 4 Bradley Baetz 2010-11-16 11:47:09 UTC
FWIW, this was an auto-downloaded online quote (stock had changed its code and I hadn't updated gnucash)

OTOH, 0 is 'valid' as a price; companies do go under.
Comment 5 Cristian Oneț 2010-11-19 12:22:18 UTC
Thomas, Alvaro, Tony any thoughts on how should we handle this?
Comment 6 Thomas Baumgart 2010-12-12 13:36:53 UTC
Seems that price equals 0 is a valid condition. I propose the following patch:

Index: accountsmodel.cpp
===================================================================
--- accountsmodel.cpp   (revision 1204831)
+++ accountsmodel.cpp   (working copy)
@@ -241,12 +241,16 @@
     {
       QList<MyMoneyPrice>::const_iterator it_p;
       QString security = account.currencyId();
-      for (it_p = prices.constBegin(); it_p != prices.constEnd(); ++it_p) {
-        value = (value * (MyMoneyMoney(1, 1) / (*it_p).rate(security))).convert(MyMoneyMoney::precToDenom(KMyMoneyGlobalSettings::pricePrecision()));
-        if ((*it_p).from() == security)
-          security = (*it_p).to();
-        else
-          security = (*it_p).from();
+      for (it_p = prices.constBegin(); !value.isZero() && it_p != prices.constEnd(); ++it_p) {
+        if((*it_p).rate(security).isZero()) {
+          value = 0;
+        } else {
+          value = (value * (MyMoneyMoney(1, 1) / (*it_p).rate(security))).convert(MyMoneyMoney::precToDenom(KMyMoneyGlobalSettings::pricePrecision()));
+          if ((*it_p).from() == security)
+            security = (*it_p).to();
+          else
+            security = (*it_p).from();
+        }
       }
       value = value.convert(m_file->baseCurrency().smallestAccountFraction());
     }
Comment 7 Alvaro Soliverez 2010-12-12 13:46:09 UTC
If price equals 0, reports will crash. We've been through that before.
So, if we decide to allow prices in 0 to go in, there's a lot more to change.
Comment 8 Cristian Oneț 2010-12-12 13:51:44 UTC
I was about to suggest to look for other places in the code where such conversion is performed but Alvaro said it all. If the UI dos not allow entering a conversion rate of 0 I would suggest forbidding it during import also.
The other solution would be to check everywhere a conversion rate is used and guard it against a zero value but then we have to implement the ??? value also (shown in the UI for the inverse conversion when you enter 0 as a price for direct conversion).
Comment 9 Thomas Baumgart 2010-12-12 14:22:28 UTC
SVN commit 1205765 by tbaumgart:

Don't import zero prices from GnuCash
Print more details about the price to the console

BUG: 256282

 M  +2 -0      converter/mymoneygncreader.cpp  
 M  +2 -1      mymoney/mymoneyprice.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1205765
Comment 10 Thomas Baumgart 2010-12-12 14:28:15 UTC
SVN commit 1205768 by tbaumgart:

Don't import zero prices from GnuCash
Print more details about the price to the console

Backported to stable branch

BUG: 256282

 M  +2 -0      converter/mymoneygncreader.cpp  
 M  +2 -1      mymoney/mymoneyprice.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1205768
Comment 11 Cristian Oneț 2011-01-26 07:35:05 UTC
*** Bug 264312 has been marked as a duplicate of this bug. ***
Comment 12 Cristian Oneț 2011-01-26 07:35:54 UTC
*** Bug 264313 has been marked as a duplicate of this bug. ***
Comment 13 Cristian Oneț 2011-06-01 22:22:39 UTC
*** Bug 274656 has been marked as a duplicate of this bug. ***